import React, { useEffect, useState } from 'react'
import { api, downloadBlob } from '../api'
import DataTable from './DataTable'
import EquationFormatsPanel from './EquationFormatsPanel'
import LoadingOverlay from './LoadingOverlay'
import MapFrame from './MapFrame'
import PlotFigure from './PlotFigure'

const REPO_INNER_TABS = [
  { key: 'mapa', label: 'Mapa' },
  { key: 'dados_mercado', label: 'Dados de Mercado' },
  { key: 'metricas', label: 'Métricas' },
  { key: 'transformacoes', label: 'Transformações' },
  { key: 'resumo', label: 'Resumo' },
  { key: 'coeficientes', label: 'Coeficientes' },
  { key: 'obs_calc', label: 'Obs x Calc' },
  { key: 'graficos', label: 'Gráficos' },
]

function formatarFonte(fonte) {
  if (!fonte || typeof fonte !== 'object') return 'Fonte não informada'
  const provider = String(fonte.provider || '').toLowerCase()
  if (provider === 'hf_dataset') {
    const repo = String(fonte.repo_id || '').trim()
    const revision = String(fonte.revision || '').trim()
    const suffix = fonte.degraded ? ' (modo contingência)' : ''
    return `HF Dataset${repo ? ` (${repo})` : ''}${revision ? ` | revisão ${revision.slice(0, 8)}` : ''}${suffix}`
  }
  return 'Pasta local'
}

export default function RepositorioTab({ authUser, sessionId }) {
  const [modelos, setModelos] = useState([])
  const [fonte, setFonte] = useState(null)
  const [loading, setLoading] = useState(false)
  const [uploading, setUploading] = useState(false)
  const [deleting, setDeleting] = useState(false)
  const [error, setError] = useState('')
  const [status, setStatus] = useState('')
  const [arquivoUpload, setArquivoUpload] = useState(null)
  const [confirmDeleteId, setConfirmDeleteId] = useState('')
  const [confirmarSubstituicao, setConfirmarSubstituicao] = useState({ open: false, substituidos: [] })
  const [confirmarExclusaoModal, setConfirmarExclusaoModal] = useState({
    open: false,
    modeloId: '',
    nomeModelo: '',
    digitado: '',
  })

  const [modeloAbertoMeta, setModeloAbertoMeta] = useState(null)
  const [modeloAbertoLoading, setModeloAbertoLoading] = useState(false)
  const [modeloAbertoError, setModeloAbertoError] = useState('')
  const [modeloAbertoActiveTab, setModeloAbertoActiveTab] = useState('mapa')
  const [modeloAbertoDados, setModeloAbertoDados] = useState(null)
  const [modeloAbertoEstatisticas, setModeloAbertoEstatisticas] = useState(null)
  const [modeloAbertoEscalasHtml, setModeloAbertoEscalasHtml] = useState('')
  const [modeloAbertoDadosTransformados, setModeloAbertoDadosTransformados] = useState(null)
  const [modeloAbertoResumoHtml, setModeloAbertoResumoHtml] = useState('')
  const [modeloAbertoEquacoes, setModeloAbertoEquacoes] = useState(null)
  const [modeloAbertoCoeficientes, setModeloAbertoCoeficientes] = useState(null)
  const [modeloAbertoObsCalc, setModeloAbertoObsCalc] = useState(null)
  const [modeloAbertoMapaHtml, setModeloAbertoMapaHtml] = useState('')
  const [modeloAbertoMapaChoices, setModeloAbertoMapaChoices] = useState(['Visualização Padrão'])
  const [modeloAbertoMapaVar, setModeloAbertoMapaVar] = useState('Visualização Padrão')
  const [modeloAbertoPlotObsCalc, setModeloAbertoPlotObsCalc] = useState(null)
  const [modeloAbertoPlotResiduos, setModeloAbertoPlotResiduos] = useState(null)
  const [modeloAbertoPlotHistograma, setModeloAbertoPlotHistograma] = useState(null)
  const [modeloAbertoPlotCook, setModeloAbertoPlotCook] = useState(null)
  const [modeloAbertoPlotCorr, setModeloAbertoPlotCorr] = useState(null)

  const isAdmin = String(authUser?.perfil || '').toLowerCase() === 'admin'
  const totalModelos = modelos.length
  const modoModeloAberto = Boolean(modeloAbertoMeta)
  const nomesSubstituidos = Array.isArray(confirmarSubstituicao.substituidos)
    ? confirmarSubstituicao.substituidos.filter(Boolean)
    : []
  const exclusaoDigitadaCorreta = confirmarExclusaoModal.digitado === confirmarExclusaoModal.nomeModelo

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

  async function carregarModelos() {
    setLoading(true)
    setError('')
    try {
      const resp = await api.repositorioListar()
      setModelos(Array.isArray(resp?.modelos) ? resp.modelos : [])
      setFonte(resp?.fonte || null)
      setStatus('')
    } catch (err) {
      setError(err.message || 'Falha ao carregar repositório.')
      setModelos([])
      setFonte(null)
    } finally {
      setLoading(false)
    }
  }

  function parseSubstituidosErro(err) {
    if (!err || typeof err !== 'object') return []
    const detail = err.detail
    if (!detail || typeof detail !== 'object') return []
    const lista = detail.substituidos
    if (!Array.isArray(lista)) return []
    return lista.map((item) => String(item || '').trim()).filter(Boolean)
  }

  async function onUploadArquivo(confirmar = false) {
    if (!isAdmin || !arquivoUpload) return
    setUploading(true)
    setError('')
    setStatus('')
    try {
      const resp = await api.repositorioUpload([arquivoUpload], { confirmarSubstituicao: confirmar })
      setModelos(Array.isArray(resp?.modelos) ? resp.modelos : [])
      setFonte(resp?.fonte || null)
      setStatus(resp?.status || 'Modelo incluído no repositório.')
      setArquivoUpload(null)
      setConfirmarSubstituicao({ open: false, substituidos: [] })
    } catch (err) {
      const substituidos = parseSubstituidosErro(err)
      const erroDuplicado = Number(err?.status) === 409 && substituidos.length > 0
      if (!confirmar && erroDuplicado) {
        setConfirmarSubstituicao({ open: true, substituidos })
        setError('')
        return
      }
      setError(err.message || 'Falha ao incluir modelo no repositório.')
    } finally {
      setUploading(false)
    }
  }

  async function onExcluirModelo(modeloId) {
    if (!isAdmin || !modeloId) return
    setDeleting(true)
    setError('')
    setStatus('')
    try {
      const resp = await api.repositorioDelete([String(modeloId)])
      setModelos(Array.isArray(resp?.modelos) ? resp.modelos : [])
      setFonte(resp?.fonte || null)
      setStatus(resp?.status || 'Modelo removido do repositório.')
      setConfirmDeleteId('')
      setConfirmarExclusaoModal({ open: false, modeloId: '', nomeModelo: '', digitado: '' })
    } catch (err) {
      setError(err.message || 'Falha na exclusão do modelo.')
    } finally {
      setDeleting(false)
    }
  }

  function onAbrirModalExclusao(item) {
    const id = String(item?.id || '').trim()
    if (!id) return
    const nomeModelo = String(item?.nome_modelo || item?.arquivo || id).trim()
    setConfirmDeleteId('')
    setConfirmarExclusaoModal({
      open: true,
      modeloId: id,
      nomeModelo,
      digitado: '',
    })
  }

  function onCancelarModalExclusao() {
    if (deleting) return
    setConfirmarExclusaoModal({ open: false, modeloId: '', nomeModelo: '', digitado: '' })
  }

  async function onConfirmarExclusaoModal() {
    const modeloId = String(confirmarExclusaoModal.modeloId || '').trim()
    if (!modeloId) return
    if (confirmarExclusaoModal.digitado !== confirmarExclusaoModal.nomeModelo) return
    await onExcluirModelo(modeloId)
  }

  function preencherModeloAberto(resp) {
    setModeloAbertoDados(resp?.dados || null)
    setModeloAbertoEstatisticas(resp?.estatisticas || null)
    setModeloAbertoEscalasHtml(resp?.escalas_html || '')
    setModeloAbertoDadosTransformados(resp?.dados_transformados || null)
    setModeloAbertoResumoHtml(resp?.resumo_html || '')
    setModeloAbertoEquacoes(resp?.equacoes || null)
    setModeloAbertoCoeficientes(resp?.coeficientes || null)
    setModeloAbertoObsCalc(resp?.obs_calc || null)
    setModeloAbertoMapaHtml(resp?.mapa_html || '')
    setModeloAbertoMapaChoices(resp?.mapa_choices || ['Visualização Padrão'])
    setModeloAbertoMapaVar('Visualização Padrão')
    setModeloAbertoPlotObsCalc(resp?.grafico_obs_calc || null)
    setModeloAbertoPlotResiduos(resp?.grafico_residuos || null)
    setModeloAbertoPlotHistograma(resp?.grafico_histograma || null)
    setModeloAbertoPlotCook(resp?.grafico_cook || null)
    setModeloAbertoPlotCorr(resp?.grafico_correlacao || null)
  }

  async function onAbrirModelo(item) {
    if (!sessionId) {
      setError('Sessão indisponível no momento. Aguarde e tente novamente.')
      return
    }
    setModeloAbertoLoading(true)
    setModeloAbertoError('')
    try {
      await api.visualizacaoRepositorioCarregar(sessionId, String(item?.id || ''))
      const resp = await api.exibirVisualizacao(sessionId)
      preencherModeloAberto(resp)
      setModeloAbertoActiveTab('mapa')
      setModeloAbertoMeta({
        id: String(item?.id || ''),
        nome: item?.nome_modelo || item?.arquivo || String(item?.id || ''),
      })
    } catch (err) {
      setModeloAbertoError(err.message || 'Falha ao abrir modelo.')
    } finally {
      setModeloAbertoLoading(false)
    }
  }

  function onVoltarRepositorio() {
    setModeloAbertoMeta(null)
    setModeloAbertoError('')
    setModeloAbertoActiveTab('mapa')
  }

  async function onModeloAbertoMapChange(nextVar) {
    setModeloAbertoMapaVar(nextVar)
    if (!sessionId) return
    try {
      const resp = await api.updateVisualizacaoMap(sessionId, nextVar)
      setModeloAbertoMapaHtml(resp?.mapa_html || '')
    } catch (err) {
      setModeloAbertoError(err.message || 'Falha ao atualizar mapa do modelo.')
    }
  }

  async function onDownloadEquacaoModeloAberto(mode) {
    if (!sessionId || !mode) return
    setModeloAbertoLoading(true)
    try {
      const blob = await api.exportEquationViz(sessionId, mode)
      const sufixo = String(mode) === 'excel_sab' ? 'estilo_sab' : 'excel'
      downloadBlob(blob, `equacao_modelo_${sufixo}.xlsx`)
    } catch (err) {
      setModeloAbertoError(err.message || 'Falha ao exportar equação.')
    } finally {
      setModeloAbertoLoading(false)
    }
  }

  if (modoModeloAberto) {
    return (
      <div className="tab-content">
        <div className="pesquisa-opened-model-view">
          <div className="pesquisa-opened-model-head">
            <div className="pesquisa-opened-model-title-wrap">
              <h3>{modeloAbertoMeta?.nome || 'Modelo'}</h3>
              <p>Visualização do modelo do repositório</p>
            </div>
            <button type="button" className="model-source-back-btn model-source-back-btn-danger" onClick={onVoltarRepositorio} disabled={modeloAbertoLoading}>
              Voltar ao repositório
            </button>
          </div>

          <div className="inner-tabs" role="tablist" aria-label="Abas internas do modelo aberto no repositório">
            {REPO_INNER_TABS.map((tab) => (
              <button
                key={tab.key}
                type="button"
                className={modeloAbertoActiveTab === tab.key ? 'inner-tab-pill active' : 'inner-tab-pill'}
                onClick={() => setModeloAbertoActiveTab(tab.key)}
              >
                {tab.label}
              </button>
            ))}
          </div>

          <div className="inner-tab-panel">
            {modeloAbertoActiveTab === 'mapa' ? (
              <>
                <div className="row compact visualizacao-mapa-controls">
                  <label>Variável no mapa</label>
                  <select value={modeloAbertoMapaVar} onChange={(event) => void onModeloAbertoMapChange(event.target.value)}>
                    {modeloAbertoMapaChoices.map((choice) => (
                      <option key={`repo-modelo-aberto-mapa-${choice}`} value={choice}>{choice}</option>
                    ))}
                  </select>
                </div>
                <MapFrame html={modeloAbertoMapaHtml} />
              </>
            ) : null}

            {modeloAbertoActiveTab === 'dados_mercado' ? <DataTable table={modeloAbertoDados} maxHeight={620} /> : null}
            {modeloAbertoActiveTab === 'metricas' ? <DataTable table={modeloAbertoEstatisticas} maxHeight={620} /> : null}

            {modeloAbertoActiveTab === 'transformacoes' ? (
              <>
                <div dangerouslySetInnerHTML={{ __html: modeloAbertoEscalasHtml }} />
                <h4 className="visualizacao-table-title">Dados com variáveis transformadas</h4>
                <DataTable table={modeloAbertoDadosTransformados} />
              </>
            ) : null}

            {modeloAbertoActiveTab === 'resumo' ? (
              <>
                <div className="equation-formats-section">
                  <h4>Equações do Modelo</h4>
                  <EquationFormatsPanel
                    equacoes={modeloAbertoEquacoes}
                    onDownload={(mode) => void onDownloadEquacaoModeloAberto(mode)}
                    disabled={modeloAbertoLoading}
                  />
                </div>
                <div dangerouslySetInnerHTML={{ __html: modeloAbertoResumoHtml }} />
              </>
            ) : null}

            {modeloAbertoActiveTab === 'coeficientes' ? <DataTable table={modeloAbertoCoeficientes} maxHeight={620} /> : null}
            {modeloAbertoActiveTab === 'obs_calc' ? <DataTable table={modeloAbertoObsCalc} maxHeight={620} /> : null}

            {modeloAbertoActiveTab === 'graficos' ? (
              <>
                <div className="plot-grid-2-fixed">
                  <PlotFigure figure={modeloAbertoPlotObsCalc} title="Obs x Calc" />
                  <PlotFigure figure={modeloAbertoPlotResiduos} title="Resíduos" />
                  <PlotFigure figure={modeloAbertoPlotHistograma} title="Histograma" />
                  <PlotFigure figure={modeloAbertoPlotCook} title="Cook" forceHideLegend />
                </div>
                <div className="plot-full-width">
                  <PlotFigure figure={modeloAbertoPlotCorr} title="Correlação" className="plot-correlation-card" />
                </div>
              </>
            ) : null}
          </div>

          {modeloAbertoError ? <div className="error-line inline-error">{modeloAbertoError}</div> : null}
        </div>
        <LoadingOverlay show={modeloAbertoLoading} label="Carregando modelo..." />
      </div>
    )
  }

  return (
    <div className="tab-content">
      <div className="repositorio-standalone-panel">
        <div className="repo-toolbar">
          <div className="repo-summary">
            <div><strong>Total:</strong> {totalModelos}</div>
            <div><strong>Fonte:</strong> {formatarFonte(fonte)}</div>
            <div><strong>Perfil:</strong> {isAdmin ? 'Administrador' : 'Leitura'}</div>
          </div>
          <div className="repo-actions">
            <button
              type="button"
              className="repo-refresh-btn"
              onClick={() => void carregarModelos()}
              disabled={loading || uploading || deleting}
            >
              Atualizar lista
            </button>
          </div>
        </div>

        {isAdmin ? (
          <div className="repo-admin-controls">
            <div className="repo-upload-row repo-upload-row-single">
              <input
                type="file"
                accept=".dai"
                onChange={(event) => setArquivoUpload(event.target.files?.[0] || null)}
                disabled={uploading || deleting}
              />
              <button type="button" onClick={() => void onUploadArquivo()} disabled={uploading || deleting || !arquivoUpload}>
                Incluir modelo no repositório
              </button>
            </div>
            {arquivoUpload ? <div className="section1-empty-hint">Arquivo selecionado: {arquivoUpload.name}</div> : null}
          </div>
        ) : (
          <div className="section1-empty-hint">Perfil de leitura: inclusão e exclusão disponíveis apenas para administradores.</div>
        )}

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

        <div className="table-container repo-table-block">
          <table className="repo-table">
            <thead>
              <tr>
                <th>Modelo</th>
                <th>Tipo</th>
                <th>Finalidade</th>
                <th>Autor</th>
                <th>Período</th>
                <th>Dados</th>
                <th>APP</th>
                <th>Status</th>
                <th className="repo-col-open">Abrir</th>
                {isAdmin ? <th className="repo-col-delete">Excluir</th> : null}
              </tr>
            </thead>
            <tbody>
              {modelos.map((item) => {
                const key = String(item.id)
                const emConfirmacao = confirmDeleteId === key
                return (
                  <tr key={key}>
                    <td>{item.nome_modelo || item.arquivo || key}</td>
                    <td>{item.tipo_imovel || '-'}</td>
                    <td>{item.finalidade || '-'}</td>
                    <td>{item.autor || '-'}</td>
                    <td>{item.periodo_dados?.label || '-'}</td>
                    <td>{item.total_dados ?? '-'}</td>
                    <td>{item.tem_app ? 'Sim' : 'Não'}</td>
                    <td>{item.status || '-'}</td>
                    <td className="repo-col-open">
                      <button
                        type="button"
                        className="repo-open-btn"
                        onClick={() => void onAbrirModelo(item)}
                        title="Abrir modelo"
                        aria-label={`Abrir ${item.nome_modelo || item.arquivo || key}`}
                      >
                        ↗
                      </button>
                    </td>
                    {isAdmin ? (
                      <td className="repo-col-delete">
                        {!emConfirmacao ? (
                          <button
                            type="button"
                            className="repo-delete-icon-btn"
                            onClick={() => setConfirmDeleteId(key)}
                            disabled={deleting}
                            title="Excluir modelo"
                            aria-label={`Excluir ${item.nome_modelo || item.arquivo || key}`}
                          >
                            🗑
                          </button>
                        ) : (
                          <div className="repo-delete-inline-confirm">
                            <button
                              type="button"
                              className="btn-danger repo-delete-confirm-btn"
                              onClick={() => onAbrirModalExclusao(item)}
                              disabled={deleting}
                            >
                              Excluir
                            </button>
                            <button
                              type="button"
                              className="repo-delete-cancel-btn"
                              onClick={() => setConfirmDeleteId('')}
                              disabled={deleting}
                            >
                              Cancelar
                            </button>
                          </div>
                        )}
                      </td>
                    ) : null}
                  </tr>
                )
              })}
              {!modelos.length ? (
                <tr>
                  <td colSpan={isAdmin ? 10 : 9}>
                    {loading ? 'Carregando modelos...' : 'Nenhum modelo encontrado no repositório.'}
                  </td>
                </tr>
              ) : null}
            </tbody>
          </table>
        </div>
      </div>

      {confirmarSubstituicao.open ? (
        <div className="pesquisa-modal-backdrop">
          <div className="pesquisa-modal repo-confirm-modal">
            <div className="pesquisa-modal-head">
              <div>
                <h4>Confirmar substituição de modelo</h4>
                <p>Já existe modelo com o mesmo nome no repositório.</p>
              </div>
              <button
                type="button"
                className="pesquisa-modal-close"
                onClick={() => setConfirmarSubstituicao({ open: false, substituidos: [] })}
                disabled={uploading}
              >
                Fechar
              </button>
            </div>
            <div className="repo-confirm-modal-body">
              <div className="repo-confirm-text">
                Se você continuar, o modelo existente será substituído.
              </div>
              <ul className="repo-replace-list">
                {(nomesSubstituidos.length ? nomesSubstituidos : [String(arquivoUpload?.name || '')]).map((nome) => (
                  <li key={`substituir-${nome}`}>{nome}</li>
                ))}
              </ul>
              <div className="repo-confirm-actions">
                <button
                  type="button"
                  className="repo-delete-cancel-btn"
                  onClick={() => setConfirmarSubstituicao({ open: false, substituidos: [] })}
                  disabled={uploading}
                >
                  Cancelar
                </button>
                <button
                  type="button"
                  className="btn-danger"
                  onClick={() => void onUploadArquivo(true)}
                  disabled={uploading}
                >
                  {uploading ? 'Substituindo...' : 'Confirmar substituição'}
                </button>
              </div>
            </div>
          </div>
        </div>
      ) : null}

      {confirmarExclusaoModal.open ? (
        <div className="pesquisa-modal-backdrop">
          <div className="pesquisa-modal repo-confirm-modal">
            <div className="pesquisa-modal-head">
              <div>
                <h4>{confirmarExclusaoModal.nomeModelo || 'Confirmar exclusão'}</h4>
                <p>Digite o nome completo do modelo para confirmar a exclusão.</p>
              </div>
              <button
                type="button"
                className="pesquisa-modal-close"
                onClick={onCancelarModalExclusao}
                disabled={deleting}
              >
                Fechar
              </button>
            </div>
            <form
              className="repo-confirm-modal-body"
              onSubmit={(event) => {
                event.preventDefault()
                void onConfirmarExclusaoModal()
              }}
            >
              <label className="repo-delete-typing-field">
                Nome do modelo
                <input
                  type="text"
                  value={confirmarExclusaoModal.digitado}
                  onChange={(event) => setConfirmarExclusaoModal((prev) => ({ ...prev, digitado: event.target.value }))}
                  placeholder="Digite exatamente como no título"
                  autoComplete="off"
                  disabled={deleting}
                />
              </label>
              {confirmarExclusaoModal.digitado && !exclusaoDigitadaCorreta ? (
                <div className="repo-delete-typing-hint repo-delete-typing-hint-error">
                  O texto digitado não corresponde ao nome do modelo.
                </div>
              ) : (
                <div className="repo-delete-typing-hint">
                  A exclusão será concluída somente quando o nome for digitado exatamente.
                </div>
              )}
              <div className="repo-confirm-actions">
                <button type="button" className="repo-delete-cancel-btn" onClick={onCancelarModalExclusao} disabled={deleting}>
                  Cancelar
                </button>
                <button type="submit" className="btn-danger" disabled={deleting || !exclusaoDigitadaCorreta}>
                  {deleting ? 'Excluindo...' : 'Excluir modelo'}
                </button>
              </div>
            </form>
          </div>
        </div>
      ) : null}
    </div>
  )
}
