/* SER-OS — Add-On Items screen
   ──────────────────────────────────────────────────────────────────
   Odoo-style operational picker:
     - Focus on search field → shows "Recently Used" + "Suggested"
       sections immediately (no typing required)
     - Typing replaces those sections with filtered matches
     - Selecting an item adds it instantly + tracks it as recently
       used (localStorage, per-FD-friendly)
     - Each item carries a glyph fallback so the UI feels visual
       even without real product photos
   */

const SUGGEST_LIMIT = 8;

function AddOnScreen({
  caseDetails, selectedPackage, selectedCasket,
  serviceData,
  selectedAddOns, setSelectedAddOns,
  onBack, onContinue, onEditCase, onJumpTo, notes, setNotes,
  confirmationStatus, onSendForConfirmation, onViewPdf, onResend, onEditArrangement,
  amendmentSnapshot, onEnterEditMode, onFinalizeAmendment, onDiscardAmendment, onSendToCustomer,
  onSimulateSign, onSendSignedForm,
  caseVersionHistory = [],
  appliedCoupon = null, onApplyCoupon, onRemoveCoupon,
}) {
  const [q, setQ]              = React.useState("");
  const [showDropdown, setSD]  = React.useState(false);
  const [category, setCategory] = React.useState("All");
  const [zoomItem, setZoomItem] = React.useState(null);
  const [configuringItem, setConfiguringItem] = React.useState(null);
  const [editingItem,     setEditingItem]     = React.useState(null);
  const searchRef = React.useRef(null);
  const searchInputRef = React.useRef(null);

  /* ── Drag-and-drop reorder state ──────────────────────────────── */
  const [dragId,     setDragId]     = React.useState(null);
  const [dragOverId, setDragOverId] = React.useState(null);

  React.useEffect(() => {
    const onClick = (e) => {
      if (searchRef.current && !searchRef.current.contains(e.target)) setSD(false);
    };
    const onEsc = (e) => { if (e.key === "Escape") setSD(false); };
    document.addEventListener("mousedown", onClick);
    document.addEventListener("keydown", onEsc);
    return () => {
      document.removeEventListener("mousedown", onClick);
      document.removeEventListener("keydown", onEsc);
    };
  }, []);

  const isAmendmentDraft = confirmationStatus === "amendment_draft";
  const isReadOnly = confirmationStatus === "confirmed"
    || confirmationStatus === "confirmed_updated"
    || confirmationStatus === "awaiting"
    || confirmationStatus === "amended_awaiting";

  const term = q.trim().toLowerCase();

  /* Available items honouring the active category — duplicates allowed. */
  const inCategory = (item) => category === "All" || item.category === category;
  const isAvailable = (item) => inCategory(item);

  /* Search results (only used when there's a query). */
  const searchHits = ADDON_ITEMS.filter((item) => {
    if (!isAvailable(item)) return false;
    if (!term) return true;
    const hay = `${item.name} ${item.category} ${(item.keywords || []).join(" ")}`.toLowerCase();
    return hay.includes(term);
  });

  /* Suggestions shown when the search box is focused but empty. */
  const suggestedItems = ADDON_ITEMS
    .filter((it) => it.suggested && isAvailable(it))
    .slice(0, SUGGEST_LIMIT);

  const addItem = (item) => {
    if (item.chargeType === "complimentary") {
      setSelectedAddOns([...selectedAddOns, { ...item, _uid: item.id + "-" + Date.now(), quantity: 1 }]);
      setQ("");
      setSD(true);
    } else {
      setConfiguringItem(item);
      setQ("");
      setSD(false);
    }
  };

  const confirmAddItem = ({ quantity, rentalDays }) => {
    const item = configuringItem;
    setSelectedAddOns([...selectedAddOns, {
      ...item,
      _uid: item.id + "-" + Date.now(),
      quantity,
      ...(rentalDays !== undefined ? { rentalDays } : {}),
    }]);
    setConfiguringItem(null);
  };

  const confirmEditItem = ({ quantity, rentalDays }) => {
    const uid = editingItem.uid;
    setSelectedAddOns(selectedAddOns.map((it) =>
      (it._uid || it.id) === uid
        ? { ...it, quantity, ...(rentalDays !== undefined ? { rentalDays } : {}) }
        : it
    ));
    setEditingItem(null);
  };
  const updateQty = (uid, delta) => {
    setSelectedAddOns(selectedAddOns.map((it) => {
      if ((it._uid || it.id) !== uid) return it;
      return { ...it, quantity: Math.max(it.minQuantity || 1, it.quantity + delta) };
    }));
  };
  const setQty = (uid, val) => {
    setSelectedAddOns(selectedAddOns.map((it) =>
      (it._uid || it.id) === uid ? { ...it, quantity: val } : it
    ));
  };
  const removeItem = (uid) => setSelectedAddOns(selectedAddOns.filter((it) => (it._uid || it.id) !== uid));
  /* moveItem kept for keyboard-fallback paths; drag-drop uses reorderItems */
  const reorderItems = (fromUid, toUid) => {
    if (!fromUid || fromUid === toUid) return;
    const arr = [...selectedAddOns];
    const fromIdx = arr.findIndex((x) => (x._uid || x.id) === fromUid);
    const toIdx   = arr.findIndex((x) => (x._uid || x.id) === toUid);
    if (fromIdx < 0 || toIdx < 0) return;
    const [moved] = arr.splice(fromIdx, 1);
    arr.splice(toIdx, 0, moved);
    setSelectedAddOns(arr);
  };

  /* Returns event-handler props for drag-over/drop on a target row */
  const rowDragHandlers = (uid) => ({
    onDragOver:  (e) => { e.preventDefault(); if (dragId && dragId !== uid) setDragOverId(uid); },
    onDragLeave: (e) => { if (!e.currentTarget.contains(e.relatedTarget)) setDragOverId(null); },
    onDrop: (e) => {
      e.preventDefault();
      reorderItems(dragId, uid);
      setDragId(null);
      setDragOverId(null);
    },
  });

  /* Drag-indicator styles for a row */
  const rowDragStyle = (uid) => ({
    opacity:    dragId === uid ? 0.4 : 1,
    boxShadow:  dragOverId === uid && dragId !== uid ? "inset 0 2px 0 0 #1F3A60" : "none",
    transition: "opacity 100ms, box-shadow 80ms",
  });

  /* Section / Note insertion (amendment_draft only) */
  const setItemName = (uid, name) => {
    setSelectedAddOns(selectedAddOns.map((it) =>
      (it._uid || it.id) === uid ? { ...it, name } : it
    ));
  };
  const addSection = () => {
    const id = "sec-" + Date.now();
    setSelectedAddOns([...selectedAddOns, {
      id, _uid: id, name: "New Section", itemType: "section", quantity: 1,
      unitPrice: 0, chargeType: "complimentary", category: "—",
    }]);
  };
  const addNote = () => {
    const id = "note-" + Date.now();
    setSelectedAddOns([...selectedAddOns, {
      id, _uid: id, name: "", itemType: "note", quantity: 1,
      unitPrice: 0, chargeType: "complimentary", category: "—",
    }]);
  };

  const subtotal = (it) => {
    if (it.chargeType === "complimentary" || it.itemType === "section" || it.itemType === "note") return 0;
    const rentalDays = it.rentalDays || 1;
    return it.unitPrice * it.quantity * rentalDays;
  };
  const addOnTotal = selectedAddOns.reduce((s, it) => s + subtotal(it), 0);

  const colTemplate = "56px 2fr 1fr 1.1fr 1.2fr 1fr 32px 40px";

  return (
    <div style={{ display: "flex", alignItems: "stretch", minHeight: "calc(100vh - 84px)" }}>
      <main style={{ flex: 1, padding: "24px 40px 64px", background: "#FAFAFA", overflowY: "auto" }}>
        <div style={{ maxWidth: 1280, margin: "0 auto", display: "flex", flexDirection: "column", gap: 20 }}>
          {!isAmendmentDraft && (
            <button onClick={onBack} style={{
              background: "transparent", border: "none", padding: 0, cursor: "pointer",
              fontFamily: "inherit", fontSize: 13, color: "#6B7A8F", alignSelf: "flex-start",
              display: "inline-flex", alignItems: "center", gap: 6,
            }}>
              <SerIcons.ArrowLeft size={18} />Back to Casket Selection
            </button>
          )}

          {/* ── Status banners ──────────────────────────────────────────── */}
          {(confirmationStatus === "confirmed" || confirmationStatus === "confirmed_updated") && (
            <div style={{
              display: "flex", alignItems: "center", justifyContent: "space-between", gap: 12,
              padding: "12px 16px", borderRadius: 10,
              background: "#EAF2E3", border: "1px solid #C4D9B8",
            }}>
              <div style={{ display: "flex", alignItems: "center", gap: 10 }}>
                <SerIcons.CheckCircle size={18} color="#5B7D4F" />
                <span style={{ fontSize: 14, fontWeight: 500, color: "#5B7D4F", letterSpacing: "-0.15px" }}>
                  {confirmationStatus === "confirmed_updated"
                    ? "Confirmed (Updated) — this arrangement has been re-confirmed by the customer."
                    : "Confirmed — this arrangement has been signed and confirmed by the customer."}
                </span>
              </div>
              {onEnterEditMode && (
                <Button variant="outline" size="sm" icon={<SerIcons.Edit size={16} />} onClick={onEnterEditMode}
                  style={{ flexShrink: 0, borderColor: "#9CAE82", color: "#5B7D4F" }}>
                  Enter Edit Mode
                </Button>
              )}
            </div>
          )}

          {isAmendmentDraft && (
            <div style={{
              display: "flex", alignItems: "center", justifyContent: "space-between", gap: 12,
              padding: "12px 16px", borderRadius: 10,
              background: "#E8EDF5", border: "1px solid #B8C8E0",
            }}>
              <div style={{ display: "flex", alignItems: "center", gap: 10 }}>
                <SerIcons.Edit size={16} color="#2D4E7D" />
                <span style={{ fontSize: 14, fontWeight: 500, color: "#2D4E7D", letterSpacing: "-0.15px" }}>
                  Amendment Draft — editing a previously confirmed arrangement. Discounts, sections, and notes can be applied.
                </span>
              </div>
            </div>
          )}

          {(confirmationStatus === "awaiting" || confirmationStatus === "amended_awaiting") && (
            <div style={{
              padding: "12px 16px", borderRadius: 10,
              background: "#FDF4E3", border: "1px solid #E8C98A",
              display: "flex", alignItems: "center", gap: 10,
            }}>
              <SerIcons.Clock size={18} color="#9A6B1F" />
              <span style={{ fontSize: 14, fontWeight: 500, color: "#9A6B1F", letterSpacing: "-0.15px" }}>
                {confirmationStatus === "amended_awaiting"
                  ? "Amendment sent — awaiting customer re-confirmation via Odoo."
                  : "Awaiting customer confirmation — the Service Summary Form has been sent via Odoo."}
              </span>
            </div>
          )}

          <header>
            <h1 style={{ font: "500 24px/32px Inter", letterSpacing: "0.07px", color: "#1F3A60", margin: 0 }}>Add-on Items</h1>
            <p style={{ fontSize: 14, color: "#6B7A8F", letterSpacing: "-0.15px", margin: "4px 0 0" }}>
              {isReadOnly
                ? "This arrangement is locked. Enter Edit Mode to make amendments."
                : isAmendmentDraft
                ? "Amendment mode — you may add items, discounts, section headers, or note lines."
                : "Search or browse to add items. Use Section to group lines, and Note to add remarks."}
            </p>
          </header>

          {/* Search row — hidden in read-only states */}
          {!isReadOnly && (
            <div ref={searchRef} style={{ position: "relative", display: "flex", gap: 10, alignItems: "stretch" }}>
              <CategorySelect value={category} onChange={setCategory} options={ADDON_CATEGORIES} />
              <div ref={searchInputRef} style={{ flex: 1, position: "relative" }}>
                <Input
                  icon={<SerIcons.Search size={18} />}
                  value={q}
                  onChange={(e) => { setQ(e.target.value); setSD(true); }}
                  onFocus={() => setSD(true)}
                  placeholder={
                    category === "All"
                      ? "Search add-on items, or click to see suggestions…"
                      : `Search within ${category}…`
                  }
                />
                {showDropdown && (
                  <AddonSearchDropdown
                    term={term} category={category}
                    searchHits={searchHits} suggested={suggestedItems}
                    onPick={addItem}
                    anchorRef={searchInputRef}
                  />
                )}
              </div>
              {/* Section + Note — available in all non-readonly draft states (like Odoo) */}
              <Button variant="outline" size="lg" style={{ height: 48, flexShrink: 0, gap: 7 }}
                icon={<SerIcons.Document size={18} />} onClick={addSection}>
                Section
              </Button>
              <Button variant="outline" size="lg" style={{ height: 48, flexShrink: 0, gap: 7 }}
                icon={<SerIcons.Edit size={18} />} onClick={addNote}>
                Note
              </Button>
            </div>
          )}

          {/* Selected items table */}
          {selectedAddOns.length === 0 ? (
            <div style={{
              background: "#FFFFFF", border: "1px dashed #D1D5DB", borderRadius: 12,
              padding: "60px 20px", textAlign: "center",
            }}>
              <div style={{ width: 56, height: 56, borderRadius: "50%", background: "#EFE7D4", margin: "0 auto 16px", display: "flex", alignItems: "center", justifyContent: "center", color: "#9CA8B8" }}>
                <SerIcons.Box size={24} />
              </div>
              <div style={{ fontSize: 15, fontWeight: 500, color: "#1F3A60", marginBottom: 4 }}>No add-on items yet</div>
              <div style={{ fontSize: 13, color: "#6B7A8F" }}>
                {isReadOnly ? "No add-on items were included in this arrangement." : "Search above or pick a category to begin"}
              </div>
            </div>
          ) : (
            <div style={{ background: "#FFFFFF", border: "1px solid #E5E7EB", borderRadius: 12, overflow: "hidden" }}>
              {/* Table header */}
              <div style={{
                display: "grid", gridTemplateColumns: colTemplate,
                padding: "12px 20px", background: "#CCD6E1", borderBottom: "1px solid #E5E7EB",
                fontSize: 11, color: "#6B7A8F", fontWeight: 500, textTransform: "uppercase", letterSpacing: "0.04em",
                alignItems: "center",
              }}>
                <span></span>
                <span>Item Name</span>
                <span>Category</span>
                <span>Unit Price</span>
                <span>Quantity</span>
                <span>Subtotal</span>
                <span />
                <span />
              </div>

              {selectedAddOns.map((it, idx) => {
                const isSection = it.itemType === "section";
                const isNote    = it.itemType === "note";
                const isComp    = it.chargeType === "complimentary";
                const isMeta    = isSection || isNote;
                const uid       = it._uid || it.id;

                /* ── Section header row ── */
                if (isSection) {
                  return (
                    <div key={uid} style={{
                      display: "flex", alignItems: "center", gap: 10,
                      padding: "10px 20px", borderBottom: idx < selectedAddOns.length - 1 ? "1px solid #F0F1F4" : "none",
                      background: "#F8F9FA",
                      ...rowDragStyle(uid),
                    }} {...rowDragHandlers(uid)}>
                      <span style={{ fontSize: 11, color: "#9CA8B8", textTransform: "uppercase", letterSpacing: "0.06em", flexShrink: 0 }}>
                        §
                      </span>
                      {(isAmendmentDraft || !isReadOnly) ? (
                        <input
                          value={it.name}
                          onChange={(e) => setItemName(uid, e.target.value)}
                          placeholder="Section heading…"
                          style={{
                            flex: 1, border: "none", background: "transparent",
                            fontFamily: "inherit", fontSize: 13, fontWeight: 600,
                            color: "#1F3A60", letterSpacing: "0.02em",
                            textTransform: "uppercase", outline: "none",
                          }}
                        />
                      ) : (
                        <span style={{ flex: 1, fontSize: 13, fontWeight: 600, color: "#1F3A60", letterSpacing: "0.02em", textTransform: "uppercase" }}>
                          {it.name}
                        </span>
                      )}
                      {!isReadOnly && (
                        <div style={{ display: "flex", alignItems: "center", gap: 4, marginLeft: "auto" }}>
                          {/* Drag handle */}
                          <div
                            draggable
                            onDragStart={(e) => { e.stopPropagation(); setDragId(uid); e.dataTransfer.effectAllowed = "move"; }}
                            onDragEnd={() => { setDragId(null); setDragOverId(null); }}
                            title="Drag to reorder"
                            style={{ width: 24, height: 24, cursor: "grab", display: "flex", alignItems: "center", justifyContent: "center", borderRadius: 4, color: "#C0C8D4", flexShrink: 0 }}
                          >
                            <GripDots />
                          </div>
                          <button onClick={() => removeItem(uid)} style={{ width: 28, height: 28, border: "none", background: "transparent", borderRadius: 6, cursor: "pointer", color: "#C0C8D4", display: "flex", alignItems: "center", justifyContent: "center" }}>
                            <SerIcons.Trash size={16} />
                          </button>
                        </div>
                      )}
                    </div>
                  );
                }

                /* ── Note row ── */
                if (isNote) {
                  return (
                    <div key={uid} style={{
                      display: "flex", alignItems: "center", gap: 10,
                      padding: "8px 20px", borderBottom: idx < selectedAddOns.length - 1 ? "1px solid #F0F1F4" : "none",
                      background: "#FAFBFC",
                      ...rowDragStyle(uid),
                    }} {...rowDragHandlers(uid)}>
                      <span style={{ fontSize: 13, color: "#9CA8B8", flexShrink: 0 }}>—</span>
                      {(isAmendmentDraft || !isReadOnly) ? (
                        <input
                          value={it.name}
                          onChange={(e) => setItemName(uid, e.target.value)}
                          placeholder="Add a note or comment…"
                          style={{
                            flex: 1, border: "none", background: "transparent",
                            fontFamily: "inherit", fontSize: 13, color: "#574F40",
                            fontStyle: "italic", outline: "none",
                          }}
                        />
                      ) : (
                        <span style={{ flex: 1, fontSize: 13, color: "#574F40", fontStyle: "italic" }}>
                          {it.name || <span style={{ color: "#9CA8B8" }}>Note</span>}
                        </span>
                      )}
                      {!isReadOnly && (
                        <div style={{ display: "flex", alignItems: "center", gap: 4, marginLeft: "auto" }}>
                          {/* Drag handle */}
                          <div
                            draggable
                            onDragStart={(e) => { e.stopPropagation(); setDragId(uid); e.dataTransfer.effectAllowed = "move"; }}
                            onDragEnd={() => { setDragId(null); setDragOverId(null); }}
                            title="Drag to reorder"
                            style={{ width: 24, height: 24, cursor: "grab", display: "flex", alignItems: "center", justifyContent: "center", borderRadius: 4, color: "#C0C8D4", flexShrink: 0 }}
                          >
                            <GripDots />
                          </div>
                          <button onClick={() => removeItem(uid)} style={{ width: 28, height: 28, border: "none", background: "transparent", borderRadius: 6, cursor: "pointer", color: "#C0C8D4", display: "flex", alignItems: "center", justifyContent: "center" }}>
                            <SerIcons.Trash size={16} />
                          </button>
                        </div>
                      )}
                    </div>
                  );
                }

                /* ── Regular item row ── */
                return (
                  <div key={uid} style={{
                    display: "grid", gridTemplateColumns: colTemplate,
                    padding: "14px 20px", alignItems: "center", gap: 4,
                    borderBottom: idx < selectedAddOns.length - 1 ? "1px solid #F0F1F4" : "none",
                    ...rowDragStyle(uid),
                  }} {...rowDragHandlers(uid)}>
                    <AddonThumbnail item={it} size={40} onZoom={isReadOnly ? undefined : setZoomItem} />
                    <div style={{ fontSize: 14, fontWeight: 500, color: "#1F3A60", letterSpacing: "-0.15px",
                                  overflow: "hidden" }}>
                      <div style={{ overflow: "hidden", textOverflow: "ellipsis", whiteSpace: "nowrap" }}>{it.name}</div>
                      {it.rentalDays && (
                        isReadOnly
                          ? <div style={{ fontSize: 11, color: "#6B7A8F", fontWeight: 400, marginTop: 1, letterSpacing: "-0.05px" }}>
                              Rental: {it.rentalDays} day{it.rentalDays > 1 ? "s" : ""}
                            </div>
                          : <button
                              type="button"
                              onPointerDown={(e) => { e.stopPropagation(); setEditingItem({ it, uid, currentQuantity: it.quantity, currentRentalDays: it.rentalDays }); }}
                              title="Edit rental duration and quantity"
                              style={{
                                all: "unset", cursor: "pointer", touchAction: "manipulation",
                                display: "inline-flex", alignItems: "center", gap: 4,
                                marginTop: 2, padding: "2px 6px",
                                borderRadius: 4, border: "1px solid #E9EBF0", background: "#F7F8FA",
                                fontSize: 11, color: "#6B7A8F", fontWeight: 400, letterSpacing: "-0.05px",
                              }}
                            >
                              Rental: {it.rentalDays} day{it.rentalDays > 1 ? "s" : ""}
                              <SerIcons.Edit size={9} color="#B0BAC8" />
                            </button>
                      )}
                    </div>
                    <div style={{ fontSize: 13, color: "#6B7A8F" }}>{it.category}</div>
                    <div>
                      <div style={{ fontSize: 14, fontWeight: 500, color: isComp ? "#5B7D4F" : "#1F3A60", fontFeatureSettings: "'tnum'" }}>
                        {isComp ? "Complimentary" : formatPrice(it.unitPrice)}
                      </div>
                      {!isComp && <div style={{ fontSize: 11, color: "#6B7A8F" }}>{it.chargeType}</div>}
                    </div>
                    {/* Quantity stepper — disabled in read-only states */}
                    <div style={{ display: "flex", alignItems: "center", gap: 8 }}>
                      {!isReadOnly ? (
                        <React.Fragment>
                          <QtyBtn onClick={() => updateQty(uid, -1)} disabled={it.quantity <= (it.minQuantity || 1)}><SerIcons.Minus size={14} /></QtyBtn>
                          <QtyInput value={it.quantity} min={it.minQuantity || 1} onCommit={(val) => setQty(uid, val)} />
                          <QtyBtn onClick={() => updateQty(uid, 1)}><SerIcons.Plus size={14} /></QtyBtn>
                        </React.Fragment>
                      ) : (
                        <span style={{ fontSize: 14, fontWeight: 500, color: "#1F3A60", paddingLeft: 4 }}>× {it.quantity}</span>
                      )}
                    </div>
                    <div style={{ fontSize: 15, fontWeight: 500, color: "#1F3A60", fontFeatureSettings: "'tnum'" }}>
                      {isComp ? "—" : formatPrice(subtotal(it))}
                    </div>
                    {!isReadOnly ? (
                      <div
                        draggable
                        onDragStart={(e) => { e.stopPropagation(); setDragId(uid); e.dataTransfer.effectAllowed = "move"; }}
                        onDragEnd={() => { setDragId(null); setDragOverId(null); }}
                        title="Drag to reorder"
                        style={{
                          display: "flex", alignItems: "center", justifyContent: "center",
                          cursor: "grab", color: "#C0C8D4", borderRadius: 4,
                        }}
                      >
                        <GripDots />
                      </div>
                    ) : <span />}
                    {!isReadOnly ? (
                      <button onClick={() => removeItem(uid)} style={{
                        width: 32, height: 32, border: "none", background: "transparent",
                        borderRadius: 8, cursor: "pointer", color: "#9CA8B8",
                        display: "flex", alignItems: "center", justifyContent: "center",
                      }}>
                        <SerIcons.Trash size={16} />
                      </button>
                    ) : <span />}
                  </div>
                );
              })}

              {/* Totals row */}
              <div style={{
                padding: "14px 20px", borderTop: "1px solid #E5E7EB", background: "#FAFAFA",
                display: "flex", justifyContent: "flex-end", alignItems: "center", gap: 16,
              }}>
                <span style={{ fontSize: 13, color: "#6B7A8F" }}>Add-ons subtotal</span>
                <span style={{ fontSize: 18, fontWeight: 500, color: "#1F3A60", letterSpacing: "-0.439px", fontFeatureSettings: "'tnum'" }}>
                  {formatPrice(addOnTotal)}
                </span>
              </div>
            </div>
          )}


        </div>
      </main>

      <OrderSummarySidebar
        caseDetails={caseDetails} caseBrand={brandForReligion(caseDetails.religion)}
        serviceData={serviceData}
        selectedPackage={selectedPackage} selectedCasket={selectedCasket}
        selectedAddOns={selectedAddOns}
        addOnTotal={addOnTotal} addOnCount={
          selectedAddOns.filter((it) => it.itemType !== "section" && it.itemType !== "note").length
        }
        notes={notes} setNotes={isReadOnly ? undefined : setNotes}
        onEditCase={onEditCase} onJumpTo={onJumpTo}
        onContinue={onContinue}
        continueLabel="Continue to Review"
        activeStep="addons"
        confirmationStatus={confirmationStatus}
        onSendForConfirmation={onSendForConfirmation}
        onViewPdf={onViewPdf}
        onResend={onResend}
        onEditArrangement={onEditArrangement}
        amendmentSnapshot={amendmentSnapshot}
        onEnterEditMode={onEnterEditMode}
        onFinalizeAmendment={onFinalizeAmendment}
        onDiscardAmendment={onDiscardAmendment}
        onSendToCustomer={onSendToCustomer}
        onSimulateSign={onSimulateSign}
        onSendSignedForm={onSendSignedForm}
        appliedCoupon={appliedCoupon}
        onApplyCoupon={onApplyCoupon}
        onRemoveCoupon={onRemoveCoupon}
      />

      <AddonZoomModal item={zoomItem} onClose={() => setZoomItem(null)} />
      {configuringItem && (
        <ConfigureAddonOverlay
          item={configuringItem}
          wakeDuration={serviceData?.wakeDuration}
          onConfirm={confirmAddItem}
          onCancel={() => setConfiguringItem(null)}
        />
      )}
      {editingItem && (
        <ConfigureAddonOverlay
          item={editingItem.it}
          wakeDuration={serviceData?.wakeDuration}
          initialQuantity={editingItem.currentQuantity}
          initialRentalDays={editingItem.currentRentalDays}
          editMode={true}
          onConfirm={confirmEditItem}
          onCancel={() => setEditingItem(null)}
        />
      )}
    </div>
  );
}

/* ─────────────────────────────────────────────────────────────
   AddonSearchDropdown — Odoo-style search panel
   ───────────────────────────────────────────────────────────── */
function AddonSearchDropdown({ term, category, searchHits, suggested, onPick, anchorRef }) {
  // Empty input → show suggestions; typing → show results.
  const showingSuggestions = !term;
  const items = showingSuggestions ? suggested : searchHits;
  const scopeLabel = category && category !== "All" ? category : null;
  const dropStyle = useSmartPosition(true, anchorRef, { maxHeight: 440 });

  const panelStyle = {
    ...dropStyle,
    background: "#FFFFFF", border: "1px solid #E5E7EB", borderRadius: 12,
    boxShadow: "0 20px 25px -5px rgba(15,23,42,0.10), 0 8px 12px -8px rgba(15,23,42,0.08)",
  };

  if (!dropStyle) return null;

  if (items.length === 0) {
    return (
      <div style={{ ...panelStyle, padding: "24px 20px", textAlign: "center" }}>
        <div style={{ fontSize: 14, fontWeight: 500, color: "#1F3A60", letterSpacing: "-0.15px" }}>
          No items found
        </div>
        <div style={{ fontSize: 13, color: "#6B7A8F", marginTop: 4, letterSpacing: "-0.15px" }}>
          Try a different keyword or category
        </div>
      </div>
    );
  }

  return (
    <div style={{ ...panelStyle, padding: 4 }}>
      <AddonDropdownSection
        icon={showingSuggestions ? <SerIcons.Tag size={14} /> : <SerIcons.Search size={14} />}
        title={
          showingSuggestions
            ? (scopeLabel ? `Suggested · ${scopeLabel}` : "Suggested for Consultations")
            : (scopeLabel ? `Results in ${scopeLabel} (${items.length})` : `Results (${items.length})`)
        }
        items={items}
        onPick={onPick}
      />
    </div>
  );
}

/* ─────────────────────────────────────────────────────────────
   CategorySelect — sits beside the search field; matches the
   48px input height so the two read as a single search bar.
   ───────────────────────────────────────────────────────────── */
function CategorySelect({ value, onChange, options }) {
  return (
    <select
      value={value}
      onChange={(e) => onChange(e.target.value)}
      aria-label="Filter by category"
      style={{
        height: 48,
        padding: "0 36px 0 14px",
        minWidth: 180,
        fontFamily: "inherit", fontSize: 14, color: "#1F3A60",
        fontWeight: 500, letterSpacing: "-0.15px",
        background: "#FFFFFF",
        border: "1px solid #E5E7EB", borderRadius: 8,
        outline: "none", cursor: "pointer", appearance: "none",
        backgroundImage: "url(\"data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='14' height='14' viewBox='0 0 20 20' fill='none'><path d='M5 8l5 5 5-5' stroke='%236B7A8F' stroke-width='1.5' stroke-linecap='round'/></svg>\")",
        backgroundRepeat: "no-repeat", backgroundPosition: "right 12px center",
      }}
    >
      {options.map((o) => (
        <option key={o} value={o}>{o === "All" ? "All Categories" : o}</option>
      ))}
    </select>
  );
}

function AddonDropdownSection({ icon, title, items, onPick, divider }) {
  return (
    <div style={{ marginTop: divider ? 4 : 0, paddingTop: divider ? 6 : 0, borderTop: divider ? "1px solid #F0F1F4" : "none" }}>
      <div style={{
        display: "inline-flex", alignItems: "center", gap: 6,
        padding: "8px 12px 6px",
        fontSize: 11, fontWeight: 500, color: "#6B7A8F",
        textTransform: "uppercase", letterSpacing: "0.06em",
      }}>
        <span style={{ color: "#9CA8B8" }}>{icon}</span>{title}
      </div>
      {items.map((it) => <AddonDropdownRow key={it.id} item={it} onPick={onPick} />)}
    </div>
  );
}

function AddonDropdownRow({ item, onPick }) {
  const [hover, setHover] = React.useState(false);
  return (
    <button
      onClick={() => onPick(item)}
      onMouseEnter={() => setHover(true)}
      onMouseLeave={() => setHover(false)}
      style={{
        all: "unset", cursor: "pointer", display: "flex",
        justifyContent: "space-between", alignItems: "center", gap: 12,
        padding: "10px 12px", borderRadius: 8, width: "100%", boxSizing: "border-box",
        background: hover ? "#F3F4F6" : "transparent",
        transition: "background 100ms ease",
      }}
    >
      <div style={{ display: "flex", alignItems: "center", gap: 12, minWidth: 0 }}>
        <AddonThumbnail item={item} size={36} />
        <div style={{ display: "flex", flexDirection: "column", minWidth: 0 }}>
          <span style={{
            fontSize: 14, fontWeight: 500, color: "#1F3A60", letterSpacing: "-0.15px",
            overflow: "hidden", textOverflow: "ellipsis", whiteSpace: "nowrap",
          }}>{item.name}</span>
          <span style={{ fontSize: 12, color: "#6B7A8F" }}>{item.category}</span>
        </div>
      </div>
      <div style={{ textAlign: "right", flexShrink: 0 }}>
        {item.chargeType === "complimentary"
          ? <div style={{ fontSize: 13, color: "#5B7D4F", fontWeight: 500, letterSpacing: "-0.15px" }}>Complimentary</div>
          : <React.Fragment>
              <div style={{ fontSize: 14, fontWeight: 500, color: "#1F3A60", fontFeatureSettings: "'tnum'", letterSpacing: "-0.15px" }}>{formatPrice(item.unitPrice)}</div>
              <div style={{ fontSize: 11, color: "#9CA8B8" }}>{item.chargeType}</div>
            </React.Fragment>}
      </div>
    </button>
  );
}

/* ─────────────────────────────────────────────────────────────
   AddonThumbnail — image > glyph fallback
   ───────────────────────────────────────────────────────────── */
/* ─────────────────────────────────────────────────────────────
   AddonThumbnail — image > glyph fallback. Tap-to-zoom when
   `onZoom` is provided (used in the selected-items table to
   give the FD a clear look at the chosen item during a live
   consultation).
   ───────────────────────────────────────────────────────────── */
function AddonThumbnail({ item, size = 40, onZoom }) {
  const wrap = (inner) => onZoom ? (
    <button
      onClick={(e) => { e.stopPropagation(); onZoom(item); }}
      aria-label={`Zoom ${item.name}`}
      title="Zoom"
      style={{
        all: "unset", cursor: "zoom-in",
        display: "inline-flex", borderRadius: 6,
      }}
    >{inner}</button>
  ) : inner;

  if (item.image) {
    return wrap(
      <div style={{
        width: size, height: size, borderRadius: 6, overflow: "hidden",
        background: `url(${item.image}) center / cover no-repeat #EFE7D4`,
        border: "1px solid var(--border-subtle, #E5E7EB)",
        flexShrink: 0,
      }} />
    );
  }
  const Glyph = AddonGlyphs[item.icon] || AddonGlyphs.box;
  const tint = CATEGORY_TINTS[item.category] || CATEGORY_TINTS.default;
  return wrap(
    <div style={{
      width: size, height: size, borderRadius: 6,
      background: tint.bg, color: tint.fg,
      border: "1px solid var(--border-subtle, #E5E7EB)",
      display: "inline-flex", alignItems: "center", justifyContent: "center",
      flexShrink: 0,
    }}>
      <Glyph size={Math.round(size * 0.55)} color="currentColor" />
    </div>
  );
}

/* ─────────────────────────────────────────────────────────────
   AddonImageCarousel — image gallery for add-on item overlays.
   Uses item.images[] (multi-image) or item.image (single) with
   fallback to a clean tinted placeholder when no images exist.
   Supports left/right arrows, dot indicators, and touch swipe.
   ───────────────────────────────────────────────────────────── */
function AddonImageCarousel({ item, height = 240 }) {
  const images = (item.images && item.images.length)
    ? item.images
    : (item.image ? [item.image] : []);

  const [idx, setIdx] = React.useState(0);
  const touchStartX = React.useRef(null);

  React.useEffect(() => { setIdx(0); }, [item && item.id]);

  const prev = () => setIdx((i) => (i - 1 + images.length) % images.length);
  const next = () => setIdx((i) => (i + 1) % images.length);

  const onTouchStart = (e) => { touchStartX.current = e.touches[0].clientX; };
  const onTouchEnd  = (e) => {
    if (touchStartX.current === null || images.length < 2) return;
    const dx = e.changedTouches[0].clientX - touchStartX.current;
    if (Math.abs(dx) > 40) { dx < 0 ? next() : prev(); }
    touchStartX.current = null;
  };

  const Glyph = AddonGlyphs[item.icon] || AddonGlyphs.box;
  const tint  = CATEGORY_TINTS[item.category] || CATEGORY_TINTS.default;

  if (images.length === 0) {
    return (
      <div style={{
        height, borderRadius: 10, overflow: "hidden",
        background: tint.bg,
        display: "flex", flexDirection: "column",
        alignItems: "center", justifyContent: "center", gap: 10,
      }}>
        <div style={{ color: tint.fg, opacity: 0.22 }}>
          <Glyph size={52} color="currentColor" />
        </div>
        <span style={{ fontSize: 12, color: tint.fg, opacity: 0.45, letterSpacing: "-0.1px" }}>
          No images uploaded
        </span>
      </div>
    );
  }

  return (
    <div
      style={{
        position: "relative", height, borderRadius: 10, overflow: "hidden",
        background: "#E8EBF0", userSelect: "none", flexShrink: 0,
      }}
      onTouchStart={onTouchStart}
      onTouchEnd={onTouchEnd}
    >
      <img
        src={images[idx]}
        alt={item.name}
        style={{ width: "100%", height: "100%", objectFit: "cover", display: "block" }}
      />
      {images.length > 1 && (
        <React.Fragment>
          <button
            onPointerDown={(e) => { e.preventDefault(); prev(); }}
            style={{
              all: "unset", cursor: "pointer", touchAction: "manipulation",
              position: "absolute", left: 10, top: "50%", transform: "translateY(-50%)",
              width: 32, height: 32, borderRadius: "50%",
              background: "rgba(255,255,255,0.88)", backdropFilter: "blur(4px)",
              display: "flex", alignItems: "center", justifyContent: "center",
              color: "#1F3A60", boxShadow: "0 1px 6px rgba(0,0,0,0.14)",
            }}
          >
            <svg width="14" height="14" viewBox="0 0 20 20" fill="none">
              <path d="M13 5l-5 5 5 5" stroke="currentColor" strokeWidth="1.7" strokeLinecap="round" strokeLinejoin="round"/>
            </svg>
          </button>
          <button
            onPointerDown={(e) => { e.preventDefault(); next(); }}
            style={{
              all: "unset", cursor: "pointer", touchAction: "manipulation",
              position: "absolute", right: 10, top: "50%", transform: "translateY(-50%)",
              width: 32, height: 32, borderRadius: "50%",
              background: "rgba(255,255,255,0.88)", backdropFilter: "blur(4px)",
              display: "flex", alignItems: "center", justifyContent: "center",
              color: "#1F3A60", boxShadow: "0 1px 6px rgba(0,0,0,0.14)",
            }}
          >
            <svg width="14" height="14" viewBox="0 0 20 20" fill="none">
              <path d="M7 5l5 5-5 5" stroke="currentColor" strokeWidth="1.7" strokeLinecap="round" strokeLinejoin="round"/>
            </svg>
          </button>
          <div style={{
            position: "absolute", bottom: 10, left: "50%", transform: "translateX(-50%)",
            display: "flex", gap: 5, alignItems: "center",
          }}>
            {images.map((_, i) => (
              <button
                key={i}
                onPointerDown={(e) => { e.preventDefault(); setIdx(i); }}
                style={{
                  all: "unset", cursor: "pointer", touchAction: "manipulation",
                  width: i === idx ? 16 : 6, height: 6, borderRadius: 3,
                  background: i === idx ? "#FFFFFF" : "rgba(255,255,255,0.55)",
                  transition: "width 150ms ease",
                }}
              />
            ))}
          </div>
        </React.Fragment>
      )}
    </div>
  );
}

/* ─────────────────────────────────────────────────────────────
   AddonZoomModal — image gallery overlay for an add-on item.
   Opens from the thumbnail in the add-on table. Shows real
   uploaded images via AddonImageCarousel; clean placeholder
   when no images are available. Esc / backdrop / X to close.
   ───────────────────────────────────────────────────────────── */
function AddonZoomModal({ item, onClose }) {
  React.useEffect(() => {
    if (!item) return;
    const onKey = (e) => { if (e.key === "Escape") onClose(); };
    document.addEventListener("keydown", onKey);
    return () => document.removeEventListener("keydown", onKey);
  }, [item, onClose]);

  if (!item) return null;
  const isComp = item.chargeType === "complimentary";
  const chargeUnitLabel = item.chargeType === "per day" ? "day"
    : item.chargeType === "per pax" ? "pax"
    : item.chargeType === "per hour" ? "hr"
    : null;

  return (
    <div
      onPointerDown={onClose}
      style={{
        position: "fixed", inset: 0, background: "rgba(15,23,42,0.75)",
        zIndex: 400, display: "flex", alignItems: "center", justifyContent: "center",
        padding: 24,
      }}
    >
      <div
        onPointerDown={(e) => e.stopPropagation()}
        style={{
          width: "min(540px, calc(100vw - 48px))",
          background: "#FFFFFF", borderRadius: 16,
          boxShadow: "0 20px 60px rgba(0,0,0,0.4)",
          overflow: "hidden",
          display: "flex", flexDirection: "column",
        }}
      >
        {/* Header */}
        <div style={{
          padding: "16px 20px",
          display: "flex", alignItems: "flex-start", justifyContent: "space-between", gap: 12,
        }}>
          <div style={{ display: "flex", flexDirection: "column", gap: 3 }}>
            <span style={{ fontSize: 17, fontWeight: 500, color: "#1F3A60", letterSpacing: "-0.3px" }}>
              {item.name}
            </span>
            <span style={{ fontSize: 13, color: "#6B7A8F", letterSpacing: "-0.1px" }}>
              {item.category}
              {isComp
                ? " · Complimentary"
                : (
                  <React.Fragment>
                    <span style={{ color: "#D1D5DB", margin: "0 5px" }}>·</span>
                    <span style={{ fontFeatureSettings: "'tnum'" }}>{formatPrice(item.unitPrice)}</span>
                    {chargeUnitLabel && <span style={{ color: "#9CA8B8" }}>{" / "}{chargeUnitLabel}</span>}
                  </React.Fragment>
                )
              }
            </span>
          </div>
          <button
            onPointerDown={(e) => { e.stopPropagation(); onClose(); }}
            aria-label="Close"
            style={{
              all: "unset", cursor: "pointer", flexShrink: 0,
              width: 32, height: 32, borderRadius: 8,
              display: "flex", alignItems: "center", justifyContent: "center",
              color: "#9CA8B8",
            }}
          >
            <SerIcons.Close size={20} />
          </button>
        </div>

        {/* Image gallery */}
        <div style={{ padding: "0 20px 20px" }}>
          <AddonImageCarousel item={item} height={300} />
        </div>
      </div>
    </div>
  );
}

const CATEGORY_TINTS = {
  Catering:  { bg: "#FAF5EE", fg: "#8B5A1A" },
  Equipment: { bg: "#EFF3F7", fg: "#3A4A60" },
  Logistics: { bg: "#F1EFE6", fg: "#5E5236" },
  Apparel:   { bg: "#F4EFF4", fg: "#5C4860" },
  Services:  { bg: "#EBF0E9", fg: "#3C5A37" },
  default:   { bg: "#EAE2CE", fg: "#574F40" },
};

/* Compact line-icon set for add-on items. Each glyph is a flat
   monochrome SVG rendered in the category tint. Drawn small and
   readable at 22px — the size used in dropdown + table rows. */
const AddonGlyphs = {
  coffeeBeans: ({ size = 16, color = "currentColor" }) =>
    <svg width={size} height={size} viewBox="0 0 20 20" fill="none">
      <ellipse cx="7"  cy="9" rx="3" ry="5" stroke={color} strokeWidth="1.3" />
      <ellipse cx="13" cy="11" rx="3" ry="5" stroke={color} strokeWidth="1.3" />
      <path d="M7 5c1.5 2 1.5 6 0 8M13 7c1.5 2 1.5 6 0 8" stroke={color} strokeWidth="1.1" />
    </svg>,
  coffeeMachine: ({ size = 16, color = "currentColor" }) =>
    <svg width={size} height={size} viewBox="0 0 20 20" fill="none">
      <path d="M4 3h12v4H4z" stroke={color} strokeWidth="1.3" strokeLinejoin="round" />
      <path d="M6 7v3a4 4 0 004 4 4 4 0 004-4V7" stroke={color} strokeWidth="1.3" strokeLinejoin="round" />
      <path d="M3 17h14" stroke={color} strokeWidth="1.3" strokeLinecap="round" />
      <path d="M10 5v1" stroke={color} strokeWidth="1.3" strokeLinecap="round" />
    </svg>,
  toilet: ({ size = 16, color = "currentColor" }) =>
    <svg width={size} height={size} viewBox="0 0 20 20" fill="none">
      <rect x="4.5" y="2.5" width="11" height="15" rx="1.2" stroke={color} strokeWidth="1.3" />
      <circle cx="10" cy="6" r="1.4" stroke={color} strokeWidth="1.3" />
      <path d="M7 11h6M7 13h6" stroke={color} strokeWidth="1.3" strokeLinecap="round" />
    </svg>,
  chiller: ({ size = 16, color = "currentColor" }) =>
    <svg width={size} height={size} viewBox="0 0 20 20" fill="none">
      <rect x="5" y="2.5" width="10" height="15" rx="1.4" stroke={color} strokeWidth="1.3" />
      <path d="M5 9h10" stroke={color} strokeWidth="1.3" />
      <path d="M7 5.5v1.5M7 11v1.5" stroke={color} strokeWidth="1.4" strokeLinecap="round" />
    </svg>,
  bulb: ({ size = 16, color = "currentColor" }) =>
    <svg width={size} height={size} viewBox="0 0 20 20" fill="none">
      <path d="M10 2.5a5 5 0 00-3 9c.7.6 1 1.4 1 2.3V15h4v-1.2c0-.9.3-1.7 1-2.3a5 5 0 00-3-9z" stroke={color} strokeWidth="1.3" strokeLinejoin="round" />
      <path d="M8.5 17h3M9 19h2" stroke={color} strokeWidth="1.3" strokeLinecap="round" />
    </svg>,
  fan: ({ size = 16, color = "currentColor" }) =>
    <svg width={size} height={size} viewBox="0 0 20 20" fill="none">
      <circle cx="10" cy="10" r="1.6" stroke={color} strokeWidth="1.3" />
      <path d="M10 2c2.5 0 4 1.4 4 3.2C14 7 12 8 10 8.4M10 18c-2.5 0-4-1.4-4-3.2C6 13 8 12 10 11.6M2 10c0-2.5 1.4-4 3.2-4C7 6 8 8 8.4 10M18 10c0 2.5-1.4 4-3.2 4-1.8 0-2.8-2-3.2-4" stroke={color} strokeWidth="1.3" strokeLinejoin="round" />
    </svg>,
  canvas: ({ size = 16, color = "currentColor" }) =>
    <svg width={size} height={size} viewBox="0 0 20 20" fill="none">
      <path d="M3 5h14l-1 11H4z" stroke={color} strokeWidth="1.3" strokeLinejoin="round" />
      <path d="M5 5l-1-2h12l-1 2" stroke={color} strokeWidth="1.3" strokeLinejoin="round" />
    </svg>,
  table: ({ size = 16, color = "currentColor" }) =>
    <svg width={size} height={size} viewBox="0 0 20 20" fill="none">
      <path d="M2.5 7.5h15" stroke={color} strokeWidth="1.5" strokeLinecap="round" />
      <path d="M5 7.5v9M15 7.5v9M2.5 6c1-1.5 3-2.5 7.5-2.5S16.5 4.5 17.5 6" stroke={color} strokeWidth="1.3" strokeLinejoin="round" />
    </svg>,
  tableRound: ({ size = 16, color = "currentColor" }) =>
    <svg width={size} height={size} viewBox="0 0 20 20" fill="none">
      <ellipse cx="10" cy="7" rx="7" ry="2.4" stroke={color} strokeWidth="1.3" />
      <path d="M5 8.5v8M15 8.5v8" stroke={color} strokeWidth="1.3" strokeLinecap="round" />
    </svg>,
  chair: ({ size = 16, color = "currentColor" }) =>
    <svg width={size} height={size} viewBox="0 0 20 20" fill="none">
      <path d="M6 3h8v8H6z" stroke={color} strokeWidth="1.3" strokeLinejoin="round" />
      <path d="M5 11h10v2H5z" stroke={color} strokeWidth="1.3" strokeLinejoin="round" />
      <path d="M7 13v4M13 13v4" stroke={color} strokeWidth="1.3" strokeLinecap="round" />
    </svg>,
  shirt: ({ size = 16, color = "currentColor" }) =>
    <svg width={size} height={size} viewBox="0 0 20 20" fill="none">
      <path d="M6 3l-3.5 2.5L4 8h2v9h8V8h2l1.5-2.5L14 3 12 4.5a3 3 0 01-4 0L6 3z" stroke={color} strokeWidth="1.3" strokeLinejoin="round" />
    </svg>,
  polo: ({ size = 16, color = "currentColor" }) =>
    <svg width={size} height={size} viewBox="0 0 20 20" fill="none">
      <path d="M6 3l-3.5 2.5L4 8h2v9h8V8h2l1.5-2.5L14 3 12 4.5a3 3 0 01-4 0L6 3z" stroke={color} strokeWidth="1.3" strokeLinejoin="round" />
      <path d="M8.5 4.5l1.5 2.5 1.5-2.5" stroke={color} strokeWidth="1.3" strokeLinejoin="round" />
      <path d="M11 7.5v3" stroke={color} strokeWidth="1.3" strokeLinecap="round" />
    </svg>,
  photo: ({ size = 16, color = "currentColor" }) =>
    <svg width={size} height={size} viewBox="0 0 20 20" fill="none">
      <rect x="2.5" y="4.5" width="15" height="11" rx="1.2" stroke={color} strokeWidth="1.3" />
      <circle cx="7.5" cy="8.5" r="1.2" stroke={color} strokeWidth="1.3" />
      <path d="M3 14l4-4 3 3 3-3 4 4" stroke={color} strokeWidth="1.3" strokeLinejoin="round" />
    </svg>,
  stream: ({ size = 16, color = "currentColor" }) =>
    <svg width={size} height={size} viewBox="0 0 20 20" fill="none">
      <circle cx="10" cy="10" r="1.8" fill={color} />
      <path d="M5.5 5.5C4.5 6.5 4 8 4 10s.5 3.5 1.5 4.5M14.5 5.5C15.5 6.5 16 8 16 10s-.5 3.5-1.5 4.5M2.5 3C1 5 0 7.5 0 10s1 5 2.5 7M17.5 3C19 5 20 7.5 20 10s-1 5-2.5 7" stroke={color} strokeWidth="1.3" strokeLinecap="round" />
    </svg>,
  moon: ({ size = 16, color = "currentColor" }) =>
    <svg width={size} height={size} viewBox="0 0 20 20" fill="none">
      <path d="M15.5 12a7 7 0 11-8-9 5.5 5.5 0 008 9z" stroke={color} strokeWidth="1.3" strokeLinejoin="round" />
    </svg>,
  bus: ({ size = 16, color = "currentColor" }) =>
    <svg width={size} height={size} viewBox="0 0 20 20" fill="none">
      <rect x="2.5" y="4" width="15" height="10" rx="2" stroke={color} strokeWidth="1.3" />
      <path d="M2.5 9h15M6 14v2M14 14v2" stroke={color} strokeWidth="1.3" strokeLinecap="round" />
      <circle cx="6" cy="14" r="1.2" stroke={color} strokeWidth="1.3" />
      <circle cx="14" cy="14" r="1.2" stroke={color} strokeWidth="1.3" />
    </svg>,
  wave: ({ size = 16, color = "currentColor" }) =>
    <svg width={size} height={size} viewBox="0 0 20 20" fill="none">
      <path d="M2 8c2 0 2-2 4-2s2 2 4 2 2-2 4-2 2 2 4 2M2 12c2 0 2-2 4-2s2 2 4 2 2-2 4-2 2 2 4 2M2 16c2 0 2-2 4-2s2 2 4 2 2-2 4-2 2 2 4 2" stroke={color} strokeWidth="1.3" strokeLinecap="round" strokeLinejoin="round" />
    </svg>,
  plate: ({ size = 16, color = "currentColor" }) =>
    <svg width={size} height={size} viewBox="0 0 20 20" fill="none">
      <circle cx="10" cy="10" r="7" stroke={color} strokeWidth="1.3" />
      <circle cx="10" cy="10" r="3.5" stroke={color} strokeWidth="1.3" />
    </svg>,
  box: ({ size = 16, color = "currentColor" }) =>
    <svg width={size} height={size} viewBox="0 0 20 20" fill="none">
      <path d="M3 6l7-3 7 3v8l-7 3-7-3V6z" stroke={color} strokeWidth="1.3" strokeLinejoin="round" />
      <path d="M3 6l7 3 7-3M10 9v9" stroke={color} strokeWidth="1.3" />
    </svg>,
};

function QtyBtn({ onClick, disabled, children }) {
  return (
    <button onClick={onClick} disabled={disabled} style={{
      width: 28, height: 28, border: "1px solid #E5E7EB", background: "#FFFFFF",
      borderRadius: 6, cursor: disabled ? "not-allowed" : "pointer", color: "#1F3A60",
      opacity: disabled ? 0.4 : 1,
      display: "flex", alignItems: "center", justifyContent: "center",
    }}>{children}</button>
  );
}

/* Editable quantity field that sits between the stepper buttons.
   Maintains its own draft string while the FD is typing so the
   input feels instant, then commits a validated integer on blur.
   The parent value prop stays in sync when steppers change it. */
function QtyInput({ value, min, onCommit }) {
  const [draft, setDraft] = React.useState(String(value));
  const focused = React.useRef(false);
  React.useEffect(() => {
    if (!focused.current) setDraft(String(value));
  }, [value]);
  const commit = () => {
    const parsed = parseInt(draft, 10);
    const safe = isNaN(parsed) || parsed < min ? min : parsed;
    onCommit(safe);
    setDraft(String(safe));
  };
  return (
    <input
      type="text"
      inputMode="numeric"
      pattern="[0-9]*"
      value={draft}
      onChange={(e) => {
        const raw = e.target.value.replace(/[^\d]/g, "");
        setDraft(raw);
        const parsed = parseInt(raw, 10);
        if (!isNaN(parsed) && parsed >= min) onCommit(parsed);
      }}
      onFocus={() => { focused.current = true; }}
      onBlur={() => { focused.current = false; commit(); }}
      style={{
        width: 48, height: 28, border: "1px solid #E5E7EB", borderRadius: 6,
        textAlign: "center", fontSize: 14, fontWeight: 500, color: "#1F3A60",
        fontFeatureSettings: "'tnum'", fontFamily: "inherit",
        background: "#FFFFFF", outline: "none", padding: 0,
        letterSpacing: "-0.15px",
        WebkitAppearance: "none", MozAppearance: "textfield",
      }}
    />
  );
}

/* ---------------- Edit Case Modal ---------------- */
function EditCaseModal({ open, caseDetails, workspace = "serenity", onClose, onSave }) {
  const [draft, setDraft] = React.useState(caseDetails);
  React.useEffect(() => { setDraft(caseDetails); }, [caseDetails, open]);
  if (!open) return null;

  // Lock contact fields only when the contact was explicitly selected from
  // the existing directory (contactFromDirectory === true).
  // Auto-created contacts (contactFromDirectory === false) keep their fields
  // editable so the FD can correct name/phone without leaving the modal.
  // Seed data and old records have contactFromDirectory undefined — treated
  // as locked (same as before) to preserve existing behaviour.
  const hasLinkedContact = !!caseDetails.contactId && caseDetails.contactFromDirectory !== false;

  // Religion options come from the active workspace.
  const religionOptions = (RELIGIONS_BY_WORKSPACE[workspace] || RELIGIONS_BY_WORKSPACE.serenity)
    .map((label) => ({ label, value: label.toLowerCase().replace(/\s+/g, "-") }));

  // Visually-disabled field — same size/shape as Input but non-interactive.
  const LockedInput = ({ value }) => (
    <div style={{
      width: "100%", boxSizing: "border-box", height: 48,
      padding: "0 14px", display: "flex", alignItems: "center",
      fontFamily: "inherit", fontSize: 14, color: "#6B7A8F",
      background: "#F8F9FB", border: "1px solid #E9EBF0",
      borderRadius: 8, letterSpacing: "-0.15px", userSelect: "none",
    }}>
      {value || "—"}
    </div>
  );

  return (
    <div onClick={onClose} style={{
      position: "fixed", inset: 0, background: "rgba(15,23,42,0.45)",
      display: "flex", alignItems: "center", justifyContent: "center", zIndex: 250, padding: 24,
    }}>
      <div onClick={(e) => e.stopPropagation()} style={{
        width: "100%", maxWidth: 480, background: "#FFFFFF", borderRadius: 12,
        boxShadow: "0 20px 25px -5px rgba(0,0,0,0.10)", overflow: "hidden",
      }}>
        <div style={{ padding: "20px 24px", borderBottom: "1px solid #E5E7EB", display: "flex", justifyContent: "space-between", alignItems: "center" }}>
          <h2 style={{ font: "500 20px/28px Inter", letterSpacing: "-0.449px", color: "#1F3A60", margin: 0 }}>Edit Case Information</h2>
          <button onClick={onClose} style={{ background: "transparent", border: "none", padding: 6, cursor: "pointer", color: "#6B7A8F" }}>
            <SerIcons.Close size={24} />
          </button>
        </div>
        <div style={{ padding: 24, display: "flex", flexDirection: "column", gap: 16 }}>

          {/* Linked-contact notice — shown whenever contact fields are locked */}
          {hasLinkedContact && (
            <div style={{
              display: "flex", alignItems: "flex-start", gap: 10,
              padding: "11px 14px", borderRadius: 8,
              background: "#F0F4F8", border: "1px solid #D4DEEC",
            }}>
              <span style={{ flexShrink: 0, marginTop: 1 }}>
                <SerIcons.Link size={14} color="#4A6E9A" />
              </span>
              <div style={{ display: "flex", flexDirection: "column", gap: 2 }}>
                <span style={{ fontSize: 13, fontWeight: 500, color: "#1F3A60", letterSpacing: "-0.1px" }}>
                  Contact details are linked to an existing record.
                </span>
                <span style={{ fontSize: 12, color: "#6B7A8F", letterSpacing: "-0.1px" }}>
                  To update name or phone number, edit the contact record directly.
                </span>
              </div>
            </div>
          )}

          <Field label="Contact Name">
            {hasLinkedContact
              ? <LockedInput value={draft.contact} />
              : <Input value={draft.contact} onChange={(e) => setDraft({ ...draft, contact: e.target.value })} />
            }
          </Field>
          <Field label="Contact Phone">
            {hasLinkedContact
              ? <LockedInput value={draft.phone || ""} />
              : <PhoneInput value={draft.phone || ""} onChange={(e) => setDraft({ ...draft, phone: e.target.value })} />
            }
          </Field>
          <Field label="Relationship to Deceased">
            <select value={draft.relationship || ""} onChange={(e) => setDraft({ ...draft, relationship: e.target.value })} style={{
              width: "100%", boxSizing: "border-box", height: 48, padding: "0 14px",
              fontFamily: "inherit", fontSize: 14,
              color: draft.relationship ? "#1F3A60" : "rgba(45,55,72,0.45)",
              background: "#FFFFFF", border: "1px solid #E5E7EB", borderRadius: 8, outline: "none",
              appearance: "none",
              backgroundImage: "url(\"data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='14' height='14' viewBox='0 0 20 20' fill='none'><path d='M5 8l5 5 5-5' stroke='%23718096' stroke-width='1.5' stroke-linecap='round'/></svg>\")",
              backgroundRepeat: "no-repeat", backgroundPosition: "right 14px center",
            }}>
              <option value="">Select relationship…</option>
              {(window.RELATIONSHIP_OPTIONS || []).map((r) => <option key={r} value={r}>{r}</option>)}
            </select>
          </Field>
          <Field label="Need Type *">
            <select value={draft.needType || "as_need"} onChange={(e) => setDraft({ ...draft, needType: e.target.value })} style={{
              width: "100%", boxSizing: "border-box", height: 48, padding: "0 14px",
              fontFamily: "inherit", fontSize: 14, color: "#1F3A60",
              background: "#FFFFFF", border: "1px solid #E5E7EB", borderRadius: 8, outline: "none",
              appearance: "none",
              backgroundImage: "url(\"data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='14' height='14' viewBox='0 0 20 20' fill='none'><path d='M5 8l5 5 5-5' stroke='%23718096' stroke-width='1.5' stroke-linecap='round'/></svg>\")",
              backgroundRepeat: "no-repeat", backgroundPosition: "right 14px center",
            }}>
              <option value="as_need">At-Need</option>
              <option value="pre_need">Pre-Need</option>
            </select>
          </Field>
          {/* Deceased Name + Religion are deliberately edited only in the
              Service Summary screen — they're not duplicated here. */}
        </div>
        <div style={{ padding: "16px 24px", borderTop: "1px solid #E5E7EB", display: "flex", gap: 12, justifyContent: "flex-end" }}>
          <Button variant="secondary"     size="md" onClick={onClose}>Cancel</Button>
          <Button variant="primary-navy" size="md" onClick={() => onSave(draft)}>Save Changes</Button>
        </div>
      </div>
    </div>
  );
}

function Field({ label, children }) {
  const cleanLabel = String(label || "").replace(/\s*\*\s*$/, "");
  const required = /\*\s*$/.test(label || "");
  return (
    <label style={{
      display: "grid", gridTemplateColumns: "180px 1fr",
      alignItems: "center", columnGap: 16,
    }}>
      <span style={{
        fontSize: 13, fontWeight: required ? 500 : 400,
        color: required ? "#1F3A60" : "#6B7A8F",
        letterSpacing: "-0.15px",
      }}>
        {cleanLabel}
        {required && <span style={{ color: "#8F4A45", marginLeft: 2 }}>*</span>}
      </span>
      <div style={{ minWidth: 0 }}>{children}</div>
    </label>
  );
}

/* ─────────────────────────────────────────────────────────────
   ConfigureAddonOverlay — shown before an item is added to the
   arrangement. Lets the FD set rental duration (for rentable
   items) and quantity before confirming. Complimentary items
   bypass this overlay and are added immediately.
   ───────────────────────────────────────────────────────────── */
function ConfigureAddonOverlay({ item, wakeDuration, onConfirm, onCancel, initialQuantity, initialRentalDays, editMode = false }) {
  const maxDays = Math.max(1, parseInt(wakeDuration) || 1);
  const isRentable = !!(item.rentable || item.chargeType === "per day");
  const showRentalDays = isRentable && maxDays > 1;

  const [rentalDays, setRentalDays] = React.useState(
    initialRentalDays !== undefined ? initialRentalDays : maxDays
  );
  const [quantity, setQuantity] = React.useState(
    initialQuantity !== undefined ? initialQuantity : (item.minQuantity || 1)
  );

  React.useEffect(() => {
    const onKey = (e) => { if (e.key === "Escape") onCancel(); };
    document.addEventListener("keydown", onKey);
    return () => document.removeEventListener("keydown", onKey);
  }, [onCancel]);

  const isComp = item.chargeType === "complimentary";
  const effectiveDays = isRentable ? rentalDays : 1;
  const lineTotal = isComp ? 0 : item.unitPrice * quantity * effectiveDays;

  const chargeUnitLabel = item.chargeType === "per day" ? "day"
    : item.chargeType === "per pax" ? "pax"
    : item.chargeType === "per hour" ? "hr"
    : "item";

  const handleConfirm = () => {
    onConfirm({
      quantity,
      ...(isRentable ? { rentalDays } : {}),
    });
  };

  return (
    <div
      onPointerDown={onCancel}
      style={{
        position: "fixed", inset: 0,
        background: "rgba(15,23,42,0.50)",
        display: "flex", alignItems: "center", justifyContent: "center",
        zIndex: 300, padding: 24,
      }}
    >
      <div
        onPointerDown={(e) => e.stopPropagation()}
        style={{
          width: "100%", maxWidth: 440,
          background: "#FFFFFF", borderRadius: 14,
          boxShadow: "0 20px 60px rgba(15,23,42,0.25)",
          overflow: "hidden",
          display: "flex", flexDirection: "column",
        }}
      >
        {/* Header */}
        <div style={{
          padding: "18px 20px", borderBottom: "1px solid #F0F1F4",
          display: "flex", alignItems: "center", justifyContent: "space-between",
        }}>
          <span style={{ fontSize: 16, fontWeight: 500, color: "#1F3A60", letterSpacing: "-0.3px" }}>
            {editMode ? "Edit Add-on Item" : "Configure Add-on Item"}
          </span>
          <button
            onPointerDown={onCancel}
            style={{
              all: "unset", cursor: "pointer",
              width: 32, height: 32, borderRadius: 8,
              display: "flex", alignItems: "center", justifyContent: "center",
              color: "#9CA8B8",
            }}
          >
            <SerIcons.Close size={20} />
          </button>
        </div>

        {/* Image gallery */}
        <div style={{ padding: "14px 20px 0" }}>
          <AddonImageCarousel item={item} height={200} />
        </div>

        {/* Item info */}
        <div style={{
          padding: "12px 20px 16px", borderBottom: "1px solid #F0F1F4",
          display: "flex", flexDirection: "column", gap: 3,
        }}>
          <span style={{ fontSize: 15, fontWeight: 500, color: "#1F3A60", letterSpacing: "-0.2px" }}>
            {item.name}
          </span>
          <span style={{ fontSize: 13, color: "#6B7A8F", letterSpacing: "-0.1px" }}>
            {item.category}
            {isComp
              ? " · Complimentary"
              : (
                <React.Fragment>
                  <span style={{ color: "#D1D5DB", margin: "0 6px" }}>·</span>
                  <span style={{ fontFeatureSettings: "'tnum'", color: "#1F3A60" }}>{formatPrice(item.unitPrice)}</span>
                  <span style={{ color: "#9CA8B8", marginLeft: 3 }}>/ {chargeUnitLabel}</span>
                </React.Fragment>
              )
            }
          </span>
        </div>

        <div style={{ padding: "20px", display: "flex", flexDirection: "column", gap: 20 }}>
          {/* Rental Duration */}
          {showRentalDays && (
            <div>
              <div style={{
                fontSize: 11, fontWeight: 500, color: "#9CA8B8",
                textTransform: "uppercase", letterSpacing: "0.06em", marginBottom: 10,
              }}>
                Rental Duration
              </div>
              <div style={{ display: "flex", flexWrap: "wrap", gap: 8 }}>
                {Array.from({ length: maxDays }, (_, i) => i + 1).map((d) => {
                  const isSel = rentalDays === d;
                  const isFullWake = d === maxDays;
                  return (
                    <button
                      key={d}
                      type="button"
                      onPointerDown={(e) => { e.preventDefault(); setRentalDays(d); }}
                      style={{
                        all: "unset", cursor: "pointer",
                        padding: "7px 14px", borderRadius: 20,
                        fontSize: 13, fontWeight: isSel ? 500 : 400,
                        letterSpacing: "-0.1px",
                        border: `1.5px solid ${isSel ? "#1F3A60" : "#E5E7EB"}`,
                        background: isSel ? "#EDF1F7" : "#FFFFFF",
                        color: isSel ? "#1F3A60" : "#6B7A8F",
                        display: "inline-flex", alignItems: "center", gap: 5,
                        transition: "border-color 80ms, background 80ms",
                        touchAction: "manipulation",
                      }}
                    >
                      {isSel && <SerIcons.Check size={12} color="#1F3A60" />}
                      {d} day{d > 1 ? "s" : ""}
                      {isFullWake && (
                        <span style={{ fontSize: 11, color: isSel ? "#4A6E9A" : "#9CA8B8", marginLeft: 1 }}>
                          (full wake)
                        </span>
                      )}
                    </button>
                  );
                })}
              </div>
            </div>
          )}

          {/* Quantity */}
          <div>
            <div style={{
              fontSize: 11, fontWeight: 500, color: "#9CA8B8",
              textTransform: "uppercase", letterSpacing: "0.06em", marginBottom: 10,
            }}>
              Quantity
            </div>
            <div style={{ display: "flex", alignItems: "center", gap: 8 }}>
              <QtyBtn
                onClick={() => setQuantity(Math.max(item.minQuantity || 1, quantity - 1))}
                disabled={quantity <= (item.minQuantity || 1)}
              >
                <SerIcons.Minus size={14} />
              </QtyBtn>
              <QtyInput value={quantity} min={item.minQuantity || 1} onCommit={setQuantity} />
              <QtyBtn onClick={() => setQuantity(quantity + 1)}>
                <SerIcons.Plus size={14} />
              </QtyBtn>
              {item.chargeType === "per pax" && (
                <span style={{ fontSize: 13, color: "#9CA8B8", marginLeft: 4 }}>pax</span>
              )}
              {item.chargeType === "per hour" && (
                <span style={{ fontSize: 13, color: "#9CA8B8", marginLeft: 4 }}>hrs</span>
              )}
            </div>
          </div>

          {/* Pricing summary */}
          <div style={{
            padding: "13px 16px", borderRadius: 10,
            background: "#F7F9FC", border: "1px solid #EAECF2",
            display: "flex", alignItems: "center", justifyContent: "space-between",
          }}>
            <span style={{ fontSize: 13, color: "#6B7A8F", letterSpacing: "-0.1px" }}>
              {isComp
                ? "Complimentary item"
                : isRentable
                ? `${formatPrice(item.unitPrice)} × ${quantity} × ${effectiveDays} day${effectiveDays > 1 ? "s" : ""}`
                : `${formatPrice(item.unitPrice)} × ${quantity}${item.chargeType !== "one-time" ? " " + chargeUnitLabel : ""}`
              }
            </span>
            <span style={{
              fontSize: 16, fontWeight: 500, color: "#1F3A60",
              letterSpacing: "-0.3px", fontFeatureSettings: "'tnum'",
            }}>
              {isComp ? "—" : formatPrice(lineTotal)}
            </span>
          </div>
        </div>

        {/* Footer */}
        <div style={{
          padding: "14px 20px", borderTop: "1px solid #F0F1F4",
          display: "flex", gap: 10, justifyContent: "flex-end",
        }}>
          <Button variant="secondary" size="md" onClick={onCancel}>Cancel</Button>
          <Button variant="primary-navy" size="md" onClick={handleConfirm}>{editMode ? "Update" : "Add Item"}</Button>
        </div>
      </div>
    </div>
  );
}

Object.assign(window, { AddOnScreen, EditCaseModal, AddonThumbnail, AddonGlyphs, AddonZoomModal });

/* ── Drag-handle grip dots (2×3 dot grid) ────────────────────────
   Used as the drag affordance in the reorderable add-on rows.
   Renders as a 2-column, 3-row grid of small filled circles — the
   standard "six-dot grip" pattern recognised as a drag handle.
   ────────────────────────────────────────────────────────────────── */
function GripDots() {
  return (
    <svg width="10" height="14" viewBox="0 0 10 14" fill="currentColor" aria-hidden="true">
      <circle cx="2.5" cy="2"  r="1.5" />
      <circle cx="7.5" cy="2"  r="1.5" />
      <circle cx="2.5" cy="7"  r="1.5" />
      <circle cx="7.5" cy="7"  r="1.5" />
      <circle cx="2.5" cy="12" r="1.5" />
      <circle cx="7.5" cy="12" r="1.5" />
    </svg>
  );
}
