import { useState, useEffect, useRef } from 'react';
import Header from './components/Header';
import ConsultorCard from './components/ConsultorCard';
import CompararModal from './components/CompararModal';
import FiltroSelos from './components/FiltroSelos';
import FiltroAtivo from './components/FiltroAtivo';
import SugerirConsultores from './components/SugerirConsultores';
import ExportProgress from './components/ExportProgress';
import { rankingService } from './services/api';
import './App.css';

function App() {
  const [consultores, setConsultores] = useState([]);
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState(null);
  const [processing, setProcessing] = useState(false);
  const [processMessage, setProcessMessage] = useState('');
  const processStartedRef = useRef(false);
  const [total, setTotal] = useState(0);
  const [page, setPage] = useState(1);
  const [pageSize, setPageSize] = useState(50);
  const [totalPages, setTotalPages] = useState(0);
  const [highlightId, setHighlightId] = useState(null);
  const [busca, setBusca] = useState('');
  const [buscando, setBuscando] = useState(false);
  const [selecionados, setSelecionados] = useState([]);
  const [modalAberto, setModalAberto] = useState(false);
  const [filtroSelos, setFiltroSelos] = useState([]);
  const [filtroAtivo, setFiltroAtivo] = useState(null);
  const [sugerirAberto, setSugerirAberto] = useState(false);
  const [exportando, setExportando] = useState(false);
  const [exportProgress, setExportProgress] = useState({ loaded: 0, total: 0, percent: 0 });
  const [exportStatus, setExportStatus] = useState('preparing');
  const abortControllerRef = useRef(null);
  const loadingRef = useRef(false);

  const toggleSelecionado = (consultor) => {
    setSelecionados((prev) => {
      const existe = prev.find((c) => c.id_pessoa === consultor.id_pessoa);
      if (existe) {
        return prev.filter((c) => c.id_pessoa !== consultor.id_pessoa);
      }
      if (prev.length >= 2) {
        return [prev[1], consultor];
      }
      return [...prev, consultor];
    });
  };

  const limparSelecao = () => {
    setSelecionados([]);
    setModalAberto(false);
  };

  const handleSugestaoSelecionada = async (idPessoa) => {
    try {
      const response = await fetch(`/api/v1/ranking/posicao/${idPessoa}`);
      if (response.ok) {
        const alvo = await response.json();
        if (alvo.encontrado && alvo.posicao) {
          const pagina = Math.ceil(alvo.posicao / pageSize);
          setHighlightId(alvo.id_pessoa);
          setPage(pagina);
        }
      }
    } catch (err) {
      console.error('Erro ao navegar para consultor:', err);
    }
  };

  const handleExportarExcel = async () => {
    if (exportando) return;
    try {
      setExportando(true);
      setExportStatus('preparing');
      setExportProgress({ loaded: 0, total: 0, percent: 0 });

      abortControllerRef.current = new AbortController();

      await rankingService.downloadRankingExcel(
        filtroSelos,
        filtroAtivo,
        (progress) => {
          setExportStatus('downloading');
          setExportProgress(progress);
        },
        abortControllerRef.current
      );

      setExportStatus('complete');
      setTimeout(() => setExportando(false), 1000);
    } catch (err) {
      if (err.name === 'CanceledError' || err.code === 'ERR_CANCELED') {
        console.log('Exportação cancelada pelo usuário');
      } else {
        console.error('Erro ao exportar Excel:', err);
        setExportStatus('error');
        setTimeout(() => setExportando(false), 2000);
      }
    }
  };

  const handleCancelExport = () => {
    if (abortControllerRef.current) {
      abortControllerRef.current.abort();
      abortControllerRef.current = null;
    }
    setExportando(false);
  };

  useEffect(() => {
    const requestKey = `${page}-${pageSize}-${filtroSelos.join(',')}-${filtroAtivo}`;
    if (loadingRef.current === requestKey) {
      return;
    }
    loadingRef.current = requestKey;
    loadRanking();
  }, [page, pageSize, filtroSelos, filtroAtivo]);

  const loadRanking = async (retryCount = 0) => {
    const MAX_RETRIES = 10;
    const RETRY_DELAY = 2000;

    try {
      setLoading(true);
      setError(null);
      setProcessMessage('');
      const response = await rankingService.getRanking(page, pageSize, filtroSelos, filtroAtivo);
      setConsultores(response.consultores);
      setTotal(response.total);
      setTotalPages(response.total_pages || 0);
      setPage(response.page || page);
    } catch (err) {
      const status = err?.response?.status;
      const isNetworkError = !err?.response || err?.code === 'ERR_NETWORK';

      if (isNetworkError && retryCount < MAX_RETRIES) {
        setProcessMessage(`Aguardando API... (tentativa ${retryCount + 1}/${MAX_RETRIES})`);
        await new Promise((r) => setTimeout(r, RETRY_DELAY));
        return loadRanking(retryCount + 1);
      }

      if (status === 503) {
        try {
          setProcessing(true);
          if (!processStartedRef.current) {
            processStartedRef.current = true;
            setProcessMessage('Ranking ainda não processado. Iniciando processamento...');
            try {
              await rankingService.processarRanking(true);
            } catch (e) {
              const st = e?.response?.status;
              if (st !== 409) throw e; // 409 = job já em execução (ex.: StrictMode)
            }
          } else {
            setProcessMessage('Processamento do ranking já iniciado. Aguardando...');
          }

          const MAX_POLLING_TIME = 45 * 60 * 1000;
          const POLLING_INTERVAL = 4000;
          const startTime = Date.now();

          while (Date.now() - startTime < MAX_POLLING_TIME) {
            try {
              const st = await rankingService.getStatus();
              setProcessMessage(st.mensagem || `Processando... ${st.progress || 0}%`);
              if (!st.running) {
                if (st.erro) throw new Error(st.erro);
                break;
              }
            } catch (e) {
              setProcessMessage('Aguardando status do processamento...');
            }
            await new Promise((r) => setTimeout(r, POLLING_INTERVAL));
          }

          if (Date.now() - startTime >= MAX_POLLING_TIME) {
            throw new Error('Timeout: processamento demorou mais que 45 minutos');
          }

          const response = await rankingService.getRanking(page, pageSize, filtroSelos, filtroAtivo);
          setConsultores(response.consultores);
          setTotal(response.total);
          setTotalPages(response.total_pages || 0);
          setPage(response.page || page);
        } catch (e) {
          console.error('Erro ao processar ranking:', e);
          setError('Erro ao processar ranking. Verifique a conexão com o Elasticsearch.');
        } finally {
          setProcessing(false);
        }
        return;
      }

      console.error('Erro ao carregar ranking:', err);
      setError('Erro ao carregar ranking. Verifique se a API está rodando.');
    } finally {
      setLoading(false);
    }
  };

  const handleBuscar = async () => {
    if (busca.trim().length < 3) return;
    try {
      setBuscando(true);
      const resultados = await rankingService.searchConsultor(busca.trim(), 5);
      if (resultados && resultados.length > 0) {
        const alvo = resultados[0];
        const pos = alvo.posicao || 1;
        const pagina = Math.ceil(pos / pageSize);
        setHighlightId(alvo.id_pessoa);
        setPage(pagina);
      } else {
        alert('Nenhum consultor encontrado.');
      }
    } catch (err) {
      alert('Erro ao buscar consultor.');
    } finally {
      setBuscando(false);
    }
  };

  const handleSubmitBuscar = (e) => {
    e.preventDefault();
    if (buscando) return;
    handleBuscar();
  };

  if (loading) {
    return (
      <div className="container">
        <div className="loading">
          {processMessage || (processing ? 'Processando ranking...' : 'Carregando ranking...')}
        </div>
      </div>
    );
  }

  if (error) {
    return (
      <div className="container">
        <div className="error">
          <h2>Erro</h2>
          <p>{error}</p>
          <button onClick={loadRanking}>Tentar novamente</button>
        </div>
      </div>
    );
  }

  return (
    <div className="container">
      <Header total={total} />

      <div className="controls">
        <div className="control-group">
          <span className="control-group-label">Exibir:</span>
          <select value={pageSize} onChange={(e) => { setPageSize(Number(e.target.value)); setPage(1); }}>
            <option value={10}>10</option>
            <option value={50}>50</option>
            <option value={100}>100</option>
            <option value={200}>200</option>
            <option value={500}>500</option>
          </select>
        </div>

        <FiltroSelos
          selecionados={filtroSelos}
          onChange={(selos) => { setFiltroSelos(selos); setPage(1); }}
        />

        <FiltroAtivo
          valor={filtroAtivo}
          onChange={(valor) => { setFiltroAtivo(valor); setPage(1); }}
        />

        <button className="btn-sugerir" onClick={() => setSugerirAberto(true)}>
          Sugerir por Tema
        </button>

        <button
          className="btn-exportar"
          onClick={handleExportarExcel}
          disabled={exportando || loading}
          title="Exportar ranking para Excel (apenas consultores com pontuação)"
        >
          {exportando ? 'Exportando...' : '📊 Exportar Excel'}
        </button>

        <div className="pagination">
          <button onClick={() => setPage(1)} disabled={page <= 1}>«</button>
          <button onClick={() => setPage((p) => Math.max(1, p - 1))} disabled={page <= 1}>‹</button>
          <span className="page-info">{page} / {totalPages || '?'}</span>
          <button onClick={() => setPage((p) => (totalPages ? Math.min(totalPages, p + 1) : p + 1))} disabled={totalPages && page >= totalPages}>›</button>
          <button onClick={() => totalPages && setPage(totalPages)} disabled={totalPages && page >= totalPages}>»</button>
        </div>

        <form className="search-box" onSubmit={handleSubmitBuscar}>
          <input
            type="text"
            placeholder="Buscar por nome..."
            value={busca}
            onChange={(e) => setBusca(e.target.value)}
          />
          <button type="submit" disabled={buscando || busca.length < 3}>
            {buscando ? '...' : 'Buscar'}
          </button>
        </form>
      </div>

      <div className="ranking-list">
        {consultores.map((consultor) => (
          <ConsultorCard
            key={consultor.id_pessoa}
            consultor={consultor}
            highlight={consultor.id_pessoa === highlightId}
            selecionado={selecionados.some((c) => c.id_pessoa === consultor.id_pessoa)}
            onToggleSelecionado={toggleSelecionado}
            totalConsultores={total}
          />
        ))}
      </div>

      {selecionados.length > 0 && (
        <div className="selecao-flutuante">
          <div className="selecao-info">
            <span>{selecionados.length}/2 selecionados</span>
            {selecionados.map((c) => (
              <span key={c.id_pessoa} className="selecao-nome">{c.nome.split(' ')[0]}</span>
            ))}
          </div>
          <div className="selecao-acoes">
            <button className="btn-limpar" onClick={limparSelecao}>Limpar</button>
            <button
              className="btn-comparar"
              disabled={selecionados.length < 2}
              onClick={() => setModalAberto(true)}
            >
              Comparar
            </button>
          </div>
        </div>
      )}

      {modalAberto && (
        <CompararModal
          consultor1={selecionados[0]}
          consultor2={selecionados[1]}
          onClose={() => setModalAberto(false)}
        />
      )}

      {sugerirAberto && (
        <SugerirConsultores
          onClose={() => setSugerirAberto(false)}
          onSelectConsultor={handleSugestaoSelecionada}
        />
      )}

      {exportando && (
        <ExportProgress
          progress={exportProgress}
          status={exportStatus}
          onCancel={handleCancelExport}
        />
      )}

      <footer>
        <p>Dados: ATUACAPES (Elasticsearch) + Oracle</p>
        <p>Clique em qualquer consultor para ver detalhes</p>
      </footer>
    </div>
  );
}

export default App;
