import { createContext, useContext, useState, useCallback, type ReactNode } from "react"; import { usePeriodicExpenses, useCreatePeriodicExpense, useUpdatePeriodicExpense, useDeletePeriodicExpense, useGenerateMonthlyExpense, useExpenses, useCreateNonPeriodicExpense, usePayExpense, useMonthlyTotals, } from "@/lib/queries"; import type { PeriodicExpense, Expense, CreatePeriodicExpenseInput, CreateNonPeriodicExpenseInput, PayExpenseInput, PaginatedResponse, MonthlyTotals, } from "@/lib/api"; interface ExpensesContextValue { periodicExpenses: PeriodicExpense[]; isLoadingPeriodic: boolean; expenses: PaginatedResponse; isLoadingExpenses: boolean; statusFilter: string; setStatusFilter: (status: string) => void; page: number; setPage: (page: number) => void; pageSize: number; monthlyTotals: MonthlyTotals | undefined; isLoadingTotals: boolean; createPeriodicExpense: (data: CreatePeriodicExpenseInput) => Promise; updatePeriodicExpense: (id: number, data: CreatePeriodicExpenseInput) => Promise; deletePeriodicExpense: (id: number) => Promise; generateMonthlyExpense: (id: number) => Promise; createNonPeriodicExpense: (data: CreateNonPeriodicExpenseInput) => Promise; payExpense: (id: number, data: PayExpenseInput) => Promise; } const ExpensesContext = createContext(null); export function ExpensesProvider({ children }: { children: ReactNode }) { const [statusFilter, setStatusFilter] = useState("PENDING"); const [page, setPage] = useState(1); const pageSize = 10; const { data: periodicExpenses = [], isLoading: isLoadingPeriodic } = usePeriodicExpenses(); const { data: expenses = { data: [], total: 0, page: 1, pageSize: 10 }, isLoading: isLoadingExpenses } = useExpenses(statusFilter, page, pageSize); const now = new Date(); const { data: monthlyTotals, isLoading: isLoadingTotals } = useMonthlyTotals(now.getFullYear(), now.getMonth() + 1); const createPeriodicMutation = useCreatePeriodicExpense(); const updatePeriodicMutation = useUpdatePeriodicExpense(); const deletePeriodicMutation = useDeletePeriodicExpense(); const generateMonthlyMutation = useGenerateMonthlyExpense(); const createExpenseMutation = useCreateNonPeriodicExpense(); const payExpenseMutation = usePayExpense(); const createPeriodicExpense = useCallback( async (data: CreatePeriodicExpenseInput): Promise => { return createPeriodicMutation.mutateAsync(data); }, [createPeriodicMutation], ); const updatePeriodicExpenseFn = useCallback( async (id: number, data: CreatePeriodicExpenseInput) => { await updatePeriodicMutation.mutateAsync({ id, data }); }, [updatePeriodicMutation], ); const deletePeriodicExpenseFn = useCallback( async (id: number) => { await deletePeriodicMutation.mutateAsync(id); }, [deletePeriodicMutation], ); const generateMonthlyExpenseFn = useCallback( async (id: number): Promise => { return generateMonthlyMutation.mutateAsync(id); }, [generateMonthlyMutation], ); const createNonPeriodicExpenseFn = useCallback( async (data: CreateNonPeriodicExpenseInput) => { await createExpenseMutation.mutateAsync(data); }, [createExpenseMutation], ); const payExpenseFn = useCallback( async (id: number, data: PayExpenseInput) => { await payExpenseMutation.mutateAsync({ id, data }); }, [payExpenseMutation], ); return ( {children} ); } export function useExpensesContext() { const ctx = useContext(ExpensesContext); if (!ctx) throw new Error("useExpensesContext must be used within ExpensesProvider"); return ctx; }