import { useState, useMemo, useEffect, useCallback, useRef } from 'react';
import { useToast } from './useToast';
import { extratoService } from '@/services/extratoService';
import { parseCurrency } from '@/utils/dateUtils';
import { workspaceDespesasV2Service } from '@/services/workspaceDespesasV2Service';
import { fornecedoresService } from '@/services/fornecedoresService';

/**
 * Hook para gerenciar a lógica de Contas a Pagar com segurança.
 */
export const useContasPagar = () => {
    const toast = useToast();
    const [transactions, setTransactions] = useState([]);
    const [isLoading, setIsLoading] = useState(false);
    const [activeTab, setActiveTab] = useState('registros');
    const [activeSubView, setActiveSubView] = useState('default'); // 'default' | 'fornecedores' | 'despesas' | 'cruzamento'
    const [searchTerm, setSearchTerm] = useState('');
    const [selectedIds, setSelectedIds] = useState([]);

    // Filtros de busca (Mês/Ano)
    const [filtroMes, setFiltroMes] = useState(String(new Date().getMonth() + 1));
    const [filtroAno, setFiltroAno] = useState(String(new Date().getFullYear()));
    const [filtroTipoPeriodo, setFiltroTipoPeriodo] = useState('mes'); // 'mes' | 'ano' | 'todos'
    const [filtroTipoCobranca, setFiltroTipoCobranca] = useState('todas'); // 'todas' | 'Recorrente' | 'Avulsa'
    
    // Estados para Fornecedores
    const [fornecedores, setFornecedores] = useState([]);
    const [fornecedoresLoading, setFornecedoresLoading] = useState(false);
    const [selectedFornecedor, setSelectedFornecedor] = useState(null);
    
    // Estados para Despesas V2
    const [despesas, setDespesas] = useState([]);
    const [despesasLoading, setDespesasLoading] = useState(false);
    const [selectedDespesa, setSelectedDespesa] = useState(null);
    const [itensDespesaLoading, setItensDespesaLoading] = useState(false);
    const [totalItensDespesa, setTotalItensDespesa] = useState({ debito: 0, credito: 0 });
    
    // Estados para Cruzamento
    const [despesasPlanejadas, setDespesasPlanejadas] = useState([]);
    const [despesasExecutadas, setDespesasExecutadas] = useState([]);
    const [cruzamentoLoading, setCruzamentoLoading] = useState(true);
    const [categorias, setCategorias] = useState([]);
    const [caixinhas, setCaixinhas] = useState([]);

    // Ref para evitar loops com toast
    const toastRef = useRef(toast);
    useEffect(() => {
        toastRef.current = toast;
    }, [toast]);

    // Carregar fornecedores reais
    const fetchFornecedores = useCallback(async () => {
        setFornecedoresLoading(true);
        try {
            const data = await fornecedoresService.fetchFornecedores();
            setFornecedores(data || []);
        } catch (error) {
            console.error('[useContasPagar] Erro ao buscar fornecedores:', error);
        } finally {
            setFornecedoresLoading(false);
        }
    }, []);

    // Carregar Despesas V2 - Estabilizado
    const fetchDespesas = useCallback(async () => {
        setDespesasLoading(true);
        try {
            const filters = {};
            if (filtroTipoPeriodo === 'mes') {
                filters.mes = filtroMes;
                filters.ano = filtroAno;
            } else if (filtroTipoPeriodo === 'ano') {
                filters.ano = filtroAno;
            }

            if (filtroTipoCobranca !== 'todas') {
                filters.tipo_cobranca = filtroTipoCobranca;
            }

            const data = await workspaceDespesasV2Service.fetchDespesas(filters);
            const list = data || [];
            setDespesas(list);
            
            // Alimenta o cruzamento com os dados planejados
            setDespesasPlanejadas(list.map(item => ({
                id: item.idDespesa || item.id,
                data: item.data,
                valor: Number(item.montante || 0),
                categoria: item.categoria,
                descricao: item.descricao,
                status: item.status
            })));
        } catch (error) {
            console.error('[useContasPagar] Erro ao buscar despesas:', error);
            // Evita toast de erro se for apenas inicialização silenciosa
            if (activeSubView === 'despesas') {
                toastRef.current.error('Erro ao carregar despesas');
            }
        } finally {
            setDespesasLoading(false);
        }
    }, [activeSubView, filtroMes, filtroAno, filtroTipoPeriodo, filtroTipoCobranca]);

    // Dispara a busca quando a sub-view muda ou na montagem
    useEffect(() => {
        if (activeSubView === 'despesas' || activeSubView === 'default') {
            fetchDespesas();
        }
        // Carrega fornecedores se estiver em contextos relevantes
        if (activeSubView === 'despesas' || activeSubView === 'fornecedores') {
            fetchFornecedores();
        }
    }, [activeSubView, fetchDespesas, fetchFornecedores]);

    // Carga inicial silenciada para garantir dados prontos na montagem do hook
    useEffect(() => {
        fetchFornecedores();
        // Também tenta um fetch inicial de despesas se já estivermos no contexto correto (ou no padrão)
        if (activeSubView === 'despesas' || activeSubView === 'default') {
            fetchDespesas();
        }
    }, []);
    // Carregar itens do diário quando uma despesa é selecionada
    const lastSelectedId = useRef(null);
 
    const fetchTotalDiario = useCallback(async (idDespesa) => {
        try {
            const res = await workspaceDespesasV2Service.fetchTotalItensDespesa(idDespesa);
            const data = res?.data || res;
            setTotalItensDespesa({
                debito: Number(data?.total_debito || 0),
                credito: Number(data?.total_credito || 0)
            });
        } catch (err) {
            console.error('[useContasPagar] Erro ao buscar total de itens:', err);
        }
    }, []);

    useEffect(() => {
        const id = selectedDespesa?.idDespesa;
        if (id && id !== lastSelectedId.current) {
            lastSelectedId.current = id;
            setItensDespesaLoading(true);
            
            Promise.all([
                workspaceDespesasV2Service.fetchItensDespesa(id),
                workspaceDespesasV2Service.fetchTotalItensDespesa(id)
            ]).then(([itens, resTotal]) => {
                const dataTotal = resTotal?.data || resTotal;
                setSelectedDespesa(prev => (prev && prev.idDespesa === id) 
                    ? { ...prev, diario: itens } 
                    : prev
                );
                setTotalItensDespesa({
                    debito: Number(dataTotal?.total_debito || 0),
                    credito: Number(dataTotal?.total_credito || 0)
                });
            }).catch(err => {
                console.error('[useContasPagar] Erro ao buscar dados do diário:', err);
            }).finally(() => {
                setItensDespesaLoading(false);
            });
        } else if (!id) {
            lastSelectedId.current = null;
        }
    }, [selectedDespesa?.idDespesa]);

    useEffect(() => {
        let cancelled = false;
        setCruzamentoLoading(true);
        extratoService
            .fetchExtrato()
            .then((raw) => {
                if (cancelled) return;
                const list = Array.isArray(raw) ? raw : [];
                const saidas = list
                    .filter((item) => item.tipoOperacao === 'D')
                    .map((item) => ({
                        id: item.idextrato ?? item.id,
                        idextrato: item.idextrato,
                        data: item.dataEntrada || '',
                        dataEntrada: item.dataEntrada || '',
                        descricao: item.descricao || item.titulo || '',
                        valor: Math.abs(parseCurrency(item.valor || 0)),
                        categoria: item.categoria ?? 'Sem Categoria',
                        caixinha: item.caixinha ?? '',
                        status: 'EXECUTADA',
                        beneficiario_pagador: item.beneficiario_pagador,
                        tipoTransacao: item.tipoTransacao
                    }));
                setDespesasExecutadas(saidas);
            })
            .catch((err) => {
                if (!cancelled) {
                    console.error('[useContasPagar] Erro ao carregar extrato para cruzamento:', err);
                    setDespesasExecutadas([]);
                }
            })
            .finally(() => {
                if (!cancelled) setCruzamentoLoading(false);
            });
        return () => { cancelled = true; };
    }, []);

    useEffect(() => {
        let cancelled = false;
        Promise.all([extratoService.fetchCategorias(), extratoService.fetchCaixinhas()])
            .then(([cats, cxs]) => {
                if (cancelled) return;
                setCategorias(Array.isArray(cats) ? cats : []);
                setCaixinhas(Array.isArray(cxs) ? cxs : []);
            })
            .catch(() => {
                if (!cancelled) {
                    setCategorias([]);
                    setCaixinhas([]);
                }
            });
        return () => { cancelled = true; };
    }, []);

    // KPIs de Cruzamento (Planejado vs Executado)
    const kpisCruzamento = useMemo(() => {
        const totalPlanejado = despesasPlanejadas.reduce((acc, item) => acc + (item.valor || 0), 0);
        const totalExecutado = despesasExecutadas.reduce((acc, item) => acc + (item.valor || 0), 0);
        const variacao = totalExecutado - totalPlanejado;
        const percentualVariacao = totalPlanejado > 0 ? ((totalExecutado / totalPlanejado) * 100).toFixed(1) : 0;
        
        return {
            totalPlanejado,
            totalExecutado,
            variacao,
            percentualVariacao: parseFloat(percentualVariacao)
        };
    }, [despesasPlanejadas, despesasExecutadas]);

    // Ações para Despesas V2 - Memoizadas
    const createDespesa = useCallback(async (despesaData) => {
        if (!despesaData.montante || !despesaData.categoria) {
            toastRef.current.error('Por favor, preencha os campos obrigatórios (Montante e Categoria)');
            return null;
        }

        try {
            const result = await workspaceDespesasV2Service.createDespesa(despesaData);
            if (result) {
                toastRef.current.success('Despesa criada com sucesso!');
                fetchDespesas();
                return result;
            }
        } catch (error) {
            console.error('[useContasPagar] Erro ao criar despesa:', error);
            toastRef.current.error('Erro ao criar despesa');
        }
        return null;
    }, [fetchDespesas]);

    const updateDespesa = useCallback(async (id, despesaData) => {
        try {
            const payload = { ...despesaData, idDespesa: id };
            const result = await workspaceDespesasV2Service.updateDespesa(payload);
            if (result) {
                toastRef.current.success('Despesa atualizada com sucesso!');
                
                // Atualiza o estado da despesa selecionada para refletir as mudanças no painel lateral
                setSelectedDespesa(prev => (prev && (prev.idDespesa === id || prev.id === id)) 
                    ? { ...prev, ...despesaData } 
                    : prev
                );

                fetchDespesas();
                return result;
            }
        } catch (error) {
            console.error('[useContasPagar] Erro ao atualizar despesa:', error);
            toastRef.current.error('Erro ao atualizar despesa');
        }
    }, [fetchDespesas]);

    const deleteDespesa = useCallback(async (id) => {
        try {
            const result = await workspaceDespesasV2Service.deleteDespesa(id);
            if (result) {
                toastRef.current.success('Despesa excluída com sucesso!');
                fetchDespesas();
                return true;
            }
        } catch (error) {
            console.error('[useContasPagar] Erro ao excluir despesa:', error);
            toastRef.current.error('Erro ao excluir despesa');
        }
        return false;
    }, [fetchDespesas]);

    // Ações para Itens de Diário
    const createItemDespesa = useCallback(async (itemData) => {
        try {
            const result = await workspaceDespesasV2Service.createItemDespesa(itemData);
            if (result && selectedDespesa) {
                const id = selectedDespesa.idDespesa;
                const updatedItens = await workspaceDespesasV2Service.fetchItensDespesa(id);
                setSelectedDespesa(prev => (prev && prev.idDespesa === id) ? { ...prev, diario: updatedItens } : prev);
                fetchTotalDiario(id);
                toastRef.current.success('Item adicionado ao diário!');
                return result;
            }
        } catch (error) {
            toastRef.current.error('Erro ao adicionar item ao diário');
        }
    }, [selectedDespesa, fetchTotalDiario]);

    const updateItemDespesa = useCallback(async (idDiario, itemData) => {
        try {
            const result = await workspaceDespesasV2Service.updateItemDespesa({ ...itemData, idDiario });
            if (result && selectedDespesa) {
                const id = selectedDespesa.idDespesa;
                const updatedItens = await workspaceDespesasV2Service.fetchItensDespesa(id);
                setSelectedDespesa(prev => (prev && prev.idDespesa === id) ? { ...prev, diario: updatedItens } : prev);
                fetchTotalDiario(id);
                toastRef.current.success('Item atualizado!');
            }
        } catch (error) {
            toastRef.current.error('Erro ao atualizar item');
        }
    }, [selectedDespesa, fetchTotalDiario]);

    const deleteItemDespesa = useCallback(async (idDiario) => {
        try {
            const result = await workspaceDespesasV2Service.deleteItemDespesa(idDiario);
            if (result && selectedDespesa) {
                const id = selectedDespesa.idDespesa;
                const updatedItens = await workspaceDespesasV2Service.fetchItensDespesa(id);
                setSelectedDespesa(prev => (prev && prev.idDespesa === id) ? { ...prev, diario: updatedItens } : prev);
                fetchTotalDiario(id);
                toastRef.current.success('Item removido!');
            }
        } catch (error) {
            toastRef.current.error('Erro ao remover item');
        }
    }, [selectedDespesa, fetchTotalDiario]);

    return {
        state: {
            activeTab,
            activeSubView,
            searchTerm,
            selectedIds,
            isLoading,
            // Fornecedores
            fornecedores,
            fornecedoresLoading,
            selectedFornecedor,
            // Despesas
            despesas,
            despesasLoading,
            selectedDespesa,
            itensDespesaLoading,
            totalItensDespesa,
            // Cruzamento
            despesasPlanejadas,
            despesasExecutadas,
            cruzamentoLoading,
            categorias,
            caixinhas,
            kpisCruzamento,
            // Filtros expostos
            filtroMes,
            filtroAno,
            filtroTipoPeriodo,
            filtroTipoCobranca
        },
        actions: useMemo(() => ({
            setActiveTab,
            setActiveSubView,
            setSearchTerm,
            fetchDespesas,
            fetchFornecedores,
            // Fornecedores
            setSelectedFornecedor,
            // Despesas
            createDespesa,
            updateDespesa,
            deleteDespesa,
            setSelectedDespesa,
            // Itens Diário
            createItemDespesa,
            updateItemDespesa,
            deleteItemDespesa,
            // Cruzamento
            setDespesasPlanejadas,
            setDespesasExecutadas,
            // Setters de filtros
            setFiltroMes,
            setFiltroAno,
            setFiltroTipoPeriodo,
            setFiltroTipoCobranca
        }), [
            setActiveTab, setActiveSubView, setSearchTerm, fetchDespesas, fetchFornecedores,
            setSelectedFornecedor, createDespesa, updateDespesa, deleteDespesa,
            setSelectedDespesa, createItemDespesa, updateItemDespesa, deleteItemDespesa,
            setDespesasPlanejadas, setDespesasExecutadas, setFiltroMes, setFiltroAno,
            setFiltroTipoPeriodo, setFiltroTipoCobranca
        ])
    };
};
