import type { SurveyBasicInfo, SurveyDetailRequest, SurveyRegistRequest } from '@/types/Survey' import { useMemo, useEffect } from 'react' import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query' import { useSurveyFilterStore } from '@/store/surveyFilterStore' import { useSessionStore } from '@/store/session' import { useAxios } from './useAxios' import { queryStringFormatter } from '@/utils/common-utils' import { useRouter } from 'next/navigation' export const requiredFields = [ { field: 'installationSystem', name: '設置希望システム', }, { field: 'constructionYear', name: '建築年数', }, { field: 'rafterSize', name: '垂木サイズ', }, { field: 'rafterPitch', name: '垂木傾斜', }, { field: 'waterproofMaterial', name: '防水材', }, { field: 'insulationPresence', name: '断熱材有無', }, { field: 'structureOrder', name: '屋根構造の順序', }, ] interface ZipCodeResponse { status: number message: string | null results: ZipCode[] | null } type ZipCode = { zipcode: string prefcode: string address1: string address2: string address3: string kana1: string kana2: string kana3: string } export function useSurvey(id?: number): { surveyList: { data: SurveyBasicInfo[]; count: number } | {} surveyDetail: SurveyBasicInfo | null isLoadingSurveyList: boolean isLoadingSurveyDetail: boolean isCreatingSurvey: boolean isUpdatingSurvey: boolean isDeletingSurvey: boolean isSubmittingSurvey: boolean createSurvey: (survey: SurveyRegistRequest) => Promise updateSurvey: ({ survey, isTemporary, storeId }: { survey: SurveyRegistRequest; isTemporary: boolean; storeId?: string }) => void deleteSurvey: () => Promise submitSurvey: (params: { targetId?: string | null; targetNm?: string | null }) => void validateSurveyDetail: (surveyDetail: SurveyDetailRequest) => string getZipCode: (zipCode: string) => Promise refetchSurveyList: () => void } { const queryClient = useQueryClient() const { keyword, searchOption, isMySurvey, sort, offset } = useSurveyFilterStore() const { session } = useSessionStore() const { axiosInstance } = useAxios() const router = useRouter() const { data: surveyListData, isLoading: isLoadingSurveyList, refetch: refetchSurveyList, } = useQuery({ queryKey: ['survey', 'list', keyword, searchOption, isMySurvey, sort, offset, session?.storeNm, session?.builderNo, session?.role], queryFn: async () => { const resp = await axiosInstance(null).get<{ data: SurveyBasicInfo[]; count: number }>('/api/survey-sales', { params: { keyword, searchOption, isMySurvey, sort, offset, storeId: session?.storeId, builderNo: session?.builderNo, role: session?.role, }, }) return resp.data }, enabled: session?.isLoggedIn, }) const surveyData = useMemo(() => { if (!surveyListData) return { count: 0, data: [] } return { ...surveyListData, } }, [surveyListData]) const { data: surveyDetail, isLoading: isLoadingSurveyDetail } = useQuery({ queryKey: ['survey', id], queryFn: async () => { if (!session?.isLoggedIn || id === 0 || id === undefined) return null try { const resp = await axiosInstance(null).get(`/api/survey-sales/${id}`, { params: { role: session?.role, storeId: session?.storeId, builderNo: session?.builderNo, isLoggedIn: session?.isLoggedIn, }, }) return resp.data } catch (error: any) { alert(error.response?.data.error) router.replace('/survey-sale') return null } }, enabled: id !== 0 && id !== undefined && session?.isLoggedIn, }) const { mutateAsync: createSurvey, isPending: isCreatingSurvey } = useMutation({ mutationFn: async (survey: SurveyRegistRequest) => { const resp = await axiosInstance(null).post('/api/survey-sales', { survey: survey, storeId: session?.storeId ?? null, role: session?.role ?? null, }) return resp.data.id ?? 0 }, onSuccess: (data) => { queryClient.invalidateQueries({ queryKey: ['survey', 'list'] }) queryClient.invalidateQueries({ queryKey: ['survey', id] }) return data }, }) const { mutate: updateSurvey, isPending: isUpdatingSurvey } = useMutation({ mutationFn: async ({ survey, isTemporary, storeId }: { survey: SurveyRegistRequest; isTemporary: boolean; storeId?: string }) => { if (id === undefined) throw new Error('id is required') const resp = await axiosInstance(null).put(`/api/survey-sales/${id}`, { survey: survey, isTemporary: isTemporary, storeId: storeId, role: session?.role ?? null, }) return resp.data }, onSuccess: () => { queryClient.invalidateQueries({ queryKey: ['survey', id] }) queryClient.invalidateQueries({ queryKey: ['survey', 'list'] }) }, }) const { mutateAsync: deleteSurvey, isPending: isDeletingSurvey } = useMutation({ mutationFn: async () => { if (id === null) throw new Error('id is required') const resp = await axiosInstance(null).delete(`/api/survey-sales/${id}`) return resp.data }, onSuccess: () => { queryClient.invalidateQueries({ queryKey: ['survey', 'list'] }) queryClient.invalidateQueries({ queryKey: ['survey', id] }) }, }) const { mutateAsync: submitSurvey, isPending: isSubmittingSurvey } = useMutation({ mutationFn: async ({ targetId, targetNm }: { targetId?: string | null; targetNm?: string | null }) => { if (!id) throw new Error('id is required') const resp = await axiosInstance(null).patch(`/api/survey-sales/${id}`, { targetId, targetNm, }) return resp.data }, onSuccess: () => { queryClient.invalidateQueries({ queryKey: ['survey', 'list'] }) queryClient.invalidateQueries({ queryKey: ['survey', id] }) }, }) const validateSurveyDetail = (surveyDetail: SurveyDetailRequest) => { // 상수 정의 const ETC_FIELDS = ['installationSystem', 'rafterSize', 'rafterPitch', 'waterproofMaterial', 'structureOrder'] as const const SPECIAL_CONDITIONS = ['constructionYear', 'insulationPresence'] as const // 유틸리티 함수들 const isEmptyValue = (value: any): boolean => { return value === null || value?.toString().trim() === '' } const checkRequiredField = (field: string): string => { if (ETC_FIELDS.includes(field as (typeof ETC_FIELDS)[number])) { if ( isEmptyValue(surveyDetail[field as keyof SurveyDetailRequest]) && isEmptyValue(surveyDetail[`${field}Etc` as keyof SurveyDetailRequest]) ) { return field } } else if (SPECIAL_CONDITIONS.includes(field as (typeof SPECIAL_CONDITIONS)[number])) { if (surveyDetail[field as keyof SurveyDetailRequest] === '2' && isEmptyValue(surveyDetail[`${field}Etc` as keyof SurveyDetailRequest])) { return `${field}Etc` } else if (isEmptyValue(surveyDetail[field as keyof SurveyDetailRequest])) { return field } } return '' } // 필수 필드 체크 const emptyField = requiredFields.find((field) => checkRequiredField(field.field)) if (emptyField) return emptyField.field // 계약 용량 단위 체크 const contractCapacity = surveyDetail.contractCapacity if (contractCapacity?.trim() && contractCapacity.split(' ').length === 1) { return 'contractCapacityUnit' } return '' } const getZipCode = async (zipCode: string): Promise => { try { const { data } = await axiosInstance(null).get( `https://zipcloud.ibsnet.co.jp/api/search?${queryStringFormatter({ zipcode: zipCode.trim() })}`, ) return data.results } catch (e) { console.error('Failed to fetch zipcode data:', e) throw new Error('Failed to fetch zipcode data') } } return { surveyList: surveyData.data, surveyDetail: surveyDetail as SurveyBasicInfo | null, isLoadingSurveyList, isLoadingSurveyDetail, isCreatingSurvey, isUpdatingSurvey, isDeletingSurvey, isSubmittingSurvey, createSurvey, updateSurvey, deleteSurvey, submitSurvey, validateSurveyDetail, getZipCode, refetchSurveyList, } }