"use client"; import { useState, useCallback } from "react"; import { ConditionNode } from "@/lib/api/dataflow"; import { generateConditionId, generateGroupId, generateActionGroupId, findOpenGroups, getNextGroupLevel, getCurrentGroupLevel, } from "@/utils/connectionUtils"; import toast from "react-hot-toast"; export const useConditionManager = () => { const [conditions, setConditions] = useState([]); // 조건 추가 const addCondition = useCallback(() => { const newCondition: ConditionNode = { id: generateConditionId(), type: "condition" as const, field: "", operator: "=", value: "", dataType: "string", // 첫 번째 조건이 아니고, 바로 앞이 group-start가 아니면 logicalOperator 추가 ...(conditions.length > 0 && conditions[conditions.length - 1]?.type !== "group-start" && { logicalOperator: "AND" as const }), }; setConditions([...conditions, newCondition]); }, [conditions]); // 그룹 시작 추가 const addGroupStart = useCallback(() => { const groupId = generateGroupId(); const groupLevel = getNextGroupLevel(conditions); const groupStart: ConditionNode = { id: generateConditionId(), type: "group-start" as const, groupId, groupLevel, // 첫 번째 그룹이 아니면 logicalOperator 추가 ...(conditions.length > 0 && { logicalOperator: "AND" as const }), }; setConditions([...conditions, groupStart]); }, [conditions]); // 그룹 끝 추가 const addGroupEnd = useCallback(() => { // 가장 최근에 열린 그룹 찾기 const openGroups = findOpenGroups(conditions); if (openGroups.length === 0) { toast.error("닫을 그룹이 없습니다."); return; } const lastOpenGroup = openGroups[openGroups.length - 1]; const groupEnd: ConditionNode = { id: generateConditionId(), type: "group-end" as const, groupId: lastOpenGroup.groupId, groupLevel: lastOpenGroup.groupLevel, }; setConditions([...conditions, groupEnd]); }, [conditions]); // 조건 업데이트 const updateCondition = useCallback( (index: number, field: keyof ConditionNode, value: string) => { const updatedConditions = [...conditions]; updatedConditions[index] = { ...updatedConditions[index], [field]: value }; setConditions(updatedConditions); }, [conditions], ); // 조건 제거 const removeCondition = useCallback( (index: number) => { const conditionToRemove = conditions[index]; // 그룹 시작/끝을 삭제하는 경우 해당 그룹 전체 삭제 if (conditionToRemove.type === "group-start" || conditionToRemove.type === "group-end") { const updatedConditions = conditions.filter((c) => c.groupId !== conditionToRemove.groupId); setConditions(updatedConditions); } else { const updatedConditions = conditions.filter((_, i) => i !== index); setConditions(updatedConditions); } }, [conditions], ); // 그룹 전체 삭제 const removeGroup = useCallback( (groupId: string) => { const updatedConditions = conditions.filter((c) => c.groupId !== groupId); setConditions(updatedConditions); }, [conditions], ); return { conditions, setConditions, addCondition, addGroupStart, addGroupEnd, updateCondition, removeCondition, removeGroup, getCurrentGroupLevel: (conditionIndex: number) => getCurrentGroupLevel(conditions, conditionIndex), }; }; // 액션별 조건 관리를 위한 헬퍼 함수들 export const useActionConditionHelpers = () => { // 액션별 그룹 시작 추가 const addActionGroupStart = useCallback( (actionIndex: number, dataSaveSettings: any, setDataSaveSettings: (settings: any) => void) => { const groupId = generateActionGroupId(); const currentConditions = dataSaveSettings.actions[actionIndex].conditions || []; const groupLevel = getNextGroupLevel(currentConditions); const groupStart: ConditionNode = { id: generateConditionId(), type: "group-start" as const, groupId, groupLevel, // 첫 번째 그룹이 아니면 logicalOperator 추가 ...(currentConditions.length > 0 && { logicalOperator: "AND" as const }), }; const newActions = [...dataSaveSettings.actions]; newActions[actionIndex].conditions = [...currentConditions, groupStart]; setDataSaveSettings({ ...dataSaveSettings, actions: newActions }); }, [], ); // 액션별 그룹 끝 추가 const addActionGroupEnd = useCallback( (actionIndex: number, dataSaveSettings: any, setDataSaveSettings: (settings: any) => void) => { const currentConditions = dataSaveSettings.actions[actionIndex].conditions || []; const openGroups = findOpenGroups(currentConditions); if (openGroups.length === 0) { toast.error("닫을 그룹이 없습니다."); return; } const lastOpenGroup = openGroups[openGroups.length - 1]; const groupEnd: ConditionNode = { id: generateConditionId(), type: "group-end" as const, groupId: lastOpenGroup.groupId, groupLevel: lastOpenGroup.groupLevel, }; const newActions = [...dataSaveSettings.actions]; newActions[actionIndex].conditions = [...currentConditions, groupEnd]; setDataSaveSettings({ ...dataSaveSettings, actions: newActions }); }, [], ); // 액션별 현재 조건의 그룹 레벨 계산 const getActionCurrentGroupLevel = useCallback((conditions: ConditionNode[], conditionIndex: number): number => { return getCurrentGroupLevel(conditions, conditionIndex); }, []); return { addActionGroupStart, addActionGroupEnd, getActionCurrentGroupLevel, }; };