import { create } from 'zustand';
import { conciliacaoService } from '@/services/conciliacaoService';
import { normalizeText } from '../views/conciliacao/utils/ofxParser';
import { runReconciliationLogic } from '../utils/reconciliationEngine';

const useConciliacao = create((set, get) => ({
  // State
  activeTab: 'consolidacao',
  activeFilter: 'Regra',
  viewLevel: 0,
  drillDownPath: [],
  
  bankTransactions: [],
  systemTransactions: [],
  predictedTransactions: [],
  
  rules: [],
  categories: [],
  caixinhas: [],
  
  isLoading: false,
  error: null,
  selectedTransactionForReconciliation: null,

  // Actions
  setSelectedTransaction: (transaction) => set({ selectedTransactionForReconciliation: transaction }),

  importOFX: async (file) => {
    try {
      set({ isLoading: true });
      await conciliacaoService.importOFX(file);
      await get().loadData();
      set({ isLoading: false });
      return { success: true };
    } catch (err) {
      console.error("Erro ao importar OFX:", err);
      set({ error: err.message, isLoading: false });
      return { success: false, error: err.message };
    }
  },

  // Actions
  setActiveTab: (tab) => set({ activeTab: tab }),
  setActiveFilter: (filter) => set({ activeFilter: filter, viewLevel: 0, drillDownPath: [] }),
  setViewLevel: (level) => set({ viewLevel: level }),
  
  navigateDrillDown: (name) => {
    const { viewLevel, drillDownPath } = get();
    if (viewLevel >= 2) return;
    set({
      drillDownPath: [...drillDownPath, name],
      viewLevel: viewLevel + 1
    });
  },
  
  navigateBack: () => {
    const { viewLevel, drillDownPath } = get();
    if (viewLevel > 0) {
      set({
        viewLevel: viewLevel - 1,
        drillDownPath: drillDownPath.slice(0, -1)
      });
    }
  },

  loadData: async () => {
    set({ isLoading: true });
    try {
      const [cats, rules, statement, caixinhas] = await Promise.all([
        conciliacaoService.fetchCategories(),
        conciliacaoService.fetchRules(),
        conciliacaoService.fetchStatement(),
        conciliacaoService.fetchCaixinhas()
      ]);

      const findId = (item) => item.id || item.id_categoria || item.idcategoria || item.id_regra || item.idregra || item._id || item.idcaixinhas_financeiro || item.idregras_financeiro || null;
      const findName = (item) => item.nome || item.name || item.descricao || item.titulo || item.regra || item.categoria || item.caixinha || "Sem Nome";

      const mappedCategories = (cats || []).map(c => ({ id: String(findId(c)), name: findName(c) }));
      const mappedCaixinhas = (caixinhas || []).map(c => ({ id: String(findId(c)), name: findName(c) }));
      
      const mappedRules = (rules || []).map(r => ({
        id: String(findId(r)),
        name: findName(r),
        condition: r.condicional || r.condicao || r.termo || "",
        categoryId: String(r.id_categoria || r.categoria || r.categoryId || "0"),
        caixinha: String(r.caixinha || "0"),
        beneficiario: r.beneficiario_pagador || r.beneficiario || "0"
      }));

      const mappedBankTransactions = (statement || []).map(t => {
        const amount = parseFloat(t.valor || 0);
        const externalRuleId = t.regra ? String(t.regra) : null;
        const externalCategoryId = t.categoria ? String(t.categoria) : null;

        return {
          id: t.idextrato || `api-${Math.random().toString(36).substr(2, 9)}`,
          date: t.dataEntrada ? new Date(t.dataEntrada) : new Date(),
          description: t.descricao || "Sem descrição",
          amount: (t.tipoOperacao === 'D' && amount > 0) ? -amount : amount,
          type: (t.tipoOperacao === 'D' || amount < 0) ? 'DEBIT' : 'CREDIT',
          externalRuleId,
          externalCategoryId,
          isReconciled: !!(externalRuleId && externalRuleId !== "0") || !!(externalCategoryId && externalCategoryId !== "0"),
          raw: t
        };
      });

      set({
        categories: mappedCategories,
        caixinhas: mappedCaixinhas,
        rules: mappedRules,
        bankTransactions: mappedBankTransactions,
        isLoading: false
      });
    } catch (err) {
      console.error("Error loading reconciliation data:", err);
      set({ error: err.message, isLoading: false });
    }
  },

  getScopedData: () => {
    const { bankTransactions, rules, categories, viewLevel, drillDownPath } = get();
    
    // Enrich transactions with resolved Category and Rule
    const enriched = bankTransactions.map(t => {
      let resolvedCategory = t.externalCategoryId;
      let resolvedRuleName = null;
      let ruleId = t.externalRuleId;

      if (ruleId && ruleId !== "0") {
        const rule = rules.find(r => r.id === ruleId);
        if (rule) {
          resolvedCategory = rule.categoryId;
          resolvedRuleName = rule.name;
        }
      }

      const categoryName = categories.find(c => c.id === resolvedCategory)?.name || "Sem Categoria";

      return {
        ...t,
        categoryName,
        categoryId: resolvedCategory,
        ruleName: resolvedRuleName || (t.isReconciled ? "Conciliado (Sem Regra)" : "Pendente"),
        ruleId: ruleId
      };
    });

    // Apply drill-down filtering
    let scoped = enriched;
    if (viewLevel >= 1) {
      scoped = scoped.filter(t => t.categoryName === drillDownPath[0]);
    }
    if (viewLevel >= 2) {
      // Logic for Level 2: Inside a category, we show either a specific rule or "Conciliado (Sem Regra)"
      scoped = scoped.filter(t => t.ruleName === drillDownPath[1]);
    }

    return scoped;
  },

  getAggregatedItems: () => {
    const { viewLevel, drillDownPath, categories, rules } = get();
    const scoped = get().getScopedData();

    if (viewLevel === 0) {
      // Level 0: Total by Category
      const grouped = {};
      scoped.forEach(t => {
        const name = t.categoryName;
        if (!grouped[name]) grouped[name] = { name, amount: 0, count: 0, predicted: 0 };
        grouped[name].amount += t.amount;
        grouped[name].count++;
      });
      return Object.values(grouped);
    }

    if (viewLevel === 1) {
      // Level 1: Inside Category - Group by Rule + "Conciliado (Sem Regra)"
      const grouped = {};
      scoped.forEach(t => {
        const name = t.ruleName;
        if (!grouped[name]) grouped[name] = { name, amount: 0, count: 0, predicted: 0 };
        grouped[name].amount += t.amount;
        grouped[name].count++;
      });
      return Object.values(grouped);
    }

    if (viewLevel === 2) {
      // Level 2: List of transactions
      return scoped.map(t => ({
        id: t.id,
        name: t.description,
        amount: t.amount,
        date: t.date,
        isTransaction: true,
        raw: t
      }));
    }

    return [];
  },

  reconcileTransaction: async (data) => {
    try {
      set({ isLoading: true });
      // The API expects individual updates or a structured payload
      // Based on the legacy code provided, it calls updateTransactionCategory, updateTransactionBox, etc.
      // Or a single updateTransactionRule if it's considered a rule update.
      // The user JSON suggests updating category, box, beneficiary, and description.

      const { idextrato, categoria, caixinha, beneficiario_pagador } = data;

      await Promise.all([
        conciliacaoService.updateTransactionCategory(idextrato, categoria),
        conciliacaoService.updateTransactionBox(idextrato, caixinha || "0"),
        conciliacaoService.updateTransactionBeneficiary(idextrato, beneficiario_pagador)
      ]);

      await get().loadData();
      set({ isLoading: false });
      return { success: true };
    } catch (err) {
      console.error("Erro ao conciliar transação:", err);
      set({ isLoading: false });
      return { success: false, error: err.message };
    }
  },

  // ==================== CATEGORIAS ====================
  addCategory: async (payload) => {
    try {
      await conciliacaoService.createCategory(payload);
      await get().loadData();
      return { success: true };
    } catch (err) {
      console.error("Erro ao adicionar categoria:", err);
      return { success: false, error: err.message };
    }
  },

  updateCategory: async (payload) => {
    try {
      await conciliacaoService.updateCategory(payload);
      await get().loadData();
      return { success: true };
    } catch (err) {
      console.error("Erro ao atualizar categoria:", err);
      return { success: false, error: err.message };
    }
  },

  deleteCategory: async (id) => {
    try {
      await conciliacaoService.deleteCategory(id);
      await get().loadData();
      return { success: true };
    } catch (err) {
      console.error("Erro ao excluir categoria:", err);
      return { success: false, error: err.message };
    }
  },

  // ==================== CAIXINHAS ====================
  addCaixinha: async (payload) => {
    try {
      await conciliacaoService.createCaixinha(payload);
      await get().loadData();
      return { success: true };
    } catch (err) {
      console.error("Erro ao adicionar caixinha:", err);
      return { success: false, error: err.message };
    }
  },

  updateCaixinha: async (payload) => {
    try {
      await conciliacaoService.updateCaixinha(payload);
      await get().loadData();
      return { success: true };
    } catch (err) {
      console.error("Erro ao atualizar caixinha:", err);
      return { success: false, error: err.message };
    }
  },

  deleteCaixinha: async (id) => {
    try {
      await conciliacaoService.deleteCaixinha(id);
      await get().loadData();
      return { success: true };
    } catch (err) {
      console.error("Erro ao excluir caixinha:", err);
      return { success: false, error: err.message };
    }
  },

  // ==================== REGRAS ====================
  addRule: async (payload) => {
    try {
      await conciliacaoService.createRule(payload);
      await get().loadData();
      return { success: true };
    } catch (err) {
      console.error("Erro ao adicionar regra:", err);
      return { success: false, error: err.message };
    }
  },

  updateRule: async (payload) => {
    try {
      await conciliacaoService.updateRule(payload);
      await get().loadData();
      return { success: true };
    } catch (err) {
      console.error("Erro ao atualizar regra:", err);
      return { success: false, error: err.message };
    }
  },

  deleteRule: async (id) => {
    try {
      await conciliacaoService.deleteRule(id);
      await get().loadData();
      return { success: true };
    } catch (err) {
      console.error("Erro ao excluir regra:", err);
      return { success: false, error: err.message };
    }
  },

  runOptimizedReconciliation: async () => {
    const { bankTransactions, rules } = get();
    
    try {
      const result = await runReconciliationLogic({
        bankTransactions,
        rules,
        updateTransactionRule: async (id, payload) => {
             // Wrapper para usar a função existente de update
             // A engine espera (id, payload), o service tem updateTransactionRule(id, payload)
             // Vamos garantir que chame o service corretamente
             return conciliacaoService.updateTransactionRule(id, payload);
        }
      });

      if (result.success && result.count > 0) {
        await get().loadData();
      }
      
      return result;
    } catch (err) {
      console.error("Erro na conciliação otimizada:", err);
      throw err;
    }
  }
}));

export default useConciliacao;
