import { useCallback, useRef, useState } from 'react'; import { toast } from '@/hooks/useToast.wrapper'; /** * 최근 거래내역 관련 로직을 처리하는 커스텀 훅 * 삭제 로직과 상태 관리 등을 담당 */ export const useRecentTransactions = ( deleteTransaction: (id: string) => void ) => { const [isDeleting, setIsDeleting] = useState(false); // 삭제 중인 ID 추적 const deletingIdRef = useRef(null); // 타임아웃 추적 const timeoutRef = useRef(null); // 삭제 요청 타임스탬프 추적 (급발진 방지) const lastDeleteTimeRef = useRef>({}); // 완전히 새로운 삭제 처리 함수 const handleDeleteTransaction = useCallback(async (id: string): Promise => { return new Promise(resolve => { try { // 삭제 진행 중인지 확인 if (isDeleting || deletingIdRef.current === id) { console.log('이미 삭제 작업이 진행 중입니다'); resolve(true); return; } // 급발진 방지 (300ms) const now = Date.now(); if (lastDeleteTimeRef.current[id] && now - lastDeleteTimeRef.current[id] < 300) { console.warn('삭제 요청이 너무 빠릅니다. 무시합니다.'); resolve(true); return; } // 타임스탬프 업데이트 lastDeleteTimeRef.current[id] = now; // 삭제 상태 설정 setIsDeleting(true); deletingIdRef.current = id; // 안전장치: 타임아웃 설정 (최대 900ms) if (timeoutRef.current) { clearTimeout(timeoutRef.current); } timeoutRef.current = setTimeout(() => { console.warn('삭제 타임아웃 - 상태 초기화'); setIsDeleting(false); deletingIdRef.current = null; resolve(true); // UI 응답성 위해 성공 간주 }, 900); // 비동기 작업을 동기적으로 처리하여 UI 블로킹 방지 setTimeout(async () => { try { deleteTransaction(id); // 안전장치 타임아웃 제거 if (timeoutRef.current) { clearTimeout(timeoutRef.current); timeoutRef.current = null; } // 상태 초기화 (지연 적용) setTimeout(() => { setIsDeleting(false); deletingIdRef.current = null; }, 100); } catch (err) { console.error('삭제 처리 오류:', err); } }, 0); // 즉시 성공 반환 (UI 응답성 향상) resolve(true); } catch (error) { console.error('삭제 처리 전체 오류:', error); // 항상 상태 정리 setIsDeleting(false); deletingIdRef.current = null; if (timeoutRef.current) { clearTimeout(timeoutRef.current); timeoutRef.current = null; } toast({ title: "오류 발생", description: "처리 중 문제가 발생했습니다.", variant: "destructive", duration: 1500 }); resolve(false); } }); }, [deleteTransaction, isDeleting]); // 컴포넌트 언마운트 시 타임아웃 정리 (리액트 컴포넌트에서 처리해야함) const cleanupTimeouts = useCallback(() => { if (timeoutRef.current) { clearTimeout(timeoutRef.current); timeoutRef.current = null; } }, []); return { handleDeleteTransaction, isDeleting, cleanupTimeouts }; };