import { useState, useCallback, useMemo, useEffect } from "react"; import { Company, CompanyFormData, CompanyModalState, CompanyDeleteState, CompanySearchFilter, AllDiskUsageInfo, } from "@/types/company"; import { DEFAULT_COMPANY_FORM_DATA, COMPANY_STATUS } from "@/constants/company"; import { companyAPI } from "@/lib/api/company"; /** * 회사 관리 비즈니스 로직을 담당하는 커스텀 훅 * CRUD 기능과 모달/다이얼로그 상태 관리 */ export const useCompanyManagement = () => { // 회사 목록 상태 const [companies, setCompanies] = useState([]); // 검색 필터 상태 const [searchFilter, setSearchFilter] = useState({}); // 로딩 및 에러 상태 const [isLoading, setIsLoading] = useState(false); const [error, setError] = useState(null); // 모달 상태 (등록/수정) const [modalState, setModalState] = useState({ isOpen: false, mode: "create", selectedCompany: null, formData: { ...DEFAULT_COMPANY_FORM_DATA }, }); // 삭제 다이얼로그 상태 const [deleteState, setDeleteState] = useState({ isOpen: false, targetCompany: null, }); // 디스크 사용량 상태 const [diskUsageInfo, setDiskUsageInfo] = useState(null); const [isDiskUsageLoading, setIsDiskUsageLoading] = useState(false); // 회사 목록 로드 const loadCompanies = useCallback(async () => { setIsLoading(true); setError(null); try { // 실제 데이터베이스에서 회사 목록 조회 const searchParams = { company_name: searchFilter.company_name, status: searchFilter.status === "all" ? undefined : searchFilter.status, }; // 더미 데이터 대신 실제 API 호출 const data = await companyAPI.getList(searchParams); setCompanies(data); // console.log("✅ 실제 DB에서 회사 목록 조회 성공:", data.length, "개"); } catch (err) { // console.error("❌ 회사 목록 조회 실패:", err); setError(err instanceof Error ? err.message : "회사 목록 조회에 실패했습니다."); setCompanies([]); } finally { setIsLoading(false); } }, [searchFilter]); // 디스크 사용량 로드 const loadDiskUsage = useCallback(async () => { setIsDiskUsageLoading(true); try { const data = await companyAPI.getAllDiskUsage(); setDiskUsageInfo(data); // console.log("✅ 디스크 사용량 조회 성공:", data.summary); } catch (err) { // console.error("❌ 디스크 사용량 조회 실패:", err); // 디스크 사용량 조회 실패는 에러로 처리하지 않음 (선택적 기능) } finally { setIsDiskUsageLoading(false); } }, []); // 초기 로드 및 검색 필터 변경 시 재로드 useEffect(() => { loadCompanies(); loadDiskUsage(); // 디스크 사용량도 함께 로드 }, [loadCompanies, loadDiskUsage]); // 디스크 사용량 정보가 포함된 회사 목록 const companiesWithDiskUsage = useMemo(() => { if (!diskUsageInfo) return companies; return companies.map((company) => { const diskUsage = diskUsageInfo.companies.find((usage) => usage.companyCode === company.company_code); return { ...company, diskUsage: diskUsage ? { fileCount: diskUsage.fileCount, totalSize: diskUsage.totalSize, totalSizeMB: diskUsage.totalSizeMB, lastChecked: diskUsage.lastChecked, } : undefined, }; }); }, [companies, diskUsageInfo]); // 필터링된 회사 목록 (디스크 사용량 정보 포함) const filteredCompanies = useMemo(() => { return companiesWithDiskUsage; }, [companiesWithDiskUsage]); // 검색 필터 업데이트 const updateSearchFilter = useCallback((filter: Partial) => { setSearchFilter((prev) => ({ ...prev, ...filter })); }, []); // 검색 필터 초기화 const clearSearchFilter = useCallback(() => { setSearchFilter({}); }, []); // 모달 열기 - 새 회사 등록 const openCreateModal = useCallback(() => { setModalState({ isOpen: true, mode: "create", selectedCompany: null, formData: { ...DEFAULT_COMPANY_FORM_DATA }, }); }, []); // 모달 열기 - 회사 수정 const openEditModal = useCallback((company: Company) => { setModalState({ isOpen: true, mode: "edit", selectedCompany: company, formData: { company_name: company.company_name, business_registration_number: company.business_registration_number || "", representative_name: company.representative_name || "", representative_phone: company.representative_phone || "", email: company.email || "", website: company.website || "", address: company.address || "", }, }); }, []); // 모달 닫기 const closeModal = useCallback(() => { setModalState((prev) => ({ ...prev, isOpen: false, selectedCompany: null, formData: { ...DEFAULT_COMPANY_FORM_DATA }, })); }, []); // 폼 데이터 변경 const updateFormData = useCallback((field: keyof CompanyFormData, value: string) => { setModalState((prev) => ({ ...prev, formData: { ...prev.formData, [field]: value, }, })); }, []); // 회사 생성 const createCompany = useCallback(async () => { if (!modalState.formData.company_name.trim()) { setError("회사명을 입력해주세요."); return false; } if (!modalState.formData.business_registration_number.trim()) { setError("사업자등록번호를 입력해주세요."); return false; } setIsLoading(true); setError(null); try { await companyAPI.create(modalState.formData); closeModal(); // 목록 다시 로드 await loadCompanies(); return true; } catch (err) { setError(err instanceof Error ? err.message : "회사 등록에 실패했습니다."); return false; } finally { setIsLoading(false); } }, [modalState.formData, closeModal, loadCompanies]); // 회사 수정 const updateCompany = useCallback(async () => { if (!modalState.selectedCompany || !modalState.formData.company_name.trim()) { setError("올바른 데이터를 입력해주세요."); return false; } if (!modalState.formData.business_registration_number.trim()) { setError("사업자등록번호를 입력해주세요."); return false; } setIsLoading(true); setError(null); try { await companyAPI.update(modalState.selectedCompany.company_code, { company_name: modalState.formData.company_name, business_registration_number: modalState.formData.business_registration_number, representative_name: modalState.formData.representative_name, representative_phone: modalState.formData.representative_phone, email: modalState.formData.email, website: modalState.formData.website, address: modalState.formData.address, status: modalState.selectedCompany.status, }); closeModal(); // 목록 다시 로드 await loadCompanies(); return true; } catch (err) { setError(err instanceof Error ? err.message : "회사 수정에 실패했습니다."); return false; } finally { setIsLoading(false); } }, [modalState.selectedCompany, modalState.formData, closeModal, loadCompanies]); // 삭제 다이얼로그 열기 const openDeleteDialog = useCallback((company: Company) => { setDeleteState({ isOpen: true, targetCompany: company, }); }, []); // 삭제 다이얼로그 닫기 const closeDeleteDialog = useCallback(() => { setDeleteState({ isOpen: false, targetCompany: null, }); }, []); // 회사 삭제 const deleteCompany = useCallback(async () => { if (!deleteState.targetCompany) return false; setIsLoading(true); setError(null); try { await companyAPI.delete(deleteState.targetCompany.company_code); closeDeleteDialog(); // 목록 다시 로드 await loadCompanies(); return true; } catch (err) { setError(err instanceof Error ? err.message : "회사 삭제에 실패했습니다."); return false; } finally { setIsLoading(false); } }, [deleteState.targetCompany, closeDeleteDialog, loadCompanies]); // 폼 저장 (등록 또는 수정) const saveCompany = useCallback(async () => { if (modalState.mode === "create") { return await createCompany(); } else { return await updateCompany(); } }, [modalState.mode, createCompany, updateCompany]); return { // 데이터 companies: filteredCompanies, searchFilter, isLoading, error, // 디스크 사용량 관련 diskUsageInfo, isDiskUsageLoading, loadDiskUsage, // 모달 상태 modalState, deleteState, // 검색 기능 updateSearchFilter, clearSearchFilter, // 모달 제어 openCreateModal, openEditModal, closeModal, updateFormData, // 삭제 다이얼로그 제어 openDeleteDialog, closeDeleteDialog, // CRUD 작업 saveCompany, deleteCompany, loadCompanies, // 외부에서 수동으로 새로고침할 때 사용 // 에러 처리 clearError: () => setError(null), }; };