import { useState, useEffect } from 'react'; import { Transaction } from '@/components/TransactionCard'; import { useAuth } from '@/contexts/auth/AuthProvider'; import { toast } from '@/hooks/useToast.wrapper'; import { isSyncEnabled } from '@/utils/syncUtils'; import { MONTHS_KR, getCurrentMonth, getPrevMonth, getNextMonth } from '@/utils/dateUtils'; import { loadTransactionsFromStorage, saveTransactionsToStorage, loadBudgetFromStorage } from '@/utils/storageUtils'; import { filterTransactionsByMonth, filterTransactionsByQuery, calculateTotalExpenses } from '@/utils/transactionUtils'; import { syncTransactionsWithSupabase, updateTransactionInSupabase, deleteTransactionFromSupabase } from '@/utils/supabaseTransactionUtils'; import { EXPENSE_CATEGORIES } from '@/constants/categoryIcons'; // 월 이름 재노출 export { MONTHS_KR }; export const useTransactions = () => { const [transactions, setTransactions] = useState([]); const [filteredTransactions, setFilteredTransactions] = useState([]); const [selectedMonth, setSelectedMonth] = useState(getCurrentMonth()); const [searchQuery, setSearchQuery] = useState(''); const [isLoading, setIsLoading] = useState(true); const [error, setError] = useState(null); const [totalBudget, setTotalBudget] = useState(1000000); // 기본 예산 const { user } = useAuth(); // 월 변경 처리 const handlePrevMonth = () => { setSelectedMonth(getPrevMonth(selectedMonth)); }; const handleNextMonth = () => { setSelectedMonth(getNextMonth(selectedMonth)); }; // 트랜잭션 로드 const loadTransactions = () => { setIsLoading(true); setError(null); try { // 로컬 스토리지에서 트랜잭션 데이터 가져오기 const localData = loadTransactionsFromStorage(); // 지원되는 카테고리로 필터링 const filteredData = localData.map(transaction => { // 트랜잭션의 카테고리가 현재 지원되는 카테고리가 아니면 '기타'로 변경 if (transaction.type === 'expense' && !EXPENSE_CATEGORIES.includes(transaction.category)) { return { ...transaction, category: '생활비' // 기본값으로 '생활비' 사용 }; } return transaction; }); // 로컬 데이터가 있으면 사용 setTransactions(filteredData); // 예산 가져오기 const budget = loadBudgetFromStorage(); setTotalBudget(budget); } catch (err) { console.error('트랜잭션 로드 중 오류:', err); setError('데이터를 불러오는 중 문제가 발생했습니다.'); toast({ title: "데이터 로드 실패", description: "지출 내역을 불러오는데 실패했습니다.", variant: "destructive" }); } finally { setIsLoading(false); } }; // 필터 적용 useEffect(() => { // 1. 월별 필터링 let filtered = filterTransactionsByMonth(transactions, selectedMonth); // 2. 검색어 필터링 if (searchQuery.trim()) { filtered = filterTransactionsByQuery(filtered, searchQuery); } setFilteredTransactions(filtered); }, [transactions, selectedMonth, searchQuery]); // 초기 데이터 로드 useEffect(() => { loadTransactions(); // Supabase 동기화 (로그인 상태인 경우) const syncWithSupabase = async () => { if (user) { const syncedTransactions = await syncTransactionsWithSupabase(user, transactions); if (syncedTransactions !== transactions) { setTransactions(syncedTransactions); saveTransactionsToStorage(syncedTransactions); } } }; syncWithSupabase(); }, [user]); // 트랜잭션 업데이트 const updateTransaction = (updatedTransaction: Transaction) => { const updatedTransactions = transactions.map(transaction => transaction.id === updatedTransaction.id ? updatedTransaction : transaction ); setTransactions(updatedTransactions); saveTransactionsToStorage(updatedTransactions); // Supabase에도 업데이트 updateTransactionInSupabase(user, updatedTransaction); toast({ title: "지출이 수정되었습니다", description: `${updatedTransaction.title} 항목이 업데이트되었습니다.`, }); }; // 트랜잭션 삭제 const deleteTransaction = (id: string) => { const updatedTransactions = transactions.filter(transaction => transaction.id !== id); setTransactions(updatedTransactions); saveTransactionsToStorage(updatedTransactions); // Supabase에서도 삭제 deleteTransactionFromSupabase(user, id); toast({ title: "지출이 삭제되었습니다", description: "선택한 지출 항목이 삭제되었습니다.", }); }; return { transactions: filteredTransactions, isLoading, error, totalBudget, selectedMonth, searchQuery, setSearchQuery, handlePrevMonth, handleNextMonth, updateTransaction, deleteTransaction, totalExpenses: calculateTotalExpenses(filteredTransactions), refreshTransactions: loadTransactions }; };