import React, { useEffect, useMemo, useState } from 'react'
import { api } from '../api'

const CAMPOS_UNIFICADOS = [
  { id: 'finalidade', label: 'Finalidade', targets: ['aval_finalidade'] },
  { id: 'bairros', label: 'Bairro', targets: ['aval_bairro'] },
  { id: 'data', label: 'Data', targets: ['data'] },
  { id: 'area', label: 'Area', targets: ['aval_area'] },
  { id: 'rh', label: 'RH', targets: ['aval_rh'] },
]

function sortByLabel(items = []) {
  return [...items].sort((a, b) => a.label.localeCompare(b.label, 'pt-BR', { sensitivity: 'base' }))
}

function normalizeColunasConfig(rawConfig = {}) {
  const out = {}
  CAMPOS_UNIFICADOS.forEach(({ id, targets }) => {
    const disponiveisMap = new Map()
    const padrao = []
    const padraoVistos = new Set()

    targets.forEach((target) => {
      const config = rawConfig?.[target] || {}
      ;(Array.isArray(config?.disponiveis) ? config.disponiveis : []).forEach((item) => {
        const itemId = typeof item === 'string' ? item : item?.id
        const itemLabel = typeof item === 'string' ? item : item?.label || item?.id
        const idText = String(itemId || '').trim()
        if (!idText) return
        if (!disponiveisMap.has(idText)) {
          disponiveisMap.set(idText, String(itemLabel || idText))
        }
      })
    })

    const disponiveis = sortByLabel(Array.from(disponiveisMap.entries()).map(([itemId, label]) => ({ id: itemId, label })))
    const idsDisponiveis = new Set(disponiveis.map((item) => item.id))

    targets.forEach((target) => {
      const config = rawConfig?.[target] || {}
      ;(Array.isArray(config?.padrao) ? config.padrao : []).forEach((item) => {
        const idText = String(item || '').trim()
        if (!idText || !idsDisponiveis.has(idText) || padraoVistos.has(idText)) return
        padraoVistos.add(idText)
        padrao.push(idText)
      })
    })

    if (!padrao.length) {
      disponiveis.forEach((item) => padrao.push(item.id))
    }

    out[id] = { disponiveis, padrao }
  })
  return out
}

function normalizeSelecionadas(raw = {}, configNormalizada = {}) {
  const out = {}
  CAMPOS_UNIFICADOS.forEach(({ id, targets }) => {
    const disponiveis = new Set((configNormalizada[id]?.disponiveis || []).map((item) => item.id))
    const preferidas = []
    targets.forEach((target) => {
      ;(Array.isArray(raw?.[target]) ? raw[target] : []).forEach((item) => preferidas.push(String(item || '').trim()))
    })
    const validas = preferidas.filter((item, idx) => item && disponiveis.has(item) && preferidas.indexOf(item) === idx)
    if (validas.length) {
      out[id] = validas
      return
    }
    const padrao = (configNormalizada[id]?.padrao || []).filter((item) => disponiveis.has(item))
    out[id] = Array.from(new Set(padrao))
  })
  return out
}

function buildPayload(selecionadas = {}, colunasConfig = {}) {
  const payload = {}
  CAMPOS_UNIFICADOS.forEach(({ id, targets }) => {
    const idsDisponiveis = new Set((colunasConfig[id]?.disponiveis || []).map((item) => item.id))
    const selecionadasCampo = (selecionadas[id] || [])
      .map((item) => String(item || '').trim())
      .filter((item, idx, arr) => item && idsDisponiveis.has(item) && arr.indexOf(item) === idx)

    targets.forEach((target) => {
      payload[target] = [...selecionadasCampo]
    })
  })
  return payload
}

function serializarCampos(campos = {}) {
  const normalizado = {}
  Object.keys(campos || {}).sort().forEach((campo) => {
    normalizado[campo] = [...(campos[campo] || [])]
  })
  return JSON.stringify(normalizado)
}

export default function PesquisaAdminConfigPanel({ onSaved }) {
  const [loading, setLoading] = useState(false)
  const [saving, setSaving] = useState(false)
  const [error, setError] = useState('')
  const [status, setStatus] = useState('')
  const [colunasConfig, setColunasConfig] = useState({})
  const [selecionadas, setSelecionadas] = useState({})
  const [baseline, setBaseline] = useState('{}')

  const dirty = useMemo(() => serializarCampos(selecionadas) !== baseline, [selecionadas, baseline])

  async function carregar() {
    setLoading(true)
    setError('')
    setStatus('')
    try {
      const response = await api.pesquisaAdminConfig()
      const configNormalizada = normalizeColunasConfig(response.colunas_filtro || {})
      const selecionadasNormalizadas = normalizeSelecionadas(response.admin_fontes || {}, configNormalizada)
      const base = serializarCampos(selecionadasNormalizadas)
      setColunasConfig(configNormalizada)
      setSelecionadas(selecionadasNormalizadas)
      setBaseline(base)
    } catch (err) {
      setError(err.message)
    } finally {
      setLoading(false)
    }
  }

  useEffect(() => {
    void carregar()
  }, [])

  function findLabel(campo, id) {
    const match = (colunasConfig[campo]?.disponiveis || []).find((item) => item.id === id)
    return match?.label || id
  }

  function onAdd(campo, value) {
    const id = String(value || '').trim()
    if (!id) return
    setSelecionadas((current) => {
      const atual = current[campo] || []
      if (atual.includes(id)) return current
      return { ...current, [campo]: [...atual, id] }
    })
  }

  function onRemove(campo, id) {
    setSelecionadas((current) => ({
      ...current,
      [campo]: (current[campo] || []).filter((item) => item !== id),
    }))
  }

  function onRestaurarPadrao(campo) {
    const padrao = colunasConfig[campo]?.padrao || []
    setSelecionadas((current) => ({ ...current, [campo]: [...padrao] }))
  }

  async function onSalvar() {
    setSaving(true)
    setError('')
    setStatus('')
    try {
      const response = await api.pesquisaAdminConfigSalvar(buildPayload(selecionadas, colunasConfig))
      const configNormalizada = normalizeColunasConfig(response.colunas_filtro || {})
      const selecionadasNormalizadas = normalizeSelecionadas(response.admin_fontes || {}, configNormalizada)
      const base = serializarCampos(selecionadasNormalizadas)
      setColunasConfig(configNormalizada)
      setSelecionadas(selecionadasNormalizadas)
      setBaseline(base)
      setStatus(response.status || 'Configuracao salva.')
      if (onSaved) onSaved()
    } catch (err) {
      setError(err.message)
    } finally {
      setSaving(false)
    }
  }

  function renderCampo(campo, label) {
    const configCampo = colunasConfig[campo] || { disponiveis: [], padrao: [] }
    const selecionadasCampo = selecionadas[campo] || []
    const selectedSet = new Set(selecionadasCampo)
    const opcoesAdicionar = (configCampo.disponiveis || []).filter((item) => !selectedSet.has(item.id))

    return (
      <div key={campo} className="pesquisa-admin-field">
        <div className="pesquisa-admin-field-head">
          <strong>{label}</strong>
          <button type="button" className="btn-pesquisa-expand" onClick={() => onRestaurarPadrao(campo)}>
            Restaurar padrao
          </button>
        </div>

        <div className="pesquisa-dynamic-filter-row pesquisa-admin-row">
          <div className="pesquisa-colunas-box">
            <div className="pesquisa-colunas-chip-list">
              {selecionadasCampo.map((itemId) => (
                <span key={`${campo}-${itemId}`} className="pesquisa-coluna-chip">
                  <span>{findLabel(campo, itemId)}</span>
                  <button type="button" className="pesquisa-coluna-remove" onClick={() => onRemove(campo, itemId)} aria-label={`Remover fonte ${findLabel(campo, itemId)}`}>
                    x
                  </button>
                </span>
              ))}
              {!selecionadasCampo.length ? <span className="pesquisa-colunas-empty">Nenhuma fonte selecionada.</span> : null}
            </div>
          </div>

          <select
            className="pesquisa-colunas-add"
            defaultValue=""
            onChange={(event) => {
              const selected = String(event.target.value || '').trim()
              if (!selected) return
              onAdd(campo, selected)
              event.target.value = ''
            }}
          >
            <option value="">Adicionar fonte...</option>
            {opcoesAdicionar.map((item) => (
              <option key={`${campo}-opt-${item.id}`} value={item.id}>{item.label}</option>
            ))}
          </select>
        </div>
      </div>
    )
  }

  return (
    <div className="pesquisa-admin-panel">
      <div className="row pesquisa-actions pesquisa-actions-primary">
        <button type="button" onClick={() => void onSalvar()} disabled={saving || loading || !dirty}>
          {saving ? 'Salvando...' : 'Salvar configuracao'}
        </button>
        <button type="button" onClick={() => void carregar()} disabled={saving || loading}>
          Recarregar
        </button>
      </div>

      {status ? <div className="status-line">{status}</div> : null}
      {error ? <div className="error-line inline-error">{error}</div> : null}

      <div className="pesquisa-admin-fields">
        {CAMPOS_UNIFICADOS.map((campo) => renderCampo(campo.id, campo.label))}
      </div>
    </div>
  )
}
