"use client"; import { useState, useCallback } from "react"; import { apiClient } from "@/lib/api/client"; import { ProcessWorkStandardConfig, ItemData, RoutingVersion, WorkItem, WorkItemDetail, SelectionState, } from "../types"; const API_BASE = "/api/process-work-standard"; export function useProcessWorkStandard(config: ProcessWorkStandardConfig) { const [items, setItems] = useState([]); const [routings, setRoutings] = useState([]); const [workItems, setWorkItems] = useState([]); const [selectedWorkItemDetails, setSelectedWorkItemDetails] = useState([]); const [selectedWorkItemId, setSelectedWorkItemId] = useState(null); const [loading, setLoading] = useState(false); const [saving, setSaving] = useState(false); const [selection, setSelection] = useState({ itemCode: null, itemName: null, routingVersionId: null, routingVersionName: null, routingDetailId: null, processName: null, }); // 품목 목록 조회 const fetchItems = useCallback( async (search?: string) => { try { setLoading(true); const ds = config.dataSource; const params = new URLSearchParams({ tableName: ds.itemTable, nameColumn: ds.itemNameColumn, codeColumn: ds.itemCodeColumn, routingTable: ds.routingVersionTable, routingFkColumn: ds.routingFkColumn, ...(search ? { search } : {}), }); const res = await apiClient.get(`${API_BASE}/items?${params}`); if (res.data?.success) { setItems(res.data.data); } } catch (err) { console.error("품목 조회 실패", err); } finally { setLoading(false); } }, [config.dataSource] ); // 라우팅 + 공정 조회 const fetchRoutings = useCallback( async (itemCode: string) => { try { const ds = config.dataSource; const params = new URLSearchParams({ routingVersionTable: ds.routingVersionTable, routingDetailTable: ds.routingDetailTable, routingFkColumn: ds.routingFkColumn, processTable: ds.processTable, processNameColumn: ds.processNameColumn, processCodeColumn: ds.processCodeColumn, }); const res = await apiClient.get( `${API_BASE}/items/${encodeURIComponent(itemCode)}/routings?${params}` ); if (res.data?.success) { setRoutings(res.data.data); } } catch (err) { console.error("라우팅 조회 실패", err); } }, [config.dataSource] ); // 작업 항목 조회 const fetchWorkItems = useCallback(async (routingDetailId: string) => { try { setLoading(true); const res = await apiClient.get( `${API_BASE}/routing-detail/${routingDetailId}/work-items` ); if (res.data?.success) { setWorkItems(res.data.items || []); } } catch (err) { console.error("작업 항목 조회 실패", err); } finally { setLoading(false); } }, []); // 작업 항목 상세 조회 const fetchWorkItemDetails = useCallback(async (workItemId: string) => { try { const res = await apiClient.get( `${API_BASE}/work-items/${workItemId}/details` ); if (res.data?.success) { setSelectedWorkItemDetails(res.data.data); setSelectedWorkItemId(workItemId); } } catch (err) { console.error("상세 조회 실패", err); } }, []); // 품목 선택 const selectItem = useCallback( async (itemCode: string, itemName: string) => { setSelection((prev) => ({ ...prev, itemCode, itemName, routingVersionId: null, routingVersionName: null, routingDetailId: null, processName: null, })); setWorkItems([]); setSelectedWorkItemDetails([]); setSelectedWorkItemId(null); await fetchRoutings(itemCode); }, [fetchRoutings] ); // 공정 선택 const selectProcess = useCallback( async ( routingDetailId: string, processName: string, routingVersionId: string, routingVersionName: string ) => { setSelection((prev) => ({ ...prev, routingVersionId, routingVersionName, routingDetailId, processName, })); setSelectedWorkItemDetails([]); setSelectedWorkItemId(null); await fetchWorkItems(routingDetailId); }, [fetchWorkItems] ); // 작업 항목 추가 const createWorkItem = useCallback( async (data: { work_phase: string; title: string; is_required: string; description?: string; details?: Array<{ detail_type?: string; content: string; is_required: string; sort_order: number; }>; }) => { if (!selection.routingDetailId) return null; try { const nextOrder = workItems.filter((wi) => wi.work_phase === data.work_phase).length + 1; const res = await apiClient.post(`${API_BASE}/work-items`, { routing_detail_id: selection.routingDetailId, work_phase: data.work_phase, title: data.title, is_required: data.is_required, sort_order: nextOrder, description: data.description, }); if (res.data?.success && res.data.data) { const newItem = res.data.data; // 상세 항목도 함께 생성 if (data.details && data.details.length > 0) { for (const detail of data.details) { await apiClient.post(`${API_BASE}/work-item-details`, { work_item_id: newItem.id, ...detail, }); } } await fetchWorkItems(selection.routingDetailId); return newItem; } } catch (err) { console.error("작업 항목 생성 실패", err); } return null; }, [selection.routingDetailId, workItems, fetchWorkItems] ); // 작업 항목 수정 const updateWorkItem = useCallback( async (id: string, data: Partial) => { try { const res = await apiClient.put(`${API_BASE}/work-items/${id}`, data); if (res.data?.success && selection.routingDetailId) { await fetchWorkItems(selection.routingDetailId); } } catch (err) { console.error("작업 항목 수정 실패", err); } }, [selection.routingDetailId, fetchWorkItems] ); // 작업 항목 삭제 const deleteWorkItem = useCallback( async (id: string) => { try { const res = await apiClient.delete(`${API_BASE}/work-items/${id}`); if (res.data?.success && selection.routingDetailId) { await fetchWorkItems(selection.routingDetailId); if (selectedWorkItemId === id) { setSelectedWorkItemDetails([]); setSelectedWorkItemId(null); } } } catch (err) { console.error("작업 항목 삭제 실패", err); } }, [selection.routingDetailId, selectedWorkItemId, fetchWorkItems] ); // 상세 추가 const createDetail = useCallback( async (workItemId: string, data: Partial) => { try { const res = await apiClient.post(`${API_BASE}/work-item-details`, { work_item_id: workItemId, ...data, }); if (res.data?.success) { await fetchWorkItemDetails(workItemId); if (selection.routingDetailId) { await fetchWorkItems(selection.routingDetailId); } } } catch (err) { console.error("상세 생성 실패", err); } }, [fetchWorkItemDetails, fetchWorkItems, selection.routingDetailId] ); // 상세 수정 const updateDetail = useCallback( async (id: string, data: Partial) => { try { const res = await apiClient.put( `${API_BASE}/work-item-details/${id}`, data ); if (res.data?.success && selectedWorkItemId) { await fetchWorkItemDetails(selectedWorkItemId); } } catch (err) { console.error("상세 수정 실패", err); } }, [selectedWorkItemId, fetchWorkItemDetails] ); // 상세 삭제 const deleteDetail = useCallback( async (id: string) => { try { const res = await apiClient.delete( `${API_BASE}/work-item-details/${id}` ); if (res.data?.success) { if (selectedWorkItemId) { await fetchWorkItemDetails(selectedWorkItemId); } if (selection.routingDetailId) { await fetchWorkItems(selection.routingDetailId); } } } catch (err) { console.error("상세 삭제 실패", err); } }, [ selectedWorkItemId, selection.routingDetailId, fetchWorkItemDetails, fetchWorkItems, ] ); return { items, routings, workItems, selectedWorkItemDetails, selectedWorkItemId, selection, loading, saving, fetchItems, selectItem, selectProcess, fetchWorkItems, fetchWorkItemDetails, setSelectedWorkItemId, createWorkItem, updateWorkItem, deleteWorkItem, createDetail, updateDetail, deleteDetail, }; }