import { useEffect, useMemo, useRef, useState } from "react"; import { useQueryClient } from "@tanstack/react-query"; import { buildCompDocAddressLine, createCompDocDialogActions, } from "@/app/(protected)/workorders/_hooks/create-comp-doc-dialog-actions"; import { useLocationDetail } from "@/domain/locations/use-cases/use-location-detail"; import type { CompDocData, CompDocSaveStatus, DocFields, DocState, } from "@/domain/work-orders/types/completion-doc"; import type { WorkOrderTableRow } from "@/domain/work-orders/types/work-order-table-row"; import { getMockWoWizardLocationDetail } from "@/domain/work-orders/mocks/wo-wizard-mock-data"; import { resolveCompDocSite } from "@/domain/work-orders/utils/completion-doc-site"; import { DOC_STATE_CFG, docStateOf } from "@/domain/work-orders/utils/completion-doc-state"; type UseCompDocDialogParams = { row: WorkOrderTableRow; open: boolean; data?: CompDocData; onSave: (data: CompDocData, status: CompDocSaveStatus) => void | Promise; onDateCompletedChange?: (date: string) => void | Promise; }; export function useCompDocDialog({ row, open, data, onSave, onDateCompletedChange, }: UseCompDocDialogParams) { const queryClient = useQueryClient(); const locId = String(row.locationId || ""); const isMockLocation = locId.startsWith("mock-"); const { data: apiLocationDetail } = useLocationDetail( isMockLocation || !locId ? undefined : locId, ); const locationDetail = isMockLocation ? getMockWoWizardLocationDetail(locId) : apiLocationDetail; const site = useMemo(() => resolveCompDocSite(row, locationDetail), [row, locationDetail]); const [notes, setNotes] = useState(""); const [docState, setDocState] = useState("draft"); const [generatedAt, setGeneratedAt] = useState(""); const [editDateCompleted, setEditDateCompleted] = useState(""); const [editAddress, setEditAddress] = useState(""); const seedKeyRef = useRef(null); const addressSeededRef = useRef(false); const addressTouchedRef = useRef(false); // Seed once per open/WO — row/detail refetches must not wipe in-progress edits. // Address waits for authoritative locationDetail (when a real location id exists) // and still accepts that first response without overwriting later user edits. useEffect(() => { if (!open) { seedKeyRef.current = null; addressSeededRef.current = false; addressTouchedRef.current = false; return; } const key = String(row.id); if (seedKeyRef.current !== key) { seedKeyRef.current = key; addressSeededRef.current = false; addressTouchedRef.current = false; setNotes(data?.notes ?? ""); setDocState(docStateOf(row.docStatus)); setGeneratedAt(data?.generatedAt ?? ""); setEditDateCompleted(row.completedDate || ""); } if (addressTouchedRef.current || addressSeededRef.current) { return; } const awaitingLocation = Boolean(locId) && !isMockLocation && !locationDetail; if (awaitingLocation) { return; } setEditAddress(buildCompDocAddressLine(resolveCompDocSite(row, locationDetail))); addressSeededRef.current = true; }, [open, row, data?.notes, data?.generatedAt, locationDetail, locId, isMockLocation]); const handleAddressChange = (value: string) => { addressTouchedRef.current = true; setEditAddress(value); }; const amazonRep = row.pocName || ""; const seaRep = row.tech || ""; const cfg = DOC_STATE_CFG[docState]; const isNotRequired = docState === "not-required"; const isGenerated = docState === "generated"; const effectiveStreet = editAddress.trim() || site.street; const docFields: DocFields = { street: effectiveStreet, city: site.city, state: site.state, zip: site.zip, dateCompleted: editDateCompleted, amazonRep, seaRep, }; const previewSite = useMemo( () => ({ ...site, street: effectiveStreet, fullAddress: [effectiveStreet, site.label, site.zip].filter(Boolean).join(", ") || effectiveStreet || "—", }), [site, effectiveStreet], ); const actions = createCompDocDialogActions({ row, notes, generatedAt, editDateCompleted, editAddress, docState, docFields, site, locId, isMockLocation, locationDetail, queryClient, onSave, onDateCompletedChange, setDocState, setGeneratedAt, }); return { site: previewSite, notes, setNotes, docState, generatedAt, editAddress, setEditAddress: handleAddressChange, editDateCompleted, setEditDateCompleted, amazonRep, seaRep, cfg, isNotRequired, isGenerated, ...actions, }; }