import { create } from 'zustand';
import type { Expense, ExpenseFormData } from '@/types';

interface ExpenseState {
  expenses: Expense[];
  fetchExpenses: () => Promise<void>;
  addExpense: (data: ExpenseFormData) => Promise<void>;
  deleteExpense: (id: number) => Promise<void>;
  getTotalExpenses: () => number;
  getExpensesByCategory: () => { category: string; amount: number }[];
}

// No demo data - starts empty
const demoExpenses: Expense[] = [];

function mapApiExpense(e: Record<string, unknown>): Expense {
  return {
    id: Number(e.id ?? 0),
    category: (e.category ?? 'other') as Expense['category'],
    description: String(e.description ?? ''),
    amount: Number(e.amount ?? 0),
    expenseDate: String(e.expense_date ?? e.expenseDate ?? ''),
    createdAt: String(e.created_at ?? e.createdAt ?? ''),
  };
}

export const useExpenseStore = create<ExpenseState>((set, get) => ({
  expenses: [],

  fetchExpenses: async () => {
    try {
      const res = await fetch('/api/expenses.php');
      const data = await res.json();
      if (Array.isArray(data)) {
        set({ expenses: data.map(mapApiExpense) });
        return;
      }
    } catch { /* offline */ }
    set({ expenses: demoExpenses });
  },

  addExpense: async (data) => {
    try {
      await fetch('/api/expenses.php', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify(data),
      });
      await get().fetchExpenses();
    } catch {
      // offline fallback
      const newExpense: Expense = {
        id: Date.now(),
        category: data.category,
        description: data.description,
        amount: data.amount,
        expenseDate: data.expenseDate,
        createdAt: new Date().toISOString(),
      };
      set(state => ({ expenses: [newExpense, ...state.expenses] }));
    }
  },

  deleteExpense: async (id) => {
    try {
      await fetch(`/api/expenses.php?id=${id}`, { method: 'DELETE' });
      await get().fetchExpenses();
    } catch {
      set(state => ({ expenses: state.expenses.filter(e => e.id !== id) }));
    }
  },

  getTotalExpenses: () => {
    return get().expenses.reduce((sum, e) => sum + e.amount, 0);
  },

  getExpensesByCategory: () => {
    const map: Record<string, number> = {};
    get().expenses.forEach(e => {
      map[e.category] = (map[e.category] || 0) + e.amount;
    });
    return Object.entries(map).map(([category, amount]) => ({ category, amount }));
  },
}));
