"use client"; import { useState, useMemo, useCallback } from "react"; import { useQueryClient } from "@tanstack/react-query"; import type { Transaction, Category } from "@/lib/types"; import { updateCategory } from "@/lib/store-db"; import { normalizeDescription, suggestKeyword, } from "@/components/rules/constants"; import { invalidateAllTransactionQueries, invalidateAllCategoryQueries, } from "@/lib/cache-utils"; interface UseTransactionRulesProps { transactionsData: { transactions: Transaction[] } | undefined; metadata: { categories: Category[]; } | null; } export function useTransactionRules({ transactionsData, metadata, }: UseTransactionRulesProps) { const queryClient = useQueryClient(); const [ruleDialogOpen, setRuleDialogOpen] = useState(false); const [ruleTransaction, setRuleTransaction] = useState( null ); const handleCreateRule = useCallback((transaction: Transaction) => { setRuleTransaction(transaction); setRuleDialogOpen(true); }, []); const ruleGroup = useMemo(() => { if (!ruleTransaction || !transactionsData) return null; const normalizedDesc = normalizeDescription(ruleTransaction.description); const similarTransactions = transactionsData.transactions.filter( (t) => normalizeDescription(t.description) === normalizedDesc ); if (similarTransactions.length === 0) return null; return { key: normalizedDesc, displayName: ruleTransaction.description, transactions: similarTransactions, totalAmount: similarTransactions.reduce((sum, t) => sum + t.amount, 0), suggestedKeyword: suggestKeyword( similarTransactions.map((t) => t.description) ), }; }, [ruleTransaction, transactionsData]); const handleSaveRule = useCallback( async (ruleData: { keyword: string; categoryId: string; applyToExisting: boolean; transactionIds: string[]; }) => { if (!metadata) return; // Add keyword to category const category = metadata.categories.find( (c) => c.id === ruleData.categoryId ); if (!category) { throw new Error("Category not found"); } // Check if keyword already exists const keywordExists = category.keywords.some( (k: string) => k.toLowerCase() === ruleData.keyword.toLowerCase() ); if (!keywordExists) { await updateCategory({ ...category, keywords: [...category.keywords, ruleData.keyword], }); } // Apply to existing transactions if requested if (ruleData.applyToExisting) { await Promise.all( ruleData.transactionIds.map((id) => fetch("/api/banking/transactions", { method: "PUT", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ id, categoryId: ruleData.categoryId }), }) ) ); } // Invalider toutes les queries liƩes invalidateAllTransactionQueries(queryClient); invalidateAllCategoryQueries(queryClient); setRuleDialogOpen(false); }, [metadata, queryClient] ); return { ruleDialogOpen, setRuleDialogOpen, ruleGroup, handleCreateRule, handleSaveRule, }; }