import React, { useState, useEffect } from 'react';
import * as XLSX from 'xlsx';
import { useAuth } from '../contexts/AuthContext';
import { useRegion } from '../contexts/RegionContext';
import { Button } from '../components/Button';
import { Upload, FileText, CheckCircle, AlertTriangle, Calendar, Database, UserPlus } from 'lucide-react';

const API_BASE_URL = import.meta.env.VITE_API_URL || "http://localhost:8080";

type ImportType = 'fot' | 'agenda' | 'profissionais' | 'financeiro';

interface ImportFotInput {
  fot: string;
  empresa_nome: string;
  curso_nome: string;
  ano_formatura_label: string;
  instituicao: string;
  cidade: string;
  estado: string;
  observacoes: string;
  gastos_captacao: number;
  pre_venda: boolean;
}

interface ImportAgendaInput {
  fot: string;
  data: string;
  tipo_evento: string;
  observacoes: string;
  local: string;
  endereco: string;
  horario: string;
  qtd_formandos: number;
  qtd_fotografos: number;
  qtd_cinegrafistas: number;
  qtd_recepcionistas: number;
  qtd_estudios: number;
  qtd_ponto_foto: number;
  qtd_ponto_id: number;
  qtd_ponto_decorado: number;
  qtd_pontos_led: number;
  qtd_plataforma_360: number;
  foto_faltante: number;
  recep_faltante: number;
  cine_faltante: number;
  logistica_observacoes: string;
  pre_venda: boolean;
}

interface ImportProfissionalInput {
    id?: string; // Optional for validation display
    nome: string;
    funcao_profissional_id: string; // Must resolve to ID
    endereco: string;
    cidade: string;
    uf: string;
    whatsapp: string;
    cpf_cnpj_titular: string;
    banco: string;
    agencia: string;
    conta_pix: string;
    observacao: string;
    email: string; // Sometimes in PIX column
    // Add other fields as needed
}

interface ImportFinanceInput {
    fot: string;
    data: string;
    tipo_evento: string;
    tipo_servico: string;
    nome: string;
    whatsapp: string;
    cpf: string;
    tabela_free: string;
    valor_free: number;
    valor_extra: number;
    descricao_extra: string;
    total_pagar: number;
    data_pgto: string;
    pgto_ok: boolean;
}

export const ImportData: React.FC = () => {
  const { token } = useAuth();
  const { currentRegion } = useRegion();
  
  // Read initial tab from URL
  const query = new URLSearchParams(window.location.search);
  const initialTab = (query.get('tab') as ImportType) || 'fot';
  const [activeTab, setActiveTab] = useState<ImportType>(initialTab);
  
  // Generic data state (can be Fot, Agenda, Profissionais)
  const [data, setData] = useState<any[]>([]);
  const [filename, setFilename] = useState<string>("");
  const [isLoading, setIsLoading] = useState(false);
  const [result, setResult] = useState<{ success: number; errors: string[] } | null>(null);

  // Cache functions for mapping
  const [functionsMap, setFunctionsMap] = useState<Record<string, string>>({});

    useEffect(() => {
        // Fetch functions to map Name -> ID
        const fetchFunctions = async () => {
            if (!token) return;
            try {
                const res = await fetch(`${API_BASE_URL}/api/funcoes`, {
                    headers: { "Authorization": `Bearer ${token}` }
                });
                if (res.ok) {
                    const list = await res.json();
                    const map: Record<string, string> = {};
                    list.forEach((f: any) => {
                        map[f.nome.toLowerCase()] = f.id;
                        map[f.nome] = f.id; // Case sensitive fallback
                    });
                     // Add mappings for variations if common
                     map['fotografo'] = map['fotógrafo'];
                     map['fotógrafa'] = map['fotógrafo'];
                     map['recepcionista'] = map['recepcionista'];
                     // ...
                    setFunctionsMap(map);
                }
            } catch (e) {
                console.error("Failed to fetch functions", e);
            }
        };
        fetchFunctions();
    }, [token]);


   const [skippedCount, setSkippedCount] = useState(0);
   const [skippedReasons, setSkippedReasons] = useState<Record<string, number>>({});


  const handleTabChange = (tab: ImportType) => {
      if (tab !== activeTab) {
          setActiveTab(tab);
          setData([]);
          setSkippedCount(0);
          setFilename("");
          setResult(null);
      }
  };

  const handleFileUpload = (e: React.ChangeEvent<HTMLInputElement>) => {
    const file = e.target.files?.[0];
    if (!file) return;

    setFilename(file.name);
    setSkippedCount(0);
    const reader = new FileReader();
    reader.onload = (evt) => {
      const bstr = evt.target?.result;
      const wb = XLSX.read(bstr, { type: 'binary', cellStyles: true, cellNF: true, sheetStubs: true });
      const wsname = wb.SheetNames[0];
      const ws = wb.Sheets[wsname];
      const jsonData = XLSX.utils.sheet_to_json(ws, { header: 1 }) as any[][];
      const rows = jsonData as any[];
      
      // Access row metadata for hidden status (if available)
      const rowMeta = ws['!rows'] || [];

      let mappedData: any[] = [];
      let skipped = 0;
      let reasons: Record<string, number> = {};
      const processedFots = new Set<string>();

      const addReason = (msg: string) => {
          skipped++;
          reasons[msg] = (reasons[msg] || 0) + 1;
      };

      // HELPER: Check if row is hidden or empty
      const isRowHidden = (rowIndex: number) => {
          // Check if row exists in metadata and is hidden
          if (rowMeta && rowMeta[rowIndex] && rowMeta[rowIndex].hidden) return true;
          return false;
      };

      if (activeTab === 'financeiro') {
             // Dynamic Header Mapping
             // 1. Find header row (look for "FOT" and "Nome")
             let headerIdx = -1;
             const colMap: {[key: string]: number} = {};
             
             for (let i = 0; i < 20 && i < rows.length; i++) {
                 const rowStrings = (rows[i] as any[]).map(c => String(c).toLowerCase().trim());
                 if (rowStrings.some(s => s === 'fot' || s === 'nome' || s === 'cpf')) {
                     headerIdx = i;
                     rowStrings.forEach((h, idx) => {
                        if (h === 'fot' || h.includes('contrato')) colMap['fot'] = idx;
                        else if (h === 'data' || h.includes('dt evento') || h.includes('data evento')) colMap['data'] = idx;
                        else if (h.includes('evento')) colMap['evento'] = idx; // Match 'Tipo Evento', 'Evento', etc.
                        else if (h === 'serviço' || h === 'servico' || h.includes('função') || h.includes('tp serv') || h.includes('tipo de serv') || h.includes('tipo serv')) colMap['servico'] = idx;
                        else if (h === 'nome' || h === 'profissional') colMap['nome'] = idx;
                        else if (h === 'whatsapp' || h === 'whats' || h === 'tel' || h === 'cel') colMap['whatsapp'] = idx;
                        else if (h === 'cpf') colMap['cpf'] = idx;
                        else if (h.includes('tab') || h.includes('tabela')) colMap['tabela'] = idx;
                        else if (h.includes('v. free') || h.includes('valor free') || h === 'cache') colMap['vfree'] = idx;
                        else if (h.includes('v. extra') || h.includes('valor extra')) colMap['vextra'] = idx;
                        else if (h.includes('desc') || h.includes('obs extra')) colMap['descextra'] = idx;
                        else if (h === 'total' || h.includes('total')) colMap['total'] = idx;
                        else if (h.includes('dt pgto') || h.includes('data pag') || h.includes('data pgto')) colMap['datapgto'] = idx;
                        else if (h === 'ok' || h.includes('pago') || h === 'status') colMap['pgtook'] = idx;
                     });
                     break;
                 }
             }

             if (headerIdx === -1) {
                 // Fallback to index based if header not found
                 headerIdx = 0;
                 colMap['fot'] = 0; colMap['data'] = 1; colMap['evento'] = 2; colMap['servico'] = 3;
                 colMap['nome'] = 4; colMap['whatsapp'] = 5; colMap['cpf'] = 6; colMap['tabela'] = 7;
                 colMap['vfree'] = 8; colMap['vextra'] = 9; colMap['descextra'] = 10; colMap['total'] = 11;
                 colMap['datapgto'] = 12; colMap['pgtook'] = 13;
             }

             // Iterate data rows
             for (let i = headerIdx + 1; i < rows.length; i++) {
                 if (isRowHidden(i)) continue; // SKIP HIDDEN ROWS
                 const row = rows[i] as any[];
                 if (!row || row.length === 0) {
                     addReason("Linha Vazia/Separador");
                     continue;
                 }
                 
                  const getCol = (key: string) => {
                      const idx = colMap[key];
                      if (idx === undefined || idx < 0) return "";
                      return row[idx] !== undefined ? String(row[idx]).trim() : "";
                  };
                  
                  const getRawCol = (key: string) => {
                       const idx = colMap[key];
                       if (idx === undefined || idx < 0) return undefined;
                       return row[idx];
                  };

                  const fot = getCol('fot');
                  const nome = getCol('nome');
                  const totalPagar = getCol('total'); 
                  const valorFree = getCol('vfree');
                  
                  // Skip if Nome is empty AND (Total is 0 or empty AND Free is 0 or empty)
                  // AND FOT checks. 
                  const isTotalZero = !totalPagar || parseFloat(totalPagar.replace(/[R$\s.]/g, '').replace(',', '.')) === 0;
                  const isFreeZero = !valorFree || parseFloat(valorFree.replace(/[R$\s.]/g, '').replace(',', '.')) === 0;
                  
                  if (!fot && !nome) {
                      addReason("Linha Vazia/Separador");
                      continue; 
                  }
                  if (!nome && isTotalZero && isFreeZero) {
                      addReason("Linha sem Dados Financeiros");
                      continue; 
                  }
                 // VALIDATION STRICT: Skip if FOT and Nome are empty or just "-"
                 if ((!fot || fot.length < 1 || fot === '-') && (!nome || nome.length < 2)) {
                     addReason("Dados Incompletos (Sem FOT/Nome)");
                     continue;
                 }

                 const parseVal = (str: string) => {
                     if (!str) return 0;
                     // Handle 1.234,56 or 1234.56
                     let s = str.replace(/[R$\s]/g, '');
                     if (s.includes(',') && s.includes('.')) {
                        // 1.234,56 -> remove dots, replace comma with dot
                        s = s.replace(/\./g, '').replace(',', '.');
                     } else if (s.includes(',')) {
                        s = s.replace(',', '.');
                     }
                     return parseFloat(s) || 0;
                 };
                 
                 const parseDateCol = (key: string) => {
                     const raw = getRawCol(key);
                     if (typeof raw === 'number') {
                         const dateObj = new Date(Math.round((raw - 25569)*86400*1000));
                         // Return YYYY-MM-DD for backend consistency
                         return dateObj.toISOString().split('T')[0];
                     }
                     const str = getCol(key);
                     // Try to fix DD/MM/YYYY to YYYY-MM-DD
                     if (str.includes('/')) {
                         const parts = str.split('/');
                         if (parts.length === 3) return `${parts[2]}-${parts[1]}-${parts[0]}`;
                     }
                     return str;
                 };

                 const item: ImportFinanceInput = {
                     fot: fot,
                     data: parseDateCol('data'),
                     tipo_evento: getCol('evento'),
                     tipo_servico: getCol('servico'),
                     nome: getCol('nome'),
                     whatsapp: getCol('whatsapp'),
                     cpf: getCol('cpf'),
                     tabela_free: getCol('tabela'),
                     valor_free: parseVal(getCol('vfree')),
                     valor_extra: parseVal(getCol('vextra')),
                     descricao_extra: getCol('descextra'),
                     total_pagar: parseVal(getCol('total')),
                     data_pgto: parseDateCol('datapgto'),
                     pgto_ok: getCol('pgtook').toLowerCase().includes('sim') || getCol('pgtook').toLowerCase() === 'ok',
                 };
                 
                 mappedData.push(item);
             }
             
             setData(mappedData);
             setSkippedCount(0);
             setResult(null);
             return; // EXIT early for Finance
      }


      
      // Start from row 1 (skip header) for OTHER inputs
      for (let i = 1; i < jsonData.length; i++) {
        if (isRowHidden(i)) continue; // SKIP HIDDEN ROWS
        const row = jsonData[i];
        if (!row || row.length === 0) continue;

        // Helper to get string
        const getStr = (idx: number) => row[idx] ? String(row[idx]).trim() : "";
        
        // Helper to extract/clean CPF/CNPJ
        const cleanCpf = (raw: string): string => {
            if (!raw) return "";
            
            // 1. If explicit "CPF" or "CNPJ" label exists, prioritize digits after it
            const labelMatch = raw.match(/(?:cpf|cnpj)[\s:./-]*([\d.-]+)/i);
            if (labelMatch && labelMatch[1]) {
                 const digits = labelMatch[1].replace(/\D/g, '');
                 if (digits.length === 11 || digits.length === 14) return digits; // Return digits only? Or formatted?
                 // Let's return formatted if possible or just digits. 
                 // Storing digits-only is safer for matching.
                 return digits; 
            }

            // 2. Try to find standard CPF pattern (11 digits with separators)
            // 111.222.333-44
            const cpfPattern = /\b\d{3}\.\d{3}\.\d{3}-\d{2}\b/;
            const cpfMatch = raw.match(cpfPattern);
            if (cpfMatch) return cpfMatch[0].replace(/\D/g, '');

            // 3. Try standard CNPJ pattern
            const cnpjPattern = /\b\d{2}\.\d{3}\.\d{3}\/\d{4}-\d{2}\b/;
            const cnpjMatch = raw.match(cnpjPattern);
            if (cnpjMatch) return cnpjMatch[0].replace(/\D/g, '');

            // 4. Fallback: Cleanup all non-digits
            const onlyDigits = raw.replace(/\D/g, '');
            
            // If length is 11 (CPF) or 14 (CNPJ), assume valid
            if (onlyDigits.length === 11 || onlyDigits.length === 14) return onlyDigits;

            // If length is ambiguous (e.g. RG+CPF concatenated without separators and no labels), 
            // It's hard. But users usually put separators or labels.
            // If the user pasted "328 065 058 52" (Spaces), onlyDigits handles it (11 chars).
            
            // Should we return strict or loose?
            // If we can't detect, return empty to force 'Skipped'?
            // Or return original raw and let user verify?
            // Returning original raw breaks Claim match.
            // Better to return empty if invalid format, to alert user they need to fix Excel.
            if (onlyDigits.length > 0) return onlyDigits; // Return whatever we found?
            
            return "";
        };

        // Helper to clean UF (State code)
        const cleanUf = (raw: string): string => {
            if (!raw) return "";
            return raw.trim().slice(0, 2).toUpperCase();
        };

        // Helper to clean generic string with max len
        const cleanStr = (raw: string, maxLen: number): string => {
             if (!raw) return "";
             let s = raw.trim();
             if (s.length > maxLen) {
                 s = s.substring(0, maxLen);
             }
             return s;
        };

        // Helper to get int
        const getInt = (idx: number) => {
            const val = row[idx];
            if (!val) return 0;
            if (typeof val === 'number') return Math.floor(val);
            const parsed = parseInt(String(val).replace(/\D/g, ''), 10);
            return isNaN(parsed) ? 0 : parsed;
        };



        if (activeTab === 'fot') {
            // Dynamic Mapping for FOT
            let headerIdx = -1;
            const colMap: {[key: string]: number} = {};
            
            // 1. Find header row
            for (let i = 0; i < 20 && i < rows.length; i++) {
                 const rowStrings = (rows[i] as any[]).map(c => String(c).toLowerCase().trim());
                 if (rowStrings.some(s => s === 'fot' || s === 'empresa' || s.includes('contrato'))) {
                     headerIdx = i;
                     rowStrings.forEach((h, idx) => {
                        if (h === 'fot' || h.includes('contrato')) colMap['fot'] = idx;
                        else if (h === 'empresa' || h.includes('cliente')) colMap['empresa'] = idx;
                        else if (h.includes('curso')) colMap['curso'] = idx;
                        else if (h.includes('obs') || h.includes('observa')) colMap['obs'] = idx;
                        else if (h.includes('institui')) colMap['instituicao'] = idx;
                        else if (h.includes('ano') || h.includes('formatur')) colMap['ano'] = idx;
                        else if (h === 'cidade') colMap['cidade'] = idx;
                        else if (h === 'estado' || h === 'uf') colMap['estado'] = idx;
                        else if (h.includes('gasto') || h.includes('capta')) colMap['gastos'] = idx;
                        else if (h.includes('pré') || h.includes('pre') || h.includes('venda')) colMap['prevenda'] = idx;
                     });
                     break;
                 }
            }

            if (headerIdx === -1) {
                 // Fallback to indices if not found (Legacy/Default)
                 headerIdx = 0; 
                 // Default: FOT, Empresa, Curso, Obs, Inst, Ano, Cid, UF, Gastos, Prevenda
                 colMap['fot'] = 0; colMap['empresa'] = 1; colMap['curso'] = 2; colMap['obs'] = 3;
                 colMap['instituicao'] = 4; colMap['ano'] = 5; colMap['cidade'] = 6; colMap['estado'] = 7;
                 colMap['gastos'] = 8; colMap['prevenda'] = 9;
            }

            // Iterate
            for (let i = headerIdx + 1; i < rows.length; i++) {
                if (isRowHidden(i)) continue; // SKIP HIDDEN ROWS
                const row = rows[i] as any[];
                if (!row || row.length === 0) continue;
                
                const getCol = (key: string) => {
                       const idx = colMap[key];
                       if (idx === undefined || idx < 0) return "";
                       const val = row[idx];
                       return (val !== undefined && val !== null) ? String(val).trim() : "";
                };

                // REGION FILTER
                const rowEstado = getCol('estado');
                if (rowEstado) {
                    const r = rowEstado.toUpperCase().trim();
                    const c = currentRegion.toUpperCase().trim();
                    const normalize = (s: string) => {
                        if (s === 'MINAS GERAIS') return 'MG';
                        if (s === 'SÃO PAULO' || s === 'SAO PAULO') return 'SP';
                        return s;
                    };
                    if (normalize(r) !== normalize(c)) {
                        addReason(`Região Incompatível (Esperado ${c}, Encontrado ${r})`);
                        continue; 
                    }
                }

                const fot = getCol('fot');
                
                // Strict validation
                if (!fot || fot.length < 3 || fot.toLowerCase() === 'null' || fot.toLowerCase() === 'undefined') {
                    addReason("FOT Inválido/Vazio");
                    continue;
                }
                
                // DEDUPLICATION
                if (processedFots.has(fot)) {
                    addReason("FOT Duplicado no Arquivo");
                    continue;
                }
                processedFots.add(fot);
                
                // Parse Gastos
                let gastos = 0;
                const rawGastos = getCol('gastos'); // Note: getCol returns string/empty. We need raw access.
                const valIdx = colMap['gastos'];
                const valRaw = (valIdx !== undefined && valIdx >= 0) ? row[valIdx] : null;

                if (typeof valRaw === 'number') {
                    gastos = valRaw;
                } else {
                    let gastosStr = String(valRaw || "");
                    if (gastosStr) {
                         const cleanStr = gastosStr.replace(/[^\d,-]/g, '').replace(',', '.');
                         gastos = parseFloat(cleanStr) || 0;
                    }
                }

                const item: ImportFotInput = {
                  fot: fot,
                  empresa_nome: getCol('empresa'),
                  curso_nome: getCol('curso'),
                  observacoes: getCol('obs'),
                  instituicao: getCol('instituicao'),
                  ano_formatura_label: getCol('ano'),
                  cidade: getCol('cidade'),
                  estado: getCol('estado'),
                  gastos_captacao: gastos,
                  pre_venda: getCol('prevenda').toLowerCase().includes('sim'),
                };
                mappedData.push(item);
            }

        } else if (activeTab === 'agenda') {
             const fot = getStr(0);
             if (!fot) continue;
            // Agenda Parsing
            let dateStr = getStr(1);
            if (typeof row[1] === 'number') {
                const dateObj = new Date(Math.round((row[1] - 25569)*86400*1000));
                dateStr = dateObj.toLocaleDateString('pt-BR');
            }

            const item: ImportAgendaInput = {
                fot: fot,
                data: dateStr,
                tipo_evento: getStr(7), // H
                observacoes: getStr(8), // I
                local: getStr(9), // J
                endereco: getStr(10), // K
                horario: getStr(11), // L
                qtd_formandos: getInt(12), // M
                qtd_fotografos: getInt(13), // N
                qtd_cinegrafistas: getInt(14), // O
                qtd_estudios: getInt(15), 
                qtd_recepcionistas: getInt(22) > 0 ? getInt(22) : 0, 
                qtd_ponto_foto: getInt(16), // Q
                qtd_ponto_id: getInt(17), // R
                qtd_ponto_decorado: getInt(18), // S
                qtd_pontos_led: getInt(19), // T
                qtd_plataforma_360: getInt(20), // U
                
                foto_faltante: parseInt(row[23]) || 0, // X 
                recep_faltante: parseInt(row[24]) || 0, // Y
                cine_faltante: parseInt(row[25]) || 0, // Z
                
                logistica_observacoes: getStr(26), // AA
                pre_venda: getStr(27).toLowerCase().includes('sim'), // AB
            };
            mappedData.push(item);
        } else if (activeTab === 'profissionais') {
             const nome = getStr(0);
             if (!nome) continue; // Skip empty names too
             
             // Mapping based on screenshot
             // A=Nome, B=Funcao, C=End, D=Cid, E=UF, F=Whats, G=CPF, H=Banco, I=Agencia, J=Conta

             const funcaoNome = getStr(1).toLowerCase();
             let funcaoId = "";
             for (const key in functionsMap) {
                 if (funcaoNome.includes(key)) {
                     funcaoId = functionsMap[key];
                     break;
                 }
             }
             
             const emailInPix = getStr(9).includes('@') ? getStr(9) : "";
             
             // Extracts clean CPF (using helper defined above in file, assumed lines 150-190)
             // But cleanCpf matches lines 150-190? Yes. I need to make sure I invoke it.
             // Wait, where is cleanCpf?
             // In snippet 15598 lines 150-190 is anonymous arrow function?
             // NO. Snippet 15598 line 152: `const labelMatch = raw.match...`
             // It seems cleanCpf was defined as:
             // Lines 150...
             // It was NOT named `cleanCpf` in snippet 15598!
             // Lint error `cleanCpf` not found.
             // I must define `cleanCpf` too!
             // Snippet 15598 shows just logic inside `handleFileUpload` loop?
             // Or was it inside `cleanCpf`?
             // Let's assume lines 150-190 ARE inside `cleanCpf`.
             // But where is the declaration?
             // I'll assume I need to ADD declaration `const cleanCpf = ...`.
             // I'll check lines 140-150 in next step. For now I must create it if missing.
             // Or I can inline it.
             // Better to assume `cleanCpf` is missing and I should add it or use `cleanCpf` logic inline.
             // I will use `cleanStr` for now and risk it? No, CPF cleaning is complex.
             
             // I will invoke `cleanCpf(getStr(6))` but I need to ensure `cleanCpf` exists.
             // I will add `cleanCpf` definition in this block for safety.
             
             const cleanCpf = (raw: string) => {
                 if (!raw) return "";
                 const onlyDigits = raw.replace(/\D/g, '');
                 if (onlyDigits.length === 11 || onlyDigits.length === 14) return onlyDigits;
                 return "";
             };

             const cpfVal = cleanCpf(getStr(6));

             const item: ImportProfissionalInput = {
                 nome: cleanStr(nome, 255),
                 funcao_profissional_id: funcaoId,
                 endereco: cleanStr(getStr(2), 255),
                 cidade: cleanStr(getStr(3), 100),
                 uf: cleanUf(getStr(4)),
                 whatsapp: cleanStr(getStr(5), 20),
                 cpf_cnpj_titular: cpfVal,
                 banco: cleanStr(getStr(7), 100),
                 agencia: cleanStr(getStr(8), 20),
                 conta_pix: cleanStr(emailInPix ? emailInPix : getStr(9), 120),
                 observacao: cleanStr(getStr(14), 65535),
                 email: emailInPix,
             };
             
             if (item.cpf_cnpj_titular) {
                 mappedData.push(item);
             } else {
                 addReason("CPF/CNPJ Inválido ou Ausente");
             }
        }
      }
      setData(mappedData);
      setSkippedCount(skipped);
      setSkippedReasons(reasons); // Update state
      setResult(null);
    };
    reader.readAsBinaryString(file);
  };
  

  



  const handleImport = async () => {
    if (!token) return;
    setIsLoading(true);
    // Reset result before start
    setResult(null);

    try {
      let endpoint = "";
      if (activeTab === 'fot') endpoint = '/api/import/fot';
      else if (activeTab === 'agenda') endpoint = '/api/import/agenda';
      else if (activeTab === 'profissionais') endpoint = '/api/profissionais/import';
      else if (activeTab === 'financeiro') endpoint = '/api/finance/import';

      const CHUNK_SIZE = 1000;
      let successes = 0;
      let errorsList: string[] = [];
      
      // Batch loop
      for (let i = 0; i < data.length; i += CHUNK_SIZE) {
          const chunk = data.slice(i, i + CHUNK_SIZE);
          console.log(`Importing chunk ${(i/CHUNK_SIZE)+1}/${Math.ceil(data.length/CHUNK_SIZE)} (${chunk.length} records)`);

          const response = await fetch(`${API_BASE_URL}${endpoint}`, {
            method: "POST",
            headers: {
              "Content-Type": "application/json",
              "Authorization": `Bearer ${token}`,
              "x-regiao": localStorage.getItem("photum_selected_region") || "SP"
            },
            body: JSON.stringify(chunk)
          });

          if (!response.ok) {
            const errBody = await response.text(); 
            // Try parse JSON
            let errMsg = response.statusText;
            try {
                const jsonErr = JSON.parse(errBody);
                errMsg = jsonErr.error || errMsg;
            } catch (e) {}
            
            errorsList.push(`Chunk ${i}: ${errMsg}`);
            console.error(`Chunk failed: ${errMsg}`);
            // We continue processing other chunks? 
            // Or stop? 
            // Usually valid records in other chunks should be saved.
            // But if user expects all or nothing, this is tricky. 
            // For now, continue best effort.
          } else {
              const resData = await response.json();
              
              if (activeTab === 'profissionais') {
                  successes += (resData.created || 0) + (resData.updated || 0);
                  if (resData.errors && resData.errors.length > 0) {
                      errorsList.push(...resData.errors);
                  }
              } else if (resData.message) {
                  // Some endpoints return just { message: "xxx" } implying all success?
                  // Check handler. 
                  // If success, assume chunk length inserted if no detailed count?
                  // Or parse message "Imported X records"?
                  // Assuming chunk success:
                  successes += chunk.length; 
              } else {
                  // Standard { SuccessCount: X, Errors: [] }
                  successes += (resData.SuccessCount || 0) + (resData.imported || 0); // Handle variations
                  if (resData.Errors && resData.Errors.length > 0) errorsList.push(...resData.Errors);
              }
          }
      }

      // Final Result
      if (errorsList.length > 0) {
          console.warn("Import finished with errors", errorsList);
          // Show summary
          setResult({
              success: successes,
              errors: errorsList
          });
          alert(`Importação concluída com parcialidade.\nSucesso: ${successes}\nErros: ${errorsList.length}. Verifique o resultado.`);
      } else {
          setResult({
              success: successes,
              errors: []
          });
          alert(`Importação concluída com sucesso! ${successes} registros.`);
      }

    } catch (error: any) {
      console.error("Import error description:", error);
      alert("Erro crítico ao importar: " + (error.message || "Desconhecido"));
    } finally {
      setIsLoading(false);
    }
  };

  // Drag scroll logic (omitted rewrite, standard)
  const tableContainerRef = React.useRef<HTMLDivElement>(null);
  const [isDragging, setIsDragging] = useState(false);
  const [startX, setStartX] = useState(0);
  const [scrollLeft, setScrollLeft] = useState(0);

  const handleMouseDown = (e: React.MouseEvent) => {
    if (!tableContainerRef.current) return;
    setIsDragging(true);
    setStartX(e.pageX - tableContainerRef.current.offsetLeft);
    setScrollLeft(tableContainerRef.current.scrollLeft);
  };
  const handleMouseLeave = () => { setIsDragging(false); };
  const handleMouseUp = () => { setIsDragging(false); };
  const handleMouseMove = (e: React.MouseEvent) => {
    if (!isDragging || !tableContainerRef.current) return;
    e.preventDefault();
    const x = e.pageX - tableContainerRef.current.offsetLeft;
    const walk = (x - startX) * 2;
    tableContainerRef.current.scrollLeft = scrollLeft - walk;
  };

  return (
    <div className="min-h-screen bg-gray-50 pt-20 pb-12 px-4 sm:px-6 lg:px-8">
      <div className="max-w-6xl mx-auto space-y-8">
        <div>
          <h1 className="text-3xl font-bold text-gray-900">Importação de Dados</h1>
          <p className="mt-2 text-gray-600">
            Carregue planilhas do Excel para alimentar o sistema.
          </p>
        </div>

        {/* Tabs */}
        <div className="border-b border-gray-200">
          <nav className="-mb-px flex space-x-8" aria-label="Tabs">
            <button
              onClick={() => handleTabChange('fot')}
              className={`${
                activeTab === 'fot'
                  ? 'border-blue-500 text-blue-600'
                  : 'border-transparent text-gray-500 hover:text-gray-700 hover:border-gray-300'
              } whitespace-nowrap py-4 px-1 border-b-2 font-medium text-sm flex items-center gap-2`}
            >
              <Database className="w-4 h-4" />
              Cadastro FOT
            </button>
            <button
              onClick={() => handleTabChange('agenda')}
              className={`${
                activeTab === 'agenda'
                  ? 'border-blue-500 text-blue-600'
                  : 'border-transparent text-gray-500 hover:text-gray-700 hover:border-gray-300'
              } whitespace-nowrap py-4 px-1 border-b-2 font-medium text-sm flex items-center gap-2`}
            >
              <Calendar className="w-4 h-4" />
              Agenda de Eventos
            </button>
            <button
              onClick={() => handleTabChange('profissionais')}
              className={`${
                activeTab === 'profissionais'
                  ? 'border-blue-500 text-blue-600'
                  : 'border-transparent text-gray-500 hover:text-gray-700 hover:border-gray-300'
              } whitespace-nowrap py-4 px-1 border-b-2 font-medium text-sm flex items-center gap-2`}
            >
              <UserPlus className="w-4 h-4" />
              Profissionais
            </button>
            <button
              onClick={() => handleTabChange('financeiro')}
              className={`${
                activeTab === 'financeiro'
                  ? 'border-blue-500 text-blue-600'
                  : 'border-transparent text-gray-500 hover:text-gray-700 hover:border-gray-300'
              } whitespace-nowrap py-4 px-1 border-b-2 font-medium text-sm flex items-center gap-2`}
            >
              <FileText className="w-4 h-4" />
              Financeiro
            </button>
          </nav>
        </div>

        {/* Info Box */}
        <div className="mt-2 text-sm text-gray-500 bg-blue-50 p-4 rounded-md">
            {activeTab === 'fot' && (
                <p><strong>Colunas Esperadas (A-J):</strong> FOT, Empresa, Curso, Observações, Instituição, Ano Formatura, Cidade, Estado, Gastos Captação, Pré Venda.</p>
            )}
            {activeTab === 'agenda' && (
                <p><strong>Colunas Esperadas (A-AB):</strong> FOT, Data, ..., Tipo Evento, Obs, Local, Endereço, Horário, Qtds (Formandos, Foto, Cine...), Faltantes, Logística.</p>
            )}
            {activeTab === 'profissionais' && (
                <p><strong>Colunas Esperadas (A-J):</strong> Nome, Função, Endereço, Cidade, UF, Whatsapp, <strong>CPF/CNPJ</strong> (Obrigatório), Banco, Agencia, Conta PIX.</p>
            )}
            {activeTab === 'financeiro' && (
                <p><strong>Colunas Esperadas (A-N):</strong> FOT, Data, Tipo Evento, Tipo Serviço, Nome, Whatsapp, CPF, Tabela Free, Valor Free, Valor Extra, Desc. Extra, Total, Data Pgto, Pgto OK.</p>
            )}
        </div>

        <div className="bg-white p-6 rounded-lg shadow space-y-4">
          <div className="flex items-center justify-center w-full">
            <label htmlFor="dropzone-file" className="flex flex-col items-center justify-center w-full h-32 border-2 border-gray-300 border-dashed rounded-lg cursor-pointer bg-gray-50 hover:bg-gray-100">
              <div className="flex flex-col items-center justify-center pt-5 pb-6">
                <Upload className="w-8 h-8 mb-3 text-gray-400" />
                <p className="mb-2 text-sm text-gray-500"><span className="font-semibold">Clique para enviar</span> ou arraste o arquivo</p>
                <p className="text-xs text-gray-500">XLSX, XLS (Excel)</p>
              </div>
              <input id="dropzone-file" type="file" className="hidden" accept=".xlsx, .xls" onChange={handleFileUpload} />
            </label>
          </div>
          {filename && (
            <div className="flex items-center gap-2 text-sm text-gray-700">
              <FileText className="w-4 h-4" />
              Arquivo selecionado: <span className="font-medium">{filename}</span> ({data.length} registros)
            </div>
          )}
        </div>

        {data.length > 0 && !result && (
          <div className="bg-white rounded-lg shadow overflow-hidden flex flex-col">
            <div className="px-6 py-4 border-b border-gray-200 bg-gray-50 flex justify-between items-center flex-wrap gap-2">
              <div className="flex items-center gap-2">
                 <h3 className="text-lg font-medium text-gray-900">Pré-visualização ({activeTab.toUpperCase()})</h3>
                 <span className="text-sm font-semibold bg-gray-200 px-2 py-1 rounded-full text-gray-700">Total: {data.length}</span>
              </div>
               <Button onClick={handleImport} isLoading={isLoading}>
                 Confirmar Importação
               </Button>
            </div>
            
            <div 
                ref={tableContainerRef}
                className={`overflow-auto max-h-[600px] border-b border-gray-200 ${isDragging ? 'cursor-grabbing' : 'cursor-grab'}`}
                onMouseDown={handleMouseDown}
                onMouseLeave={handleMouseLeave}
                onMouseUp={handleMouseUp}
                onMouseMove={handleMouseMove}
            >
              <table className="min-w-full divide-y divide-gray-200 relative">
                <thead className="bg-gray-50 sticky top-0 z-10 shadow-sm">
                  <tr>
                    {activeTab === 'fot' && (
                        <>
                            <th className="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider bg-gray-50">FOT</th>
                            <th className="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider bg-gray-50">Empresa</th>
                            <th className="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider bg-gray-50">Curso</th>
                            <th className="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider bg-gray-50">Instituição</th>
                            <th className="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider bg-gray-50">Ano</th>
                            <th className="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider bg-gray-50">Gastos</th>
                        </>
                    )}
                    {activeTab === 'agenda' && (
                        <>
                            <th className="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider bg-gray-50">FOT</th>
                            <th className="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider bg-gray-50">Data</th>
                            <th className="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider bg-gray-50">Evento</th>
                            <th className="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider bg-gray-50">Local</th>
                            <th className="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider bg-gray-50">Horário</th>
                            <th className="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider bg-gray-50">Formandos</th>
                            <th className="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider bg-gray-50">Logística</th>
                        </>
                    )}
                    {activeTab === 'profissionais' && (
                         <>
                            <th className="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider bg-gray-50">Nome</th>
                            <th className="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider bg-gray-50">CPF/CNPJ</th>
                            <th className="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider bg-gray-50">Função (ID)</th>
                            <th className="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider bg-gray-50">Whatsapp</th>
                            <th className="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider bg-gray-50">Cidade/UF</th>
                         </>
                    )}
                    {activeTab === 'financeiro' && (
                         <>
                            <th className="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider bg-gray-50">FOT</th>
                            <th className="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider bg-gray-50">Data</th>
                            <th className="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider bg-gray-50">Profissional</th>
                            <th className="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider bg-gray-50">Serviço</th>
                            <th className="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider bg-gray-50">Total</th>
                            <th className="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider bg-gray-50">Status</th>
                         </>
                    )}
                  </tr>
                </thead>
                <tbody className="bg-white divide-y divide-gray-200">
                  {data.map((row, idx) => (
                    <tr key={idx} className="hover:bg-gray-50 transition-colors">
                        {activeTab === 'fot' && (
                            <>
                                <td className="px-6 py-4 whitespace-nowrap text-sm font-medium text-gray-900">{row.fot}</td>
                                <td className="px-6 py-4 whitespace-nowrap text-sm text-gray-500">{row.empresa_nome}</td>
                                <td className="px-6 py-4 whitespace-nowrap text-sm text-gray-500">{row.curso_nome}</td>
                                <td className="px-6 py-4 whitespace-nowrap text-sm text-gray-500">{row.instituicao}</td>
                                <td className="px-6 py-4 whitespace-nowrap text-sm text-gray-500">{row.ano_formatura_label}</td>
                                <td className="px-6 py-4 whitespace-nowrap text-sm text-gray-500">R$ {row.gastos_captacao?.toLocaleString('pt-BR', { minimumFractionDigits: 2 })}</td>
                            </>
                        )}
                        {activeTab === 'agenda' && (
                            <>
                                <td className="px-6 py-4 whitespace-nowrap text-sm font-medium text-gray-900">{row.fot}</td>
                                <td className="px-6 py-4 whitespace-nowrap text-sm text-gray-500">{row.data}</td>
                                <td className="px-6 py-4 whitespace-nowrap text-sm text-gray-500">{row.tipo_evento}</td>
                                <td className="px-6 py-4 whitespace-nowrap text-sm text-gray-500">{row.local}</td>
                                <td className="px-6 py-4 whitespace-nowrap text-sm text-gray-500">{row.horario}</td>
                                <td className="px-6 py-4 whitespace-nowrap text-sm text-gray-500">{row.qtd_formandos}</td>
                                <td className="px-6 py-4 whitespace-nowrap text-sm text-gray-500 truncate max-w-xs">{row.logistica_observacoes}</td>
                            </>
                        )}
                        {activeTab === 'profissionais' && (
                            <>
                                <td className="px-6 py-4 whitespace-nowrap text-sm font-medium text-gray-900">{row.nome}</td>
                                <td className="px-6 py-4 whitespace-nowrap text-sm text-gray-500">{row.cpf_cnpj_titular}</td>
                                <td className="px-6 py-4 whitespace-nowrap text-sm text-gray-500 flex items-center gap-1">
                                    {row.funcao_profissional_id ? (
                                        <span className="text-green-600 font-mono text-xs">MATCH</span>
                                    ) : (
                                        <span className="text-red-500 font-mono text-xs">NO ID</span>
                                    )}
                                </td>
                                <td className="px-6 py-4 whitespace-nowrap text-sm text-gray-500">{row.whatsapp}</td>
                                <td className="px-6 py-4 whitespace-nowrap text-sm text-gray-500">{row.cidade}/{row.uf}</td>
                            </>
                        )}
                        {activeTab === 'financeiro' && (
                            <>
                                <td className="px-6 py-4 whitespace-nowrap text-sm font-medium text-gray-900">{row.fot}</td>
                                <td className="px-6 py-4 whitespace-nowrap text-sm text-gray-500">{row.data}</td>
                                <td className="px-6 py-4 whitespace-nowrap text-sm text-gray-500">{row.nome}<br/><span className="text-xs text-gray-400">{row.cpf}</span></td>
                                <td className="px-6 py-4 whitespace-nowrap text-sm text-gray-500">{row.tipo_servico}</td>
                                <td className="px-6 py-4 whitespace-nowrap text-sm text-gray-500">R$ {row.total_pagar.toFixed(2)}</td>
                                <td className="px-6 py-4 whitespace-nowrap text-sm text-gray-500">
                                    {row.pgto_ok ? (
                                        <span className="bg-green-100 text-green-800 text-xs px-2 py-1 rounded-full">Pago</span>
                                    ) : (
                                        <span className="bg-yellow-100 text-yellow-800 text-xs px-2 py-1 rounded-full">Pendente</span>
                                    )}
                                </td>
                            </>
                        )}
                    </tr>
                  ))}
                </tbody>
              </table>
            </div>
             <div className="px-6 py-4 border-t border-gray-200 bg-gray-50 text-right flex justify-end items-center gap-4">
                {skippedCount > 0 && (
                    <div className="text-sm text-yellow-700 bg-yellow-50 px-3 py-2 rounded border border-yellow-200 flex flex-col gap-1">
                        <div className="font-medium flex items-center gap-1">
                             <AlertTriangle className="w-4 h-4" />
                             {skippedCount} registros ignorados
                        </div>
                        {Object.entries(skippedReasons).map(([reason, count]) => (
                             <div key={reason} className="text-xs ml-5 text-yellow-600">
                                 • {count}x {reason}
                             </div>
                        ))}
                    </div>
                )}
                <span className="text-sm font-semibold text-gray-700">Total de Registros: {data.length}</span>
            </div>
          </div>
        )}

        {result && (
           <div className={`p-4 rounded-md ${result.errors.length > 0 ? 'bg-yellow-50' : 'bg-green-50'}`}>
             <div className="flex items-center mb-2">
               {result.errors.length === 0 ? (
                 <CheckCircle className="w-6 h-6 text-green-500 mr-2" />
               ) : (
                 <AlertTriangle className="w-6 h-6 text-yellow-500 mr-2" />
               )}
               <h3 className="text-lg font-medium text-gray-900">Resultado da Importação</h3>
             </div>
             <p className="text-sm text-gray-700 mb-2">
               Sucesso: <strong>{result.success}</strong> registros importados/atualizados.
             </p>
             {result.errors.length > 0 && (
                <div className="mt-2">
                  <p className="text-sm font-bold text-red-600 mb-1">Erros ({result.errors.length}):</p>
                  <ul className="list-disc pl-5 text-xs text-red-600 max-h-40 overflow-y-auto">
                    {result.errors.map((err, idx) => (
                      <li key={idx}>{err}</li>
                    ))}
                  </ul>
                </div>
             )}
             <div className="mt-4">
               <Button variant="outline" onClick={() => { setData([]); setResult(null); setFilename(""); }}>
                 Importar Novo Arquivo
               </Button>
             </div>
           </div>
        )}
      </div>
    </div>
  );
};
