import { useMemo, useState } from "react"; import type { DispatchDetail } from "@/domain/work-orders/types/work-order"; import { useDispatchUpliftController } from "@/app/(protected)/workorders/_hooks/use-dispatch-uplift-controller"; import { useDispatchDetail } from "@/domain/work-orders/use-cases/use-work-order-detail"; import { useAddChecklistItem, useAddDispatchComment, useAddDispatchSignoff, useUpdateChecklistItem, useUpdateDispatch, useVerifyDispatch, } from "@/domain/work-orders/use-cases/use-work-order-mutations"; import { isDispatchLocked } from "@/domain/work-orders/utils/is-dispatch-locked"; import { useAuthContext } from "@/providers/auth-context"; import { toDateInputValue } from "@/lib/time-utils"; import { buildDispatchEditForm } from "@/app/(protected)/workorders/_components/dispatch/dispatch-detail/build-dispatch-edit-form"; import type { DispatchEditFormState } from "@/app/(protected)/workorders/_components/dispatch/dispatch-detail/dispatch-edit-form"; function buildVerifyState(dispatch?: DispatchDetail) { if (!dispatch) { return { canVerify: false, missing: [] as string[] }; } const checklistTotal = dispatch.checklistItems.length; const checklistDone = dispatch.checklistItems.filter((item) => item.isCompleted).length; const signoffTypes = new Set(dispatch.signoffs.map((signoff) => signoff.signoffType)); const missing: string[] = []; if (checklistDone < checklistTotal) { missing.push(`${checklistTotal - checklistDone} checklist item(s)`); } if (!signoffTypes.has("Customer")) { missing.push("Customer sign-off"); } if (!signoffTypes.has("Vendor")) { missing.push("Vendor sign-off"); } return { missing, canVerify: missing.length === 0 && (checklistTotal > 0 || dispatch.signoffs.length >= 2), }; } export function useDispatchDetailController( dispatchId: string | number, workOrderId: string | number, ) { const { user } = useAuthContext(); const { data: dispatch, isLoading, isFetching, refetch } = useDispatchDetail(dispatchId); const uplift = useDispatchUpliftController(dispatchId); const [editing, setEditing] = useState(false); const [form, setForm] = useState({ status: "", nteAmount: "", scheduledDate: "", completedDate: "", description: "", }); const [newChecklistItem, setNewChecklistItem] = useState(""); const [commentText, setCommentText] = useState(""); const [sendEmail, setSendEmail] = useState(true); const [sigCaptureType, setSigCaptureType] = useState(null); const updateDispatchMutation = useUpdateDispatch(dispatchId, workOrderId); const addCommentMutation = useAddDispatchComment(dispatchId); const updateChecklistMutation = useUpdateChecklistItem(dispatchId); const addChecklistMutation = useAddChecklistItem(dispatchId); const addSignoffMutation = useAddDispatchSignoff(dispatchId); const verifyMutation = useVerifyDispatch(dispatchId, workOrderId); const userName = (typeof user?.name === "string" ? user.name : undefined) ?? (typeof user?.fullname === "string" ? user.fullname : undefined) ?? "User"; const isLocked = dispatch ? isDispatchLocked(dispatch) : false; const verifyState = useMemo(() => buildVerifyState(dispatch), [dispatch]); const beginEditing = () => { if (dispatch) { setForm(buildDispatchEditForm(dispatch)); } setEditing(true); }; const handleSave = () => { updateDispatchMutation.mutate( { id: dispatchId, status: form.status, nteAmount: form.nteAmount ? parseFloat(form.nteAmount) : null, scheduledDate: form.scheduledDate || null, completedDate: form.completedDate || null, description: form.description, }, { onSuccess: () => setEditing(false) }, ); }; const handleCancelDispatch = (current: DispatchDetail) => { if (!window.confirm("Are you sure you want to cancel this dispatch?")) { return; } updateDispatchMutation.mutate({ id: dispatchId, status: "Cancelled", nteAmount: current.nteAmount, scheduledDate: toDateInputValue(current.scheduledDate) || null, completedDate: toDateInputValue(current.completedDate) || null, description: current.description, }); }; const handleComment = (event: React.FormEvent) => { event.preventDefault(); if (!commentText.trim()) { return; } addCommentMutation.mutate( { text: commentText.trim(), sendEmail }, { onSuccess: () => setCommentText("") }, ); }; const isMutating = updateDispatchMutation.isPending || addCommentMutation.isPending || updateChecklistMutation.isPending || addChecklistMutation.isPending || addSignoffMutation.isPending || verifyMutation.isPending || uplift.isMutating; return { dispatch, isLoading, isFetching, refetch, uplifts: uplift.uplifts, isLoadingUplifts: uplift.isLoadingUplifts, editing, form, setForm, newChecklistItem, setNewChecklistItem, commentText, setCommentText, sendEmail, setSendEmail, sigCaptureType, setSigCaptureType, upliftAction: uplift.upliftAction, setUpliftAction: uplift.setUpliftAction, isLocked, isMutating, userName, verifyState, beginEditing, handleSave, handleCancelDispatch, handleComment, handleUpliftConfirm: uplift.handleUpliftConfirm, setEditing, updateDispatchMutation, updateChecklistMutation, addChecklistMutation, addSignoffMutation, verifyMutation, approveUpliftMutation: uplift.approveUpliftMutation, rejectUpliftMutation: uplift.rejectUpliftMutation, requestChangesUpliftMutation: uplift.requestChangesUpliftMutation, addCommentMutation, }; } export type DispatchDetailController = ReturnType;