'use client'; import { useCallback, useEffect, useState } from 'react'; import { MessageCircle, X } from 'lucide-react'; import type { FulfillmentMode, InquiryBranch, InquiryPreferredDate, } from '@/domain/cart/inquiry'; import type { DeliveryInquiryDetails, PickupInquiryDetails } from '@/domain/cart/inquiry'; import { DEFAULT_INQUIRY_BRANCH, getMinInquiryTimeForToday, isInquiryBranchOnlineEnabled, validateInquirySchedule, } from '@/domain/cart/inquiry'; import type { Language } from '@/domain/language/entities'; import { getWhatsAppInquiryLanguage } from '@/application/messaging/inquiry-language'; import DeliveryAddressAutocomplete from '@/components/DeliveryAddressAutocomplete'; export interface CartInquiryModalLabels { titlePickup: string; titleDelivery: string; signedInAs: string; nameLabel: string; namePlaceholder: string; emailLabel: string; emailPlaceholder: string; emailRequired: string; branchLabel: string; branchAskim: string; branchBackaplan: string; askimOnlineUnavailable: string; addressLabel: string; addressPlaceholder: string; addressHint: string; addressFallbackPlaceholder: string; addressFallbackHint: string; addressSearching: string; addressNoResults: string; addressOutsideGothenburg: string; addressSelectSuggestion: string; addressInvalid: string; preferredDateLabel: string; preferredDatePlaceholder: string; dateToday: string; dateTomorrow: string; preferredTimeLabel: string; scheduleOptionalHint: string; submitPickup: string; submitDelivery: string; cancel: string; close: string; nameRequired: string; branchRequired: string; scheduleIncomplete: string; scheduleTooSoon: string; } interface CartInquiryModalProps { mode: FulfillmentMode; isOpen: boolean; language: Language; customerEmail: string | null; customerName: string | null; onClose: () => void; onSubmitPickup: (details: PickupInquiryDetails) => void; onSubmitDelivery: (details: DeliveryInquiryDetails) => void; labels: CartInquiryModalLabels; } function createPickupDefaults(email = '', name = ''): PickupInquiryDetails { return { name: name.trim(), email, branch: DEFAULT_INQUIRY_BRANCH, preferredDate: '', preferredTime: '', }; } function createDeliveryDefaults(email = '', name = ''): DeliveryInquiryDetails { return { ...createPickupDefaults(email, name), address: '', }; } export default function CartInquiryModal({ mode, isOpen, language, customerEmail, customerName, onClose, onSubmitPickup, onSubmitDelivery, labels, }: CartInquiryModalProps) { const [pickup, setPickup] = useState(createPickupDefaults); const [delivery, setDelivery] = useState(createDeliveryDefaults); const [errors, setErrors] = useState>({}); const [addressValid, setAddressValid] = useState(true); const autocompleteLang = getWhatsAppInquiryLanguage(language); const handleKeyDown = useCallback( (e: KeyboardEvent) => { if (e.key === 'Escape') onClose(); }, [onClose], ); useEffect(() => { if (!isOpen) return; setErrors({}); window.addEventListener('keydown', handleKeyDown); return () => window.removeEventListener('keydown', handleKeyDown); }, [isOpen, handleKeyDown]); useEffect(() => { if (!isOpen) { setPickup(createPickupDefaults()); setDelivery(createDeliveryDefaults()); setErrors({}); setAddressValid(true); return; } const email = customerEmail ?? ''; const name = customerName ?? ''; setPickup(createPickupDefaults(email, name)); setDelivery(createDeliveryDefaults(email, name)); setErrors({}); setAddressValid(true); }, [isOpen, customerEmail, customerName]); if (!isOpen) return null; const title = mode === 'pickup' ? labels.titlePickup : labels.titleDelivery; const submitLabel = mode === 'pickup' ? labels.submitPickup : labels.submitDelivery; const formState = mode === 'pickup' ? pickup : delivery; const branch = formState.branch; const preferredDate = formState.preferredDate; const preferredTime = formState.preferredTime; const isAskimBlocked = branch === 'askim'; const isSubmitDisabled = !isInquiryBranchOnlineEnabled(branch); const minTimeToday = getMinInquiryTimeForToday(); const emailLocked = Boolean(customerEmail); const setName = (value: string) => { if (mode === 'pickup') setPickup((p) => ({ ...p, name: value })); else setDelivery((d) => ({ ...d, name: value })); if (errors.name) setErrors((err) => ({ ...err, name: '' })); }; const setEmail = (value: string) => { if (emailLocked) return; if (mode === 'pickup') setPickup((p) => ({ ...p, email: value })); else setDelivery((d) => ({ ...d, email: value })); if (errors.email) setErrors((err) => ({ ...err, email: '' })); }; const setBranch = (value: InquiryBranch) => { if (mode === 'pickup') setPickup((p) => ({ ...p, branch: value })); else setDelivery((d) => ({ ...d, branch: value })); if (errors.branch) setErrors((err) => ({ ...err, branch: '' })); }; const setPreferredDate = (value: InquiryPreferredDate) => { if (mode === 'pickup') { setPickup((p) => ({ ...p, preferredDate: value })); } else { setDelivery((d) => ({ ...d, preferredDate: value })); } if (errors.schedule) setErrors((err) => ({ ...err, schedule: '' })); }; const setPreferredTime = (value: string) => { if (mode === 'pickup') { setPickup((p) => ({ ...p, preferredTime: value })); } else { setDelivery((d) => ({ ...d, preferredTime: value })); } if (errors.schedule) setErrors((err) => ({ ...err, schedule: '' })); }; const validateSchedule = (state: PickupInquiryDetails): boolean => { const result = validateInquirySchedule(state); if (result === 'ok') return true; if (result === 'incomplete') { setErrors((err) => ({ ...err, schedule: labels.scheduleIncomplete })); } else if (result === 'too_soon' || result === 'invalid_time') { setErrors((err) => ({ ...err, schedule: labels.scheduleTooSoon })); } return false; }; const handleSubmit = (e: React.FormEvent) => { e.preventDefault(); const nextErrors: Record = {}; if (mode === 'pickup') { if (!pickup.name.trim()) nextErrors.name = labels.nameRequired; if (!pickup.email.trim()) nextErrors.email = labels.emailRequired; if (!pickup.branch) nextErrors.branch = labels.branchRequired; if (Object.keys(nextErrors).length) { setErrors(nextErrors); return; } if (!validateSchedule(pickup)) return; if (!isInquiryBranchOnlineEnabled(pickup.branch)) return; onSubmitPickup(pickup); return; } if (!delivery.name.trim()) nextErrors.name = labels.nameRequired; if (!delivery.email.trim()) nextErrors.email = labels.emailRequired; if (!delivery.branch) nextErrors.branch = labels.branchRequired; if (delivery.address.trim() && !addressValid) { nextErrors.address = labels.addressInvalid; } if (Object.keys(nextErrors).length) { setErrors(nextErrors); return; } if (!validateSchedule(delivery)) return; if (!isInquiryBranchOnlineEnabled(delivery.branch)) return; onSubmitDelivery(delivery); }; const inputClass = 'mt-1.5 w-full min-h-[48px] rounded-xl border border-[#EDE6D9] bg-[#FFFCF7] px-3 py-3 text-base text-[#2C2A26] placeholder:text-[#8A8478] focus:border-[#c99a2e] focus:ring-2 focus:ring-[#c99a2e]/20 touch-manipulation'; return ( <>
e.stopPropagation()} >

{title}

{customerEmail && (
{customerEmail.charAt(0).toUpperCase()}

{labels.signedInAs}

{customerEmail}

)}
setName(e.target.value)} placeholder={labels.namePlaceholder} className={inputClass} autoComplete="name" /> {errors.name && (

{errors.name}

)}
setEmail(e.target.value)} placeholder={labels.emailPlaceholder} readOnly={emailLocked} className={`${inputClass} ${emailLocked ? 'bg-[#F8F5F0]/80 text-[#6B665F] cursor-default' : ''}`} autoComplete="email" /> {errors.email && (

{errors.email}

)}
{errors.branch && (

{errors.branch}

)} {isAskimBlocked && (

{labels.askimOnlineUnavailable}

)}
{mode === 'delivery' && (
setDelivery((d) => ({ ...d, address }))} onValidationChange={setAddressValid} language={autocompleteLang} labels={{ placeholder: labels.addressPlaceholder, hint: labels.addressHint, fallbackPlaceholder: labels.addressFallbackPlaceholder, fallbackHint: labels.addressFallbackHint, searching: labels.addressSearching, noResults: labels.addressNoResults, outsideGothenburg: labels.addressOutsideGothenburg, selectSuggestion: labels.addressSelectSuggestion, }} inputClassName={inputClass} /> {errors.address && (

{errors.address}

)}
)}

{labels.scheduleOptionalHint}

setPreferredTime(e.target.value)} min={preferredDate === 'today' ? minTimeToday : undefined} className={inputClass} />
{errors.schedule && (

{errors.schedule}

)}
); }