import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query' import type { SurveyBasicInfo, SurveyDetailInfo, SurveyDetailRequest, SurveyDetailCoverRequest, SurveyRegistRequest, } from '@/types/Survey' import { axiosInstance } from '@/libs/axios' import { useSurveyFilterStore } from '@/store/surveyFilterStore' import { queryStringFormatter } from '@/utils/common-utils' import { useSessionStore } from '@/store/session' const requiredFields = [ { field: 'INSTALLATION_SYSTEM', name: '設置希望システム', }, { field: 'CONSTRUCTION_YEAR', name: '建築年数', }, { field: 'RAFTER_SIZE', name: '垂木サイズ', }, { field: 'RAFTER_PITCH', name: '垂木傾斜', }, { field: 'WATERPROOF_MATERIAL', name: '防水材', }, { field: 'INSULATION_PRESENCE', name: '断熱材有無', }, { field: 'STRUCTURE_ORDER', 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 useServey(id?: number): { surveyList: SurveyBasicInfo[] | [] surveyDetail: SurveyBasicInfo | null surveyListCount: number isLoadingSurveyList: boolean isLoadingSurveyDetail: boolean isCreatingSurvey: boolean isUpdatingSurvey: boolean isDeletingSurvey: boolean createSurvey: (survey: SurveyRegistRequest) => Promise createSurveyDetail: (params: { surveyId: number; surveyDetail: SurveyDetailCoverRequest }) => void updateSurvey: (survey: SurveyRegistRequest) => void deleteSurvey: () => Promise submitSurvey: () => void validateSurveyDetail: (surveyDetail: SurveyDetailRequest) => string getZipCode: (zipCode: string) => Promise } { const queryClient = useQueryClient() const { keyword, searchOption, isMySurvey, sort, offset } = useSurveyFilterStore() const { session } = useSessionStore() const { data: surveyList, isLoading: isLoadingSurveyList } = useQuery({ queryKey: ['survey', 'list', keyword, searchOption, isMySurvey, sort, offset, session?.storeNm, session?.builderNo, session?.role], queryFn: async () => { const resp = await axiosInstance(null).get('/api/survey-sales', { params: { keyword, searchOption, isMySurvey, sort, offset, store: session?.storeNm, builderNo: session?.builderNo, role: session?.role, }, }) return resp.data }, }) const { data: surveyDetail, isLoading: isLoadingSurveyDetail } = useQuery({ queryKey: ['survey', id], queryFn: async () => { if (id === undefined) throw new Error('id is required') if (id === null) return null const resp = await axiosInstance(null).get(`/api/survey-sales/${id}`) return resp.data }, enabled: id !== undefined, }) const { data: surveyListCount } = useQuery({ queryKey: ['survey', 'list', keyword, searchOption, isMySurvey, sort, session?.builderNo, session?.storeNm, session?.role], queryFn: async () => { const resp = await axiosInstance(null).get('/api/survey-sales', { params: { keyword, searchOption, isMySurvey, sort, builderNo: session?.builderNo, store: session?.storeNm, role: session?.role, }, }) return resp.data }, }) const { mutateAsync: createSurvey, isPending: isCreatingSurvey } = useMutation({ mutationFn: async (survey: SurveyRegistRequest) => { const resp = await axiosInstance(null).post('/api/survey-sales', survey) 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: SurveyRegistRequest) => { if (id === undefined) throw new Error('id is required') const resp = await axiosInstance(null).put(`/api/survey-sales/${id}`, survey) 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: createSurveyDetail } = useMutation({ mutationFn: async ({ surveyId, surveyDetail }: { surveyId: number; surveyDetail: SurveyDetailCoverRequest }) => { const resp = await axiosInstance(null).patch(`/api/survey-sales/${surveyId}`, surveyDetail) return resp.data }, onSuccess: () => { queryClient.invalidateQueries({ queryKey: ['survey', 'list'] }) queryClient.invalidateQueries({ queryKey: ['survey', id] }) }, }) const { mutateAsync: submitSurvey } = useMutation({ mutationFn: async () => { if (id === undefined) throw new Error('id is required') const resp = await axiosInstance(null).patch(`/api/survey-sales/${id}`, { submit: true, }) return resp.data }, onSuccess: () => { queryClient.invalidateQueries({ queryKey: ['survey', 'list'] }) queryClient.invalidateQueries({ queryKey: ['survey', id] }) }, }) const validateSurveyDetail = (surveyDetail: SurveyDetailRequest) => { const etcFields = ['INSTALLATION_SYSTEM', 'CONSTRUCTION_YEAR', 'RAFTER_SIZE', 'RAFTER_PITCH', 'WATERPROOF_MATERIAL', 'STRUCTURE_ORDER'] as const const emptyField = requiredFields.find((field) => { if (etcFields.includes(field.field as (typeof etcFields)[number])) { return ( surveyDetail[field.field as keyof SurveyDetailRequest] === null && surveyDetail[`${field.field}_ETC` as keyof SurveyDetailRequest] === '' ) } else { return surveyDetail[field.field as keyof SurveyDetailRequest] === null } }) const contractCapacity = surveyDetail.CONTRACT_CAPACITY if (contractCapacity && contractCapacity.trim() !== '' && contractCapacity.split(' ')?.length === 1) { return 'CONTRACT_CAPACITY_UNIT' } return emptyField?.name || '' } 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: surveyList || [], surveyDetail: surveyDetail || null, surveyListCount: surveyListCount || 0, isLoadingSurveyList, isLoadingSurveyDetail, isCreatingSurvey, isUpdatingSurvey, isDeletingSurvey, createSurvey, updateSurvey, deleteSurvey, createSurveyDetail, submitSurvey, validateSurveyDetail, getZipCode, } }