import { useState, useEffect, useMemo, useCallback } from 'react';
import { workspaceReceitasService } from '@/services/workspaceReceitasService';
import { toast } from 'sonner';

/**
 * Formata data para mês (YYYY-MM)
 * @param {Date} date
 * @returns {string}
 */
const formatMonth = (date) => {
  const year = date.getFullYear();
  const month = String(date.getMonth() + 1).padStart(2, '0');
  return `${year}-${month}`;
};

/**
 * Extrai mês de uma data string (YYYY-MM-DD ou similar)
 * @param {string} dateStr
 * @returns {string}
 */
const extractMonth = (dateStr) => {
  if (!dateStr) return '';
  const date = new Date(dateStr);
  if (isNaN(date.getTime())) return '';
  return formatMonth(date);
};

/**
 * Hook para gerenciar a lógica de Receitas do Workspace
 * Integra com workspaceReceitasService e gerencia estado de boletos, clientes e serviços
 * Implementa lógica de cruzamento entre boletos e extrato (baseado na lógica antiga)
 */
export const useWorkspaceReceitas = () => {
  const [activeTab, setActiveTab] = useState('boletos');
  
  // Estados de dados brutos
  const [boletosRaw, setBoletosRaw] = useState([]);
  const [extratoRaw, setExtratoRaw] = useState([]);
  const [clientes, setClientes] = useState([]);
  const [servicos, setServicos] = useState([]);
  
  // Estados de loading e erro
  const [isLoadingBoletos, setIsLoadingBoletos] = useState(false);
  const [isLoadingClientes, setIsLoadingClientes] = useState(false);
  const [isLoadingServicos, setIsLoadingServicos] = useState(false);
  const [error, setError] = useState(null);
  
  // Filtros e busca
  const [searchTerm, setSearchTerm] = useState('');
  const [filterMonth, setFilterMonth] = useState(() => {
    const now = new Date();
    return formatMonth(now);
  });
  
  // Estado de filtro por status (para mostrar tabela detalhada)
  const [selectedStatus, setSelectedStatus] = useState(null);

  /**
   * Carrega boletos e extrato (para cruzamento)
   */
  const loadBoletos = useCallback(async () => {
    setIsLoadingBoletos(true);
    setError(null);
    
    try {
      // Busca boletos
      const boletosData = await workspaceReceitasService.fetchBoletos();
      const cobrancas = boletosData?.Boletos_GET?.cobrancas || [];
      setBoletosRaw(cobrancas);
      
      // Busca extrato para cruzamento
      try {
        const extratoData = await workspaceReceitasService.fetchExtrato();
        setExtratoRaw(Array.isArray(extratoData) ? extratoData : []);
      } catch (extratoErr) {
        console.warn('Erro ao carregar extrato (não crítico):', extratoErr);
        setExtratoRaw([]);
      }
    } catch (err) {
      console.error('Erro ao carregar boletos:', err);
      setError(err.message || 'Erro ao carregar boletos');
      toast.error('Erro ao carregar boletos');
      setBoletosRaw([]);
      setExtratoRaw([]);
    } finally {
      setIsLoadingBoletos(false);
    }
  }, []);

  /**
   * Carrega clientes
   */
  const loadClientes = async () => {
    setIsLoadingClientes(true);
    setError(null);
    
    try {
      const data = await workspaceReceitasService.fetchClientes();
      setClientes(Array.isArray(data) ? data : []);
    } catch (err) {
      console.error('Erro ao carregar clientes:', err);
      setError(err.message || 'Erro ao carregar clientes');
      toast.error('Erro ao carregar clientes');
      setClientes([]);
    } finally {
      setIsLoadingClientes(false);
    }
  };

  /**
   * Carrega serviços
   */
  const loadServicos = async () => {
    setIsLoadingServicos(true);
    setError(null);
    
    try {
      const data = await workspaceReceitasService.fetchServicos();
      setServicos(Array.isArray(data) ? data : []);
    } catch (err) {
      console.error('Erro ao carregar serviços:', err);
      setError(err.message || 'Erro ao carregar serviços');
      toast.error('Erro ao carregar serviços');
      setServicos([]);
    } finally {
      setIsLoadingServicos(false);
    }
  };

  /**
   * Carrega dados quando tab muda ou mês muda
   */
  useEffect(() => {
    if (activeTab === 'boletos') {
      loadBoletos();
    } else if (activeTab === 'clientes') {
      loadClientes();
    } else if (activeTab === 'servicos') {
      loadServicos();
    }
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [activeTab, filterMonth, loadBoletos]);

  /**
   * Processa e cruza dados de boletos com extrato
   * Baseado na lógica antiga: Construir_Interface
   */
  const processedData = useMemo(() => {
    if (!boletosRaw.length && !extratoRaw.length) {
      return {
        boletosFiltrados: [],
        pixRecebidos: [],
        statusGroups: {},
        totalByStatus: {}
      };
    }

    const filterDate = new Date(`${filterMonth}-01T00:00:00`);
    const filterMonthStr = formatMonth(filterDate);

    // Filtra boletos por mês
    const boletosFiltrados = boletosRaw.filter(item => {
      const cobranca = item.cobranca || item;
      const dataVencimento = cobranca.dataVencimento;
      if (!dataVencimento) return false;
      const itemMonth = extractMonth(dataVencimento);
      return itemMonth === filterMonthStr;
    });

    // Filtra extrato por mês e tipoOperacao === "C" (Crédito)
    const extratoFiltrado = extratoRaw.filter(item => {
      const itemMonth = extractMonth(item.dataEntrada);
      const isCredit = item.tipoOperacao === 'C';
      return itemMonth === filterMonthStr && isCredit;
    });

    // Lógica de cruzamento: encontra PIX recebidos que não têm boleto correspondente
    // Baseado na lógica antiga: list_Constructor.filtro_entradas
    const listNot = ['CANCELADO', 'A_RECEBER', 'ATRASADO'];
    const filtroEntradas = {};

    for (const extratoItem of extratoFiltrado) {
      const valorExtrato = Number(extratoItem.valor?.toString().replace(',', '.')) || 0;

      for (const boletoItem of boletosFiltrados) {
        const cobranca = boletoItem.cobranca || boletoItem;
        const situacao = cobranca.situacao;

        // Ignora boletos cancelados, a receber ou atrasados
        if (listNot.includes(situacao)) continue;

        const valorBoleto = Number(cobranca.valorTotalRecebido || cobranca.valorNominal || 0);

        // Se os valores não batem, adiciona ao filtro de entradas extras
        if (valorExtrato !== valorBoleto) {
          if (!filtroEntradas[extratoItem.idextrato]) {
            filtroEntradas[extratoItem.idextrato] = [];
          }
          filtroEntradas[extratoItem.idextrato].push({ ...extratoItem });
        } else {
          // Se os valores batem, remove da lista de entradas extras
          if (filtroEntradas[extratoItem.idextrato]) {
            filtroEntradas[extratoItem.idextrato] = filtroEntradas[extratoItem.idextrato].filter(
              item => Number(item.valor?.toString().replace(',', '.')) !== valorBoleto
            );
          }
        }
      }
    }

    // Converte objeto de entradas extras para array
    const pixRecebidos = Object.values(filtroEntradas)
      .flat()
      .filter((item, index, self) => 
        index === self.findIndex(t => t.idextrato === item.idextrato)
      );

    // Agrupa por status
    const statusGroups = {};
    const totalByStatus = {};

    // Processa boletos
    for (const item of boletosFiltrados) {
      const cobranca = item.cobranca || item;
      const situacao = cobranca.situacao;
      const origemRecebimento = cobranca.origemRecebimento || 'BOLETO';
      const valor = Number(cobranca.valorTotalRecebido || cobranca.valorNominal || 0);

      const key = `${situacao}_${origemRecebimento}`;
      
      if (!statusGroups[key]) {
        statusGroups[key] = {
          status: situacao,
          origemRecebimento,
          items: [],
          quantidade: 0,
          total: 0
        };
      }

      statusGroups[key].items.push(cobranca);
      statusGroups[key].quantidade++;
      statusGroups[key].total += valor;
    }

    // Processa PIX recebidos (entradas extras)
    if (pixRecebidos.length > 0) {
      const pixKey = 'PIX';
      if (!statusGroups[pixKey]) {
        statusGroups[pixKey] = {
          status: 'RECEBIDO',
          origemRecebimento: 'PIX',
          items: [],
          quantidade: 0,
          total: 0
        };
      }

      for (const pixItem of pixRecebidos) {
        const valor = Number(pixItem.valor?.toString().replace(',', '.')) || 0;
        statusGroups[pixKey].items.push({
          pagador: { nome: pixItem.descricao || 'PIX Recebido' },
          dataEmissao: '',
          dataVencimento: pixItem.dataEntrada,
          tipoCobranca: pixItem.titulo || 'PIX',
          Valor_Nominal: '----',
          valorTotalRecebido: valor,
          origemRecebimento: 'PIX',
          situacao: 'RECEBIDO'
        });
        statusGroups[pixKey].quantidade++;
        statusGroups[pixKey].total += valor;
      }
    }

    // Calcula totais por status
    for (const key in statusGroups) {
      const group = statusGroups[key];
      totalByStatus[group.status] = {
        quantidade: (totalByStatus[group.status]?.quantidade || 0) + group.quantidade,
        total: (totalByStatus[group.status]?.total || 0) + group.total,
        origemRecebimento: group.origemRecebimento
      };
    }

    return {
      boletosFiltrados,
      pixRecebidos,
      statusGroups,
      totalByStatus
    };
  }, [boletosRaw, extratoRaw, filterMonth]);

  /**
   * Boletos filtrados por busca e status selecionado
   */
  const boletosFiltrados = useMemo(() => {
    let items = [];

    if (selectedStatus === 'PIX') {
      items = processedData.pixRecebidos.map(item => ({
        id: item.idextrato || '',
        cliente: item.descricao || 'PIX Recebido',
        vencimento: item.dataEntrada || '',
        valor: Number(item.valor?.toString().replace(',', '.')) || 0,
        status: 'RECEBIDO',
        dataEmissao: '',
        origemRecebimento: 'PIX',
        tipoCobranca: item.titulo || 'PIX'
      }));
    } else if (selectedStatus) {
      const group = Object.values(processedData.statusGroups).find(
        g => g.status === selectedStatus
      );
      if (group) {
        items = group.items.map(item => ({
          id: item.codigoSolicitacao || '',
          cliente: item.pagador?.nome || '',
          vencimento: item.dataVencimento || '',
          valor: Number(item.valorNominal || 0),
          status: item.situacao || '',
          dataEmissao: item.dataEmissao || '',
          valorTotalRecebido: item.valorTotalRecebido || null,
          origemRecebimento: item.origemRecebimento || 'BOLETO',
          tipoCobranca: item.tipoCobranca || '',
          codigoSolicitacao: item.codigoSolicitacao || '',
          seuNumero: item.seuNumero || '',
          dataSituacao: item.dataSituacao || ''
        }));
      }
    } else {
      // Se não há status selecionado, mostra todos os boletos filtrados
      items = processedData.boletosFiltrados.map(item => {
        const cobranca = item.cobranca || item;
        return {
          id: cobranca.codigoSolicitacao || '',
          cliente: cobranca.pagador?.nome || '',
          vencimento: cobranca.dataVencimento || '',
          valor: Number(cobranca.valorNominal || 0),
          status: cobranca.situacao || '',
          dataEmissao: cobranca.dataEmissao || '',
          valorTotalRecebido: cobranca.valorTotalRecebido || null,
          origemRecebimento: cobranca.origemRecebimento || 'BOLETO',
          tipoCobranca: cobranca.tipoCobranca || '',
          codigoSolicitacao: cobranca.codigoSolicitacao || '',
          seuNumero: cobranca.seuNumero || '',
          dataSituacao: cobranca.dataSituacao || ''
        };
      });
    }

    // Aplica busca por termo
    if (searchTerm) {
      const term = searchTerm.toLowerCase();
      items = items.filter(b => 
        b.cliente?.toLowerCase().includes(term) ||
        b.id?.toString().includes(term) ||
        b.status?.toLowerCase().includes(term) ||
        b.codigoSolicitacao?.toLowerCase().includes(term)
      );
    }

    return items;
  }, [processedData, selectedStatus, searchTerm]);

  /**
   * Clientes filtrados por busca
   */
  const clientesFiltrados = useMemo(() => {
    if (!searchTerm) return clientes;
    
    const term = searchTerm.toLowerCase();
    return clientes.filter(c => 
      c.nome?.toLowerCase().includes(term) ||
      c.cnpj?.includes(term) ||
      c.id?.toString().includes(term)
    );
  }, [clientes, searchTerm]);

  /**
   * Serviços filtrados por busca
   */
  const servicosFiltrados = useMemo(() => {
    if (!searchTerm) return servicos;
    
    const term = searchTerm.toLowerCase();
    return servicos.filter(s => 
      s.descricao?.toLowerCase().includes(term) ||
      s.categoria?.toLowerCase().includes(term) ||
      s.id?.toString().includes(term)
    );
  }, [servicos, searchTerm]);

  /**
   * KPIs calculados baseados nos dados processados
   */
  const kpis = useMemo(() => {
    const { totalByStatus } = processedData;
    
    const totalAReceber = totalByStatus['A_RECEBER']?.total || 0;
    const totalEmAtraso = totalByStatus['ATRASADO']?.total || 0;
    const totalRecebido = (totalByStatus['RECEBIDO']?.total || 0) + (processedData.pixRecebidos.reduce((acc, p) => acc + (Number(p.valor?.toString().replace(',', '.')) || 0), 0));
    const totalFaturado = clientes.reduce((acc, c) => acc + (c.total_faturado || 0), 0);

    return {
      aReceber: totalAReceber,
      emAtraso: totalEmAtraso,
      recebido: totalRecebido,
      totalFaturado
    };
  }, [processedData, clientes]);

  /**
   * Dados ativos baseado na tab
   */
  const activeData = useMemo(() => {
    if (activeTab === 'boletos') return boletosFiltrados;
    if (activeTab === 'clientes') return clientesFiltrados;
    if (activeTab === 'servicos') return servicosFiltrados;
    return [];
  }, [activeTab, boletosFiltrados, clientesFiltrados, servicosFiltrados]);

  /**
   * Loading ativo baseado na tab
   */
  const isLoading = useMemo(() => {
    if (activeTab === 'boletos') return isLoadingBoletos;
    if (activeTab === 'clientes') return isLoadingClientes;
    if (activeTab === 'servicos') return isLoadingServicos;
    return false;
  }, [activeTab, isLoadingBoletos, isLoadingClientes, isLoadingServicos]);

  /**
   * Extrato filtrado por tipoOperacao === "C" (Crédito) para receitas
   */
  const extratoReceitas = useMemo(() => {
    const filterDate = new Date(`${filterMonth}-01T00:00:00`);
    const filterMonthStr = formatMonth(filterDate);
    
    return extratoRaw.filter(item => {
      const itemMonth = extractMonth(item.dataEntrada);
      const isCredit = item.tipoOperacao === 'C';
      return itemMonth === filterMonthStr && isCredit;
    });
  }, [extratoRaw, filterMonth]);

  return {
    state: {
      activeTab,
      boletos: boletosFiltrados,
      clientes: clientesFiltrados,
      servicos: servicosFiltrados,
      activeData,
      kpis,
      isLoading,
      error,
      searchTerm,
      filterMonth,
      selectedStatus,
      statusGroups: processedData.statusGroups,
      totalByStatus: processedData.totalByStatus,
      extratoReceitas
    },
    actions: {
      setActiveTab,
      setSearchTerm,
      setFilterMonth,
      setSelectedStatus,
      loadBoletos,
      loadClientes,
      loadServicos
    }
  };
};
