/* SER-OS — Read-Only Arrangement Screen
   ──────────────────────────────────────────────────────────────────
   PROPOSAL-STYLE LAYOUT
   This screen is the live counterpart to the printed Service Summary
   Form. It is NOT a CRM read-out — it is a presentation surface that
   the FD reviews with the family. So:
     • document-feel background (cream, not cool blue-grey)
     • hero cover with the deceased name set in the brand display face
     • selected Package and Casket appear as feature cards with imagery
     • Add-ons render with the same thumbnails used during selection
     • pricing summary leads with a single Total, GST shown beneath
     • Draft / Awaiting / Confirmed / Amendment Mode each get a calm,
       immediately recognisable banner + (for Amendment Mode) a subtle
       blue tint across the whole document body.
   ────────────────────────────────────────────────────────────────── */

/* ── Status token resolution ───────────────────────────────────── */
function stateConfig(confirmationStatus, showSignedAnimation) {
  if (showSignedAnimation && (confirmationStatus === "confirmed" || confirmationStatus === "confirmed_updated")) {
    return { key: "just-signed", label: "Signed in Odoo", tone: "success" };
  }
  switch (confirmationStatus) {
    case "awaiting":          return { key: "awaiting",         label: "Awaiting Customer Signature",  tone: "warning" };
    case "amended_awaiting":  return { key: "amended_awaiting", label: "Amendment Awaiting Signature", tone: "warning" };
    case "confirmed":         return { key: "confirmed",        label: "Confirmed Arrangement",        tone: "success" };
    case "confirmed_updated": return { key: "confirmed",        label: "Confirmed Arrangement",        tone: "success" };
    case "amendment_draft":   return { key: "amendment_draft",  label: "Amendment Mode",               tone: "info"    };
    default:                  return { key: "draft",            label: "In Progress",                  tone: "neutral" };
  }
}

function tonePalette(tone) {
  switch (tone) {
    case "success": return { dot: "var(--status-success)",    fg: "var(--status-success-fg)", bg: "rgba(156,174,130,0.14)", border: "rgba(156,174,130,0.45)" };
    case "warning": return { dot: "var(--status-warning)",    fg: "var(--status-warning)",    bg: "rgba(194,138,69,0.10)",  border: "rgba(194,138,69,0.40)" };
    case "info":    return { dot: "var(--brand-navy)",        fg: "var(--brand-navy)",        bg: "rgba(0,49,105,0.06)",    border: "rgba(0,49,105,0.22)"  };
    case "neutral":
    default:        return { dot: "var(--fg-tertiary)",       fg: "var(--fg-secondary)",      bg: "var(--slate-100)",       border: "var(--border-subtle)" };
  }
}

/* ─────────────────────────────────────────────────────────────────
   MAIN COMPONENT
   ───────────────────────────────────────────────────────────────── */
function ReadOnlyArrangementScreen({
  caseDetails,
  serviceData,
  selectedPackage,
  selectedCasket,
  selectedAddOns = [],
  addOnTotal = 0,
  notes = "",
  confirmationStatus = "confirmed",
  caseVersionHistory = [],
  initialShowEditWarning = false,
  confirmedAt = null,
  showSignedAnimation = false,
  onBack,
  onViewPdf,
  onSendSignedForm,
  onSendReminder,
  onEnterEditMode,
  onSimulateSign,
  onCancelCase,
  onViewHistoricalVersion,
  contacts = [],
  appliedCoupon = null,
}) {
  const [showMoreActions, setShowMoreActions] = React.useState(false);
  const moreActionsRef = React.useRef(null);

  React.useEffect(() => { window.scrollTo({ top: 0, behavior: "instant" }); }, []);

  React.useEffect(() => {
    if (!showMoreActions) return;
    const handler = (e) => {
      if (moreActionsRef.current && !moreActionsRef.current.contains(e.target)) setShowMoreActions(false);
    };
    document.addEventListener("mousedown", handler);
    return () => document.removeEventListener("mousedown", handler);
  }, [showMoreActions]);

  const isSigned          = confirmationStatus === "confirmed" || confirmationStatus === "confirmed_updated";
  const isAwaiting        = confirmationStatus === "awaiting"  || confirmationStatus === "amended_awaiting";
  const isAmendmentMode   = confirmationStatus === "amendment_draft";
  const state             = stateConfig(confirmationStatus, showSignedAnimation);
  const palette           = tonePalette(state.tone);

  const pkgPrice      = selectedPackage ? selectedPackage.price : 0;
  const casketUpgrade = selectedCasket  ? (selectedCasket.included ? 0 : (selectedCasket.upgrade || 0)) : 0;
  const subtotal      = pkgPrice + casketUpgrade + addOnTotal;
  const coupons       = Array.isArray(appliedCoupon) ? appliedCoupon : (appliedCoupon ? [appliedCoupon] : []);
  const discountCs    = coupons.filter((c) => c.type === "discount");
  const couponAmt     = discountCs.reduce((sum, c) => sum + (c.amount || 0), 0);
  const adjustedSub   = Math.max(0, subtotal - couponAmt);
  const gst           = adjustedSub * 0.09;
  const finalTotal    = adjustedSub * 1.09;
  const realAddOns    = selectedAddOns.filter(it => it.itemType !== "section" && it.itemType !== "note");

  const syncTime = React.useMemo(
    () => new Date().toLocaleTimeString("en-SG", { hour: "2-digit", minute: "2-digit" }),
    []
  );

  const roDate = (iso) => {
    if (!iso) return null;
    try { return new Date(iso.length > 10 ? iso : iso + "T12:00:00").toLocaleDateString("en-SG", { day: "numeric", month: "short", year: "numeric" }); }
    catch { return iso; }
  };
  const roDT = (v) => {
    if (!v) return null;
    const [datePart, timePart] = v.split("T");
    const d = roDate(datePart);
    const t = timePart ? timePart.slice(0, 5) : null;
    return [d, t].filter(Boolean).join(", ");
  };

  const workspace   = caseDetails?.brand === "Fountains Funerals" ? "fountains" : "serenity";
  const isFountains = workspace === "fountains";
  const roReligion  = (serviceData?.religion || caseDetails?.religion || "").toLowerCase();
  const isChristian = roReligion === "christian";
  const isCatholic  = roReligion === "catholic";
  const isChristianOrCatholic = isChristian || isCatholic;

  /* ── Contacts ── */
  const contactsById = React.useMemo(
    () => Object.fromEntries((contacts || []).map((c) => [c.id, c])),
    [contacts]
  );
  const primaryContact   = serviceData?.primaryContactId   ? contactsById[serviceData.primaryContactId]   : null;
  const secondaryContact = serviceData?.secondaryContactId ? contactsById[serviceData.secondaryContactId] : null;
  const maritalLabel = { S: "Single", M: "Married", D: "Divorced", W: "Widowed" }[serviceData?.maritalStatus] || serviceData?.maritalStatus || null;

  const familyTree = serviceData?.family || {};
  const ftSum = (o) => Object.values(o || {}).reduce((a, b) => a + (Number(b) || 0), 0);
  const familyTreeGroups = [
    { name: "Children", total: ftSum(familyTree.children), items: [
      ["son",           "Son",             Number(familyTree.children?.son)           || 0],
      ["daughter",      "Daughter",        Number(familyTree.children?.daughter)      || 0],
      ["sonInLaw",      "Son-in-Law",      Number(familyTree.children?.sonInLaw)      || 0],
      ["daughterInLaw", "Daughter-in-Law", Number(familyTree.children?.daughterInLaw) || 0],
    ]},
    { name: "Siblings", total: ftSum(familyTree.siblings), items: [
      ["elderBrother",        "Elder Brother",          Number(familyTree.siblings?.elderBrother)        || 0],
      ["youngerBrother",      "Younger Brother",        Number(familyTree.siblings?.youngerBrother)      || 0],
      ["elderSister",         "Elder Sister",           Number(familyTree.siblings?.elderSister)         || 0],
      ["youngerSister",       "Younger Sister",         Number(familyTree.siblings?.youngerSister)       || 0],
      ["elderBrotherInLaw",   "Elder Brother-in-Law",   Number(familyTree.siblings?.elderBrotherInLaw)   || 0],
      ["youngerBrotherInLaw", "Younger Brother-in-Law", Number(familyTree.siblings?.youngerBrotherInLaw) || 0],
      ["elderSisterInLaw",    "Elder Sister-in-Law",    Number(familyTree.siblings?.elderSisterInLaw)    || 0],
      ["youngerSisterInLaw",  "Younger Sister-in-Law",  Number(familyTree.siblings?.youngerSisterInLaw)  || 0],
    ]},
    { name: "Paternal Grandchildren", total: ftSum(familyTree.paternal), items: [
      ["elderGrandson",      "Elder Grandson",          Number(familyTree.paternal?.elderGrandson)      || 0],
      ["grandson",           "Grandson",                Number(familyTree.paternal?.grandson)           || 0],
      ["grandsonInLaw",      "Grandson-in-Law",         Number(familyTree.paternal?.grandsonInLaw)      || 0],
      ["granddaughter",      "Grand-Daughter",          Number(familyTree.paternal?.granddaughter)      || 0],
      ["granddaughterInLaw", "Grand-Daughter-in-Law",   Number(familyTree.paternal?.granddaughterInLaw) || 0],
      ["greatGrandson",      "Great Grandson",          Number(familyTree.paternal?.greatGrandson)      || 0],
    ]},
    { name: "Maternal Grandchildren", total: ftSum(familyTree.maternal), items: [
      ["grandson",           "Grandson",                Number(familyTree.maternal?.grandson)           || 0],
      ["granddaughter",      "Grand-Daughter",          Number(familyTree.maternal?.granddaughter)      || 0],
      ["granddaughterInLaw", "Grand-Daughter-in-Law",   Number(familyTree.maternal?.granddaughterInLaw) || 0],
      ["grandsonInLaw",      "Grandson-in-Law",         Number(familyTree.maternal?.grandsonInLaw)      || 0],
      ["greatGrandson",      "Great Grandson",          Number(familyTree.maternal?.greatGrandson)      || 0],
    ]},
  ];
  const familyTreeHasData = familyTreeGroups.some((g) => g.total > 0);

  const hasCareInfo    = !!(serviceData?.transferLocationType || serviceData?.transferLocation || (Array.isArray(serviceData?.embalmingOptions) ? serviceData.embalmingOptions.length > 0 : serviceData?.embalmingRequired) || serviceData?.embalmingRemarks);
  const hasPastoralData = !isFountains && isChristianOrCatholic && !!(
    serviceData?.church || serviceData?.pastor || serviceData?.memorialServiceDateTime ||
    serviceData?.parish || serviceData?.nightlyPrayersDateTime ||
    serviceData?.churchMass || serviceData?.churchMassDetails || serviceData?.massDateTime
  );

  const pageBg = isAmendmentMode
    ? "linear-gradient(180deg, rgba(0,49,105,0.04) 0%, rgba(0,49,105,0.02) 600px, transparent 1200px), var(--surface-app)"
    : "var(--surface-app)";

  return (
    <div style={{ minHeight: "calc(100vh - 84px)", background: pageBg }}>
      <StickyTopBar
        caseDetails={caseDetails}
        state={state}
        palette={palette}
        syncTime={syncTime}
        isSigned={isSigned}
        isAwaiting={isAwaiting}
        onBack={onBack}
        onViewPdf={onViewPdf}
        onEnterEditMode={onEnterEditMode}
        onSendSignedForm={onSendSignedForm}
        onSendReminder={onSendReminder}
        onSimulateSign={onSimulateSign}
        onCancelCase={onCancelCase}
        showMoreActions={showMoreActions}
        setShowMoreActions={setShowMoreActions}
        moreActionsRef={moreActionsRef}
      />

      <div style={{
        maxWidth: 1180, margin: "0 auto",
        padding: "32px 48px 96px",
        display: "flex", flexDirection: "column", gap: 18,
      }}>
        <StateBanner state={state} confirmedAt={confirmedAt} />

        <HeroCover
          caseDetails={caseDetails}
          serviceData={serviceData}
          primaryContact={primaryContact}
          roDate={roDate}
        />

        <ProposalSection title="Selected Package">
          <PackageFeature pkg={selectedPackage} price={pkgPrice} />
        </ProposalSection>

        <ProposalSection title="Selected Casket">
          <CasketFeature casket={selectedCasket} upgrade={casketUpgrade} />
        </ProposalSection>

        <ProposalSection title="Wake & Service">
          <DetailStrip rows={[
            ["Wake Venue", (() => {
              const type = serviceData?.wakeVenueType;
              if (!type && !serviceData?.wakeVenue) return null;
              if (type === "Parlour") {
                const p = serviceData.wakeVenueParlour;
                if (!p) return "Parlour";
                const loc = p === "Others" ? (serviceData.wakeVenueRemarks || null) : p;
                return loc ? `Parlour – ${loc}` : "Parlour";
              }
              if (type === "Church") {
                const c = serviceData.wakeVenueChurch;
                if (!c) return "Church";
                const loc = c === "Others" ? (serviceData.wakeVenueRemarks || null) : c;
                return loc ? `Church – ${loc}` : "Church";
              }
              if (type === "HDB") {
                const addr = serviceData.wakeVenueRemarks;
                return addr ? `HDB – ${addr}` : "HDB";
              }
              if (type === "Others") {
                const custom = serviceData.wakeVenueRemarks;
                return custom ? `Others – ${custom}` : "Others";
              }
              return type || serviceData.wakeVenue;
            })()],
            ["Wake commences", roDate(serviceData?.wakeStartDate)],
            ["Wake concludes", roDate(serviceData?.wakeEndDate)],
            ["Duration",       serviceData?.wakeDuration ? `${serviceData.wakeDuration} day${serviceData.wakeDuration !== "1" ? "s" : ""}` : null],
            ["Visiting hours", serviceData?.visitingHours],
          ].filter(Boolean)} />
        </ProposalSection>

        <ProposalSection title="Final Resting">
          <DetailStrip rows={[
            ["Funeral Arrangement",
              serviceData?.cremationOrBurial === "cremation" ? "Cremation"
              : serviceData?.cremationOrBurial === "burial"  ? "Burial"
              : serviceData?.cremationOrBurial === "others"  ? "Others"
              : null],
            ["Funeral Date", roDate(serviceData?.dispositionDate)],
            [serviceData?.cremationOrBurial === "cremation" ? "Cremation location"
              : serviceData?.cremationOrBurial === "burial" ? "Burial location"
              : "Location",
              serviceData?.cremationOrBurial === "cremation" ? serviceData?.cremationLocation
              : serviceData?.cremationOrBurial === "burial" ? serviceData?.burialLocation
              : null],
            serviceData?.cremationOrBurial === "cremation" ? (() => {
              const arr = serviceData?.restingArrangement === "Others"
                ? (serviceData?.finalRestingLocationOthers || null)
                : (serviceData?.restingArrangement || null);
              const loc = serviceData?.finalRestingLocation === "Others"
                ? (serviceData?.finalRestingLocationOthers || null)
                : (serviceData?.finalRestingLocation || null);
              const display = arr && loc ? `${arr} – ${loc}` : (arr || loc || null);
              return display ? ["Final resting", display] : null;
            })() : null,
            serviceData?.cremationOrBurial === "cremation" ? ["Final resting date / time", roDT(serviceData?.finalRestingDate)] : null,
            isFountains && serviceData?.prayerService ? ["Prayer service",
              Array.isArray(serviceData.prayerService)
                ? serviceData.prayerService.map(id => {
                    if (id === "others") return serviceData?.prayerServiceOthers || "Others";
                    return (window.PRAYER_SERVICE_OPTIONS || []).find(o => o.id === id)?.label || id;
                  }).join(" · ")
                : serviceData.prayerService] : null,
            isFountains && serviceData?.ancestorTabletLocation ? ["Ancestral tablet", serviceData.ancestorTabletLocation] : null,
          ].filter(Boolean)} />
          {serviceData?.dispositionRemarks && (
            <RemarkBlock label="Additional Information">{serviceData.dispositionRemarks}</RemarkBlock>
          )}
          {isFountains && serviceData?.jilingAnlingRemarks && (
            <RemarkBlock label="Anling / Jiling remarks">{serviceData.jilingAnlingRemarks}</RemarkBlock>
          )}
        </ProposalSection>

        {hasPastoralData && (
          <ProposalSection title="Pastoral Care">
            <DetailStrip rows={[
              isChristian && ["Church", serviceData.church],
              isChristian && ["Pastor", serviceData.pastor],
              isChristian && serviceData.memorialServiceDateTime && ["Memorial service date / time", serviceData.memorialServiceDateTime],
              isCatholic  && ["Parish church", serviceData.parish],
              isCatholic  && serviceData.nightlyPrayersDateTime && ["Nightly prayers", roDT(serviceData.nightlyPrayersDateTime)],
              isCatholic  && ["Church mass", serviceData.churchMass ? "Yes — required" : "No"],
              isCatholic  && serviceData.massDateTime && ["Mass date / time", roDT(serviceData.massDateTime)],
            ].filter(Boolean)} />
            {isCatholic && serviceData.churchMassDetails && (
              <RemarkBlock label="Mass location">{serviceData.churchMassDetails}</RemarkBlock>
            )}
          </ProposalSection>
        )}

        <ProposalSection title="Add-on Items">
          <AddonsList items={selectedAddOns} total={addOnTotal} />
        </ProposalSection>

        {notes && notes.trim() && (
          <ProposalSection title="Notes">
            <InternalNote>{notes}</InternalNote>
          </ProposalSection>
        )}

        <ProposalSection title="Pricing Summary">
          <PricingSummary
            subtotal={subtotal}
            discountCs={discountCs}
            gst={gst}
            finalTotal={finalTotal}
          />
        </ProposalSection>

        <SecondaryDivider>Case &amp; Family Information</SecondaryDivider>

        <ProposalSection title="Deceased Profile" muted>
          <DetailStrip rows={[
            ["Salutation",     serviceData?.salutations],
            ["Gender",         serviceData?.gender === "M" ? "Male" : serviceData?.gender === "F" ? "Female" : serviceData?.gender],
            ["Age",            serviceData?.age ? String(serviceData.age) : null],
            ["Date of birth",  roDate(serviceData?.dateOfBirth)],
            ["Date of death",  roDate(serviceData?.dateOfDeath)],
            ["Time of death",  serviceData?.timeOfDeath],
            isFountains && ["Marital status", maritalLabel],
            isFountains && ["Dialect",        serviceData?.dialect],
          ].filter(Boolean)} />
        </ProposalSection>

        <ProposalSection title="Family Contacts" muted>
          <ContactsBlock
            primary={primaryContact}
            secondary={secondaryContact}
            primaryRelationship={serviceData?.primaryRelationship}
            secondaryRelationship={serviceData?.secondaryRelationship}
            fallbackName={caseDetails?.contact}
            fallbackPhone={caseDetails?.phone}
          />
        </ProposalSection>

        {hasCareInfo && (
          <ProposalSection title="Preparation &amp; Care" muted>
            <DetailStrip rows={[
              (() => {
                const t = serviceData?.transferLocationType || serviceData?.transferLocation;
                if (!t) return null;
                const specific =
                  t === "Hospital"
                    ? (serviceData?.transferLocationHospital === "Others"
                        ? (serviceData?.transferLocationRemarks || "Others")
                        : serviceData?.transferLocationHospital) || null
                    : t === "Hospice"
                    ? (serviceData?.transferLocationHospice === "Others"
                        ? (serviceData?.transferLocationRemarks || "Others")
                        : serviceData?.transferLocationHospice) || null
                    : serviceData?.transferLocationRemarks || null;
                return ["Transfer Location", specific ? `${t} – ${specific}` : t];
              })(),
              (() => {
                const opts = Array.isArray(serviceData?.embalmingOptions) ? serviceData.embalmingOptions : [];
                if (opts.length === 0) return null;
                const labels = opts.map(id => {
                  const found = (window.EMBALMING_OPTIONS || []).find(o => o.id === id);
                  return found ? found.label : id;
                });
                return ["Embalming Options", labels.join(", ")];
              })(),
            ].filter(Boolean).filter(([_, v]) => v != null && v !== "")} />
            {serviceData?.embalmingRemarks && (
              <RemarkBlock label="Embalming Remarks">{serviceData.embalmingRemarks}</RemarkBlock>
            )}
          </ProposalSection>
        )}

        {isFountains && (serviceData?.survivingSpouse || serviceData?.survivingParents) && (
          <ProposalSection title="Family Record" muted>
            <DetailStrip rows={[
              ["Surviving spouse",  serviceData.survivingSpouse],
              ["Surviving parents", serviceData.survivingParents],
            ]} />
          </ProposalSection>
        )}

        {isFountains && familyTreeHasData && (
          <ProposalSection title="Family Tree" muted>
            <FamilyTreeBlock groups={familyTreeGroups} />
          </ProposalSection>
        )}

        {caseVersionHistory.length > 0 && (
          <ProposalSection
            title="Version History"
            muted
            badge={`${caseVersionHistory.length} version${caseVersionHistory.length !== 1 ? "s" : ""}`}
          >
            <VersionList versions={caseVersionHistory} onView={onViewHistoricalVersion} />
          </ProposalSection>
        )}

        {isAwaiting && onSimulateSign && (
          <PrototypeSimulateBlock onSimulateSign={onSimulateSign} />
        )}
      </div>
    </div>
  );
}

/* ═════════════════════════════════════════════════════════════════
   SUB-COMPONENTS
   ═════════════════════════════════════════════════════════════════ */

function StickyTopBar({
  caseDetails, state, palette, syncTime,
  isSigned, isAwaiting,
  onBack, onViewPdf, onEnterEditMode,
  onSendSignedForm, onSendReminder, onSimulateSign, onCancelCase,
  showMoreActions, setShowMoreActions, moreActionsRef,
}) {
  // Awaiting-state prototype actions live in the overflow so the primary
  // toolbar stays a calm three-CTA composition (View PDF / Enter Edit
  // Mode / Cancel Case). Removed: redundant status pill — the ModeBar
  // above already communicates the workflow state.
  const hasOverflow = isAwaiting && (onSendReminder || onSimulateSign);

  return (
    <div style={{
      position: "sticky", top: 108, zIndex: 49,
      background: "var(--surface-card)",
      borderBottom: "1px solid var(--border-subtle)",
      boxShadow: "0 1px 4px rgba(15,23,42,0.05)",
    }}>
      <div style={{
        maxWidth: 1440, margin: "0 auto", padding: "0 48px",
        display: "flex", alignItems: "center", gap: 14, height: 68,
      }}>
        {/* Left: back + title */}
        <Button
          variant="outline" size="sm"
          icon={<SerIcons.ChevronLeft size={13} color="#574F40" />}
          onClick={onBack}
          style={{ color: "#574F40", flexShrink: 0 }}>
          Back
        </Button>
        <div style={{ width: 1, height: 28, background: "var(--border-subtle)", flexShrink: 0 }} />
        <div style={{ flex: 1, minWidth: 0 }}>
          <div style={{
            fontSize: 13, fontWeight: 600, color: "var(--fg-primary)",
            letterSpacing: "-0.15px", whiteSpace: "nowrap",
            overflow: "hidden", textOverflow: "ellipsis",
          }}>
            {caseDetails?.deceased || "—"}
          </div>
          <div style={{
            fontSize: 11, color: "var(--fg-tertiary, #9CA8B8)",
            letterSpacing: "-0.05px", whiteSpace: "nowrap",
            overflow: "hidden", textOverflow: "ellipsis",
          }}>
            {caseDetails?.quotationId} · {caseDetails?.contact} · Last sync {syncTime}
          </div>
        </div>

        {/* Right: three CTAs */}
        <div style={{ display: "flex", alignItems: "center", gap: 8, flex: "0 0 auto" }}>
          <Button
            variant="outline" size="sm"
            icon={<SerIcons.Document size={16} />}
            onClick={onViewPdf}
            style={{ flexShrink: 0, whiteSpace: "nowrap" }}>
            View PDF
          </Button>

          <Button
            variant="primary-navy" size="sm"
            icon={<SerIcons.Edit size={16} />}
            onClick={onEnterEditMode}
            style={{ flexShrink: 0, whiteSpace: "nowrap" }}>
            Enter Edit Mode
          </Button>

          <Button
            variant="outline" size="sm"
            icon={<SerIcons.Close size={14} color="#8F4A45" />}
            onClick={onCancelCase}
            style={{ color: "#8F4A45", flexShrink: 0, whiteSpace: "nowrap" }}>
            Cancel Case
          </Button>

          {hasOverflow && (
            <div ref={moreActionsRef} style={{ position: "relative" }}>
              <IconButton
                onClick={() => setShowMoreActions((o) => !o)}
                title="More actions"
                ariaLabel="More actions"
              >
                <SerIcons.More size={18} />
              </IconButton>
              {showMoreActions && (
                <div style={{
                  position: "absolute", top: "calc(100% + 8px)", right: 0,
                  minWidth: 220, background: "var(--surface-card)",
                  border: "1px solid var(--border-subtle)",
                  borderRadius: 12,
                  boxShadow: "var(--shadow-overlay)",
                  padding: 6, zIndex: 60,
                }}>
                  {isAwaiting && onSendReminder && (
                    <OverflowMenuItem icon={<SerIcons.Mail size={16} />}
                      onClick={() => { setShowMoreActions(false); onSendReminder(); }}>
                      Send Reminder
                    </OverflowMenuItem>
                  )}
                  {isAwaiting && onSimulateSign && (
                    <OverflowMenuItem icon={<SerIcons.Check size={16} />}
                      onClick={() => { setShowMoreActions(false); onSimulateSign(); }}>
                      ⚙ Simulate: Customer Signs in Odoo
                    </OverflowMenuItem>
                  )}
                </div>
              )}
            </div>
          )}
        </div>
      </div>
    </div>
  );
}

function StateBanner({ state, confirmedAt }) {
  if (state.key === "draft") return null;

  const palette = tonePalette(state.tone);
  let icon = null, title = state.label, body = null;

  if (state.key === "awaiting" || state.key === "amended_awaiting") {
    icon = <SerIcons.Clock size={18} color={palette.fg} />;
    body = "The Service Summary Form has been sent to the customer via Odoo. No changes can be made until the customer signs or the form is recalled.";
  } else if (state.key === "just-signed") {
    icon = <SerIcons.Check size={18} color={palette.fg} />;
    body = "The customer's signature has been received. Syncing confirmation status to FD App…";
  } else if (state.key === "confirmed") {
    icon = <SerIcons.CheckCircle size={18} color={palette.fg} />;
    title = "Arrangement Confirmed";
    body = confirmedAt
      ? `Customer signed and confirmed via Odoo on ${new Date(confirmedAt).toLocaleDateString("en-SG", { day: "numeric", month: "long", year: "numeric" })} at ${new Date(confirmedAt).toLocaleTimeString("en-SG", { hour: "2-digit", minute: "2-digit" })}. To make changes, use Enter Edit Mode to begin an amendment.`
      : "Customer has signed and confirmed this arrangement via Odoo. To make changes, use Enter Edit Mode to begin an amendment.";
  } else if (state.key === "amendment_draft") {
    icon = <SerIcons.Edit size={18} color={palette.fg} />;
    title = "Amendment Mode";
    body = "You are editing a confirmed arrangement. Changes are not yet saved or sent to the customer.";
  }

  return (
    <div style={{
      display: "flex", alignItems: "flex-start", gap: 14,
      padding: "16px 20px", borderRadius: 12,
      background: palette.bg, border: `1px solid ${palette.border}`,
    }}>
      <div style={{
        width: 36, height: 36, borderRadius: "50%",
        background: "var(--surface-card)",
        display: "flex", alignItems: "center", justifyContent: "center",
        flexShrink: 0,
        boxShadow: "inset 0 0 0 1px " + palette.border,
      }}>
        {icon}
      </div>
      <div style={{ flex: 1, minWidth: 0 }}>
        <div style={{ fontSize: 14, fontWeight: 600, color: palette.fg, letterSpacing: "-0.15px", marginBottom: 3 }}>
          {title}
        </div>
        <div style={{ fontSize: 13, color: "var(--fg-secondary)", lineHeight: "20px", letterSpacing: "-0.1px" }}>
          {body}
        </div>
      </div>
    </div>
  );
}

function HeroCover({ caseDetails, serviceData, primaryContact, roDate }) {
  const dob = roDate(serviceData?.dateOfBirth);
  const dod = roDate(serviceData?.dateOfDeath);
  const religion = caseDetails?.religion ? titleCase(caseDetails.religion) : null;

  return (
    <section style={{
      background: "var(--surface-card)",
      border: "1px solid var(--border-subtle)",
      borderRadius: 16,
      padding: "40px 44px 36px",
      boxShadow: "0 1px 4px rgba(15,23,42,0.04)",
    }}>
      <div style={{
        fontSize: 11, fontWeight: 600, color: "var(--fg-tertiary)",
        textTransform: "uppercase", letterSpacing: "0.12em",
        marginBottom: 12,
      }}>
        Service Summary
      </div>
      <h1 style={{
        font: "var(--font-display)",
        fontFamily: "var(--font-display)",
        fontWeight: 500,
        fontSize: 44, lineHeight: "56px",
        letterSpacing: "0.01em",
        color: "var(--fg-primary)",
        margin: "0 0 6px",
      }}>
        {caseDetails?.deceased || "—"}
      </h1>
      <div style={{
        fontSize: 14, color: "var(--fg-secondary)",
        letterSpacing: "-0.15px", lineHeight: "20px",
      }}>
        {[dob && `Born ${dob}`, dod && `Passed ${dod}`, religion].filter(Boolean).join("  ·  ")}
      </div>

      <div style={{
        marginTop: 28, paddingTop: 24,
        borderTop: "1px solid var(--slate-150)",
        display: "grid", gridTemplateColumns: "repeat(4, 1fr)", gap: 24,
      }}>
        <KeyFact label="Case Number"    value={caseDetails?.quotationId} />
        <KeyFact label="Need Type"      value={caseDetails?.needType === "pre_need" ? "Pre-Need" : "At-Need"} />
        <KeyFact label="Family Representative"
                 value={primaryContact?.name || caseDetails?.contact || "—"}
                 sub={[serviceData?.primaryRelationship, fmtPhone(primaryContact?.mobile || primaryContact?.phone || caseDetails?.phone)].filter(Boolean).join("  ·  ")} />
        <KeyFact label="Assigned FD"    value={caseDetails?.fd || "—"} />
      </div>
    </section>
  );
}

function KeyFact({ label, value, sub }) {
  return (
    <div>
      <div style={{
        fontSize: 10, fontWeight: 600, color: "var(--fg-tertiary)",
        textTransform: "uppercase", letterSpacing: "0.10em", marginBottom: 6,
      }}>
        {label}
      </div>
      <div style={{ fontSize: 15, fontWeight: 500, color: "var(--fg-primary)", letterSpacing: "-0.2px", lineHeight: "22px" }}>
        {value || "—"}
      </div>
      {sub && (
        <div style={{ fontSize: 12, color: "var(--fg-secondary)", marginTop: 2, fontFeatureSettings: "'tnum'" }}>
          {sub}
        </div>
      )}
    </div>
  );
}

function ProposalSection({ title, badge, muted, children }) {
  return (
    <section style={{
      background: "var(--surface-card)",
      border: "1px solid var(--border-subtle)",
      borderRadius: 16,
      padding: "28px 32px",
      opacity: muted ? 0.96 : 1,
      boxShadow: "0 1px 4px rgba(15,23,42,0.04)",
    }}>
      <header style={{
        display: "flex", alignItems: "baseline", justifyContent: "space-between",
        marginBottom: 20,
      }}>
        <h2 style={{
          font: "var(--type-h2)",
          fontSize: muted ? 15 : 17,
          fontWeight: 600,
          letterSpacing: "-0.3px",
          color: "var(--fg-primary)",
          margin: 0,
        }}>
          {title}
        </h2>
        {badge && (
          <span style={{
            fontSize: 11, fontWeight: 600, color: "var(--fg-secondary)",
            background: "var(--slate-100)",
            padding: "3px 10px", borderRadius: 6,
            letterSpacing: "-0.05px",
          }}>
            {badge}
          </span>
        )}
      </header>
      {children}
    </section>
  );
}

function SecondaryDivider({ children }) {
  return (
    <div style={{
      display: "flex", alignItems: "center", gap: 16,
      margin: "12px 0 4px",
    }}>
      <div style={{ flex: 1, height: 1, background: "var(--slate-200)" }} />
      <span style={{
        fontSize: 11, fontWeight: 600, color: "var(--fg-tertiary)",
        textTransform: "uppercase", letterSpacing: "0.12em",
      }}>
        {children}
      </span>
      <div style={{ flex: 1, height: 1, background: "var(--slate-200)" }} />
    </div>
  );
}

function DetailStrip({ rows }) {
  if (!rows || rows.length === 0) return null;
  return (
    <div style={{
      display: "grid",
      gridTemplateColumns: "repeat(2, 1fr)",
      columnGap: 48, rowGap: 18,
    }}>
      {rows.map(([label, value], i) => (
        <div key={i} style={{ display: "flex", flexDirection: "column", gap: 4 }}>
          <span style={{ fontSize: 12, color: "var(--fg-tertiary)", letterSpacing: "-0.05px" }}>
            {label}
          </span>
          <span style={{
            fontSize: 15, color: "var(--fg-primary)", fontWeight: 500,
            letterSpacing: "-0.2px", lineHeight: "22px",
          }}>
            {value || "—"}
          </span>
        </div>
      ))}
    </div>
  );
}

function RemarkBlock({ label, children }) {
  return (
    <div style={{
      marginTop: 18, padding: "14px 16px",
      background: "var(--slate-100)",
      borderRadius: 10,
      border: "1px solid var(--border-subtle)",
    }}>
      <div style={{
        fontSize: 11, fontWeight: 600, color: "var(--fg-tertiary)",
        textTransform: "uppercase", letterSpacing: "0.1em",
        marginBottom: 4,
      }}>{label}</div>
      <p style={{
        margin: 0, fontSize: 14, color: "var(--fg-primary)",
        lineHeight: "22px", letterSpacing: "-0.1px",
      }}>{children}</p>
    </div>
  );
}

function PackageFeature({ pkg, price }) {
  if (!pkg) return <EmptyState>No package selected.</EmptyState>;
  return (
    <div>
      <div style={{ display: "flex", gap: 20, alignItems: "flex-start" }}>
        {pkg.image && (
          <div style={{
            width: 140, height: 96, flexShrink: 0,
            borderRadius: 10, overflow: "hidden",
            background: `var(--slate-100) center/cover no-repeat url(${pkg.image})`,
            boxShadow: "inset 0 0 0 1px var(--border-subtle)",
          }} />
        )}
        <div style={{ flex: 1, minWidth: 0 }}>
          <div style={{
            fontSize: 22, fontWeight: 500, color: "var(--fg-primary)",
            letterSpacing: "-0.4px", lineHeight: "28px",
          }}>
            {pkg.name}
          </div>
          {pkg.blurb && (
            <p style={{
              margin: "6px 0 0", fontSize: 14, color: "var(--fg-secondary)",
              lineHeight: "20px", letterSpacing: "-0.1px",
            }}>{pkg.blurb}</p>
          )}
          {pkg.venueLabel && (
            <div style={{
              marginTop: 10, display: "inline-flex", alignItems: "center", gap: 6,
              fontSize: 12, color: "var(--fg-secondary)",
              padding: "3px 10px", borderRadius: 6,
              background: "var(--surface-chip)",
              border: "1px solid var(--brand-tan-soft)",
            }}>
              <SerIcons.MapPin size={12} color="var(--fg-secondary)" />
              {pkg.venueLabel}
            </div>
          )}
        </div>
        <div style={{
          fontSize: 24, fontWeight: 500, color: "var(--fg-primary)",
          letterSpacing: "-0.4px", fontFeatureSettings: "'tnum'",
          flexShrink: 0,
        }}>
          {formatPrice(price)}
        </div>
      </div>

      {pkg.sections?.length > 0 && (
        <div style={{
          marginTop: 24, paddingTop: 20,
          borderTop: "1px solid var(--slate-150)",
          display: "grid", gridTemplateColumns: "repeat(2, 1fr)", columnGap: 40, rowGap: 18,
        }}>
          {pkg.sections.map((section, si) => (
            <div key={si}>
              <div style={{
                fontSize: 11, fontWeight: 600, color: "var(--fg-tertiary)",
                textTransform: "uppercase", letterSpacing: "0.10em",
                marginBottom: 8,
              }}>
                {section.name}
              </div>
              <ul style={{ listStyle: "none", padding: 0, margin: 0, display: "flex", flexDirection: "column", gap: 5 }}>
                {section.items.map((item, ii) => (
                  <li key={ii} style={{
                    display: "flex", alignItems: "flex-start", gap: 8,
                    fontSize: 13, color: "var(--fg-primary)", lineHeight: "20px",
                    letterSpacing: "-0.1px",
                  }}>
                    <SerIcons.Check size={12} color="var(--status-success)" style={{ marginTop: 4, flexShrink: 0 }} />
                    {item}
                  </li>
                ))}
              </ul>
            </div>
          ))}
        </div>
      )}
    </div>
  );
}

function CasketFeature({ casket, upgrade }) {
  const [activeImg, setActiveImg] = React.useState(0);
  if (!casket) return <EmptyState>No casket selected.</EmptyState>;
  const images = (casket.images && casket.images.length > 0) ? casket.images : (casket.image ? [casket.image] : []);
  const safeImg = Math.min(activeImg, Math.max(0, images.length - 1));

  return (
    <div style={{ display: "flex", gap: 28, alignItems: "flex-start" }}>
      <div style={{ width: 320, flexShrink: 0 }}>
        {images.length > 0 ? (
          <React.Fragment>
            <div style={{
              width: "100%", aspectRatio: "4 / 3",
              borderRadius: 12, overflow: "hidden",
              background: `var(--slate-100) center/cover no-repeat url(${images[safeImg]})`,
              boxShadow: "inset 0 0 0 1px var(--border-subtle)",
            }} />
            {images.length > 1 && (
              <div style={{ marginTop: 10, display: "flex", gap: 8 }}>
                {images.map((img, i) => (
                  <button
                    key={i}
                    onClick={() => setActiveImg(i)}
                    style={{
                      all: "unset", cursor: "pointer",
                      width: 56, height: 42, borderRadius: 6, overflow: "hidden",
                      background: `var(--slate-100) center/cover no-repeat url(${img})`,
                      boxShadow: i === safeImg
                        ? "inset 0 0 0 2px var(--brand-navy)"
                        : "inset 0 0 0 1px var(--border-subtle)",
                    }}
                  />
                ))}
              </div>
            )}
          </React.Fragment>
        ) : (
          <div style={{
            width: "100%", aspectRatio: "4 / 3",
            borderRadius: 12,
            background: "var(--surface-chip)",
            border: "1px dashed var(--brand-tan-soft)",
            display: "flex", alignItems: "center", justifyContent: "center",
            color: "var(--fg-tertiary)",
          }}>
            <SerIcons.Box size={32} color="var(--fg-tertiary)" />
          </div>
        )}
      </div>

      <div style={{ flex: 1, minWidth: 0, display: "flex", flexDirection: "column", gap: 14 }}>
        <div style={{ display: "flex", justifyContent: "space-between", gap: 16, alignItems: "flex-start" }}>
          <div>
            <div style={{
              fontSize: 24, fontWeight: 500, color: "var(--fg-primary)",
              letterSpacing: "-0.4px", lineHeight: "30px",
            }}>
              {casket.name}
            </div>
            <div style={{
              marginTop: 4, fontSize: 14, color: "var(--fg-secondary)",
              letterSpacing: "-0.1px",
            }}>
              {casket.finish} {casket.tier ? `· ${casket.tier}` : ""}
            </div>
          </div>
          <div style={{
            fontSize: 20, fontWeight: 500,
            color: casket.included ? "var(--status-success-fg)" : "var(--fg-primary)",
            letterSpacing: "-0.3px", fontFeatureSettings: "'tnum'",
            flexShrink: 0,
          }}>
            {casket.included ? "Included" : `+${formatPrice(upgrade)}`}
          </div>
        </div>

        <div style={{
          display: "grid", gridTemplateColumns: "1fr 1fr",
          columnGap: 32, rowGap: 12,
          paddingTop: 14, borderTop: "1px solid var(--slate-150)",
        }}>
          {[
            ["Material", casket.material],
            ["Interior", casket.interior],
            ["Design", casket.designHighlights],
          ].filter(([_, v]) => v).map(([label, value]) => (
            <div key={label}>
              <div style={{ fontSize: 11, fontWeight: 600, color: "var(--fg-tertiary)", textTransform: "uppercase", letterSpacing: "0.10em", marginBottom: 3 }}>
                {label}
              </div>
              <div style={{ fontSize: 13, color: "var(--fg-primary)", lineHeight: "20px", letterSpacing: "-0.1px" }}>
                {value}
              </div>
            </div>
          ))}
        </div>
      </div>
    </div>
  );
}

function AddonsList({ items, total }) {
  const realItems = items.filter(it => it.itemType !== "section" && it.itemType !== "note");
  if (realItems.length === 0 && items.filter(it => it.itemType === "note").length === 0) {
    return <EmptyState>No add-on items selected.</EmptyState>;
  }

  return (
    <React.Fragment>
      <ul style={{ listStyle: "none", padding: 0, margin: 0, display: "flex", flexDirection: "column" }}>
        {items.map((item, i) => {
          if (item.itemType === "section") {
            return (
              <li key={i} style={{
                fontSize: 11, fontWeight: 700, color: "var(--fg-tertiary)",
                textTransform: "uppercase", letterSpacing: "0.10em",
                padding: "16px 0 8px",
                borderTop: i === 0 ? "none" : "1px solid var(--slate-150)",
              }}>
                {item.name.replace(/^§\s*/, "")}
              </li>
            );
          }
          if (item.itemType === "note") {
            return (
              <li key={i} style={{
                fontSize: 13, color: "var(--fg-secondary)",
                fontStyle: "italic", padding: "6px 0",
                lineHeight: "20px", letterSpacing: "-0.1px",
              }}>
                {item.name}
              </li>
            );
          }
          const lineTotal = item.chargeType === "complimentary" ? 0 : item.unitPrice * item.quantity * (item.rentalDays || 1);
          let displayTotal = lineTotal;
          if (item.discountType === "percent" && item.discountValue > 0) displayTotal = lineTotal * (1 - item.discountValue / 100);
          else if (item.discountType === "fixed" && item.discountValue > 0) displayTotal = Math.max(0, lineTotal - item.discountValue);
          return (
            <li key={i} style={{
              display: "flex", alignItems: "center", gap: 14,
              padding: "12px 0",
              borderTop: i === 0 ? "none" : "1px solid var(--slate-150)",
            }}>
              <div style={{ flexShrink: 0 }}>
                {window.AddonThumbnail
                  ? <window.AddonThumbnail item={item} size={48} />
                  : <div style={{ width: 48, height: 48, borderRadius: 8, background: "var(--surface-chip)" }} />
                }
              </div>
              <div style={{ flex: 1, minWidth: 0 }}>
                <div style={{
                  fontSize: 14, fontWeight: 500, color: "var(--fg-primary)",
                  letterSpacing: "-0.15px", lineHeight: "20px",
                }}>
                  {item.name}
                </div>
                <div style={{ fontSize: 12, color: "var(--fg-secondary)", marginTop: 2, letterSpacing: "-0.05px" }}>
                  Qty {item.quantity}
                  {item.rentalDays && (
                    <span style={{ color: "var(--fg-tertiary)" }}> · {item.rentalDays} day{item.rentalDays > 1 ? "s" : ""}</span>
                  )}
                  {item.discountValue > 0 && (
                    <span style={{ marginLeft: 8, color: "var(--status-warning)" }}>
                      {item.discountType === "percent" ? `−${item.discountValue}%` : `−${formatPrice(item.discountValue)}`}
                    </span>
                  )}
                </div>
              </div>
              <div style={{
                flexShrink: 0,
                fontSize: 15, fontWeight: 500,
                color: item.chargeType === "complimentary" ? "var(--status-success-fg)" : "var(--fg-primary)",
                letterSpacing: "-0.2px", fontFeatureSettings: "'tnum'",
              }}>
                {item.chargeType === "complimentary" ? "Included" : formatPrice(displayTotal)}
              </div>
            </li>
          );
        })}
      </ul>

      {realItems.length > 0 && (
        <div style={{
          marginTop: 18, paddingTop: 16,
          borderTop: "1px solid var(--slate-200)",
          display: "flex", justifyContent: "space-between", alignItems: "baseline",
        }}>
          <span style={{ fontSize: 13, color: "var(--fg-secondary)", letterSpacing: "-0.1px" }}>
            {realItems.length} item{realItems.length !== 1 ? "s" : ""}
          </span>
          <span style={{ fontSize: 16, fontWeight: 500, color: "var(--fg-primary)", letterSpacing: "-0.25px", fontFeatureSettings: "'tnum'" }}>
            {formatPrice(total)}
          </span>
        </div>
      )}
    </React.Fragment>
  );
}

function PricingSummary({ subtotal, discountCs, gst, finalTotal }) {
  return (
    <div>
      <div style={{ display: "flex", flexDirection: "column" }}>
        <PriceRow label="Subtotal" value={formatPrice(subtotal)} />
        {discountCs.map((c) => (
          <PriceRow key={c.code}
            label={`Coupon (${c.code})`}
            value={`−${formatPrice(c.amount || 0)}`}
            tone="warning"
          />
        ))}
        <PriceRow label="GST (9%) — included" value={formatPrice(gst)} muted />
      </div>

      <div style={{
        marginTop: 18, padding: "22px 28px",
        background: "var(--brand-navy)",
        borderRadius: 12,
        display: "flex", justifyContent: "space-between", alignItems: "center",
        gap: 12, flexWrap: "wrap",
      }}>
        <div>
          <div style={{ fontSize: 13, fontWeight: 500, color: "rgba(255,255,255,0.72)", letterSpacing: "-0.05px", textTransform: "uppercase" }}>
            Total
          </div>
          <div style={{ fontSize: 11, color: "rgba(200,181,151,0.78)", marginTop: 4, letterSpacing: "0.02em" }}>
            Includes GST (9%): {formatPrice(gst)}
          </div>
        </div>
        <div style={{
          fontSize: 36, fontWeight: 500, color: "#FFFFFF",
          letterSpacing: "-0.8px", fontFeatureSettings: "'tnum'",
        }}>
          {formatPrice(finalTotal)}
        </div>
      </div>
    </div>
  );
}

function PriceRow({ label, value, muted, tone }) {
  const color = tone === "warning" ? "var(--status-warning)"
              : muted             ? "var(--fg-secondary)"
              :                     "var(--fg-primary)";
  return (
    <div style={{ display: "flex", justifyContent: "space-between", alignItems: "baseline", padding: "9px 0" }}>
      <span style={{ fontSize: 14, color, letterSpacing: "-0.1px" }}>{label}</span>
      <span style={{ fontSize: 14, color, fontWeight: 500, fontFeatureSettings: "'tnum'", letterSpacing: "-0.1px" }}>{value}</span>
    </div>
  );
}

function InternalNote({ children }) {
  return (
    <div style={{
      padding: "16px 18px",
      background: "var(--surface-chip)",
      border: "1px solid var(--brand-tan-soft)",
      borderRadius: 10,
    }}>
      <div style={{ display: "flex", alignItems: "center", gap: 6, marginBottom: 8 }}>
        <SerIcons.Notes size={14} color="var(--fg-secondary)" />
        <span style={{
          fontSize: 11, fontWeight: 600, color: "var(--fg-secondary)",
          textTransform: "uppercase", letterSpacing: "0.10em",
        }}>
          Internal Note · Not visible to family
        </span>
      </div>
      <p style={{
        margin: 0, fontSize: 14, color: "var(--fg-primary)",
        lineHeight: "22px", letterSpacing: "-0.1px",
      }}>{children}</p>
    </div>
  );
}

/* ── Contacts block ───────────────────────────────────────────── */
function ContactsBlock({ primary, secondary, primaryRelationship, secondaryRelationship, fallbackName, fallbackPhone }) {
  return (
    <div style={{ display: "flex", flexDirection: "column", gap: 24 }}>
      <ROContactCard
        eyebrow="Primary Family Contact"
        name={primary?.name || fallbackName}
        relationship={primaryRelationship}
        phone={primary?.mobile || primary?.phone || fallbackPhone}
        email={primary?.email}
      />
      {secondary && (
        <ROContactCard
          eyebrow="Secondary Family Contact"
          name={secondary.name}
          relationship={secondaryRelationship}
          phone={secondary.mobile || secondary.phone}
          email={secondary.email}
        />
      )}
    </div>
  );
}

function ROContactCard({ eyebrow, name, relationship, phone, email }) {
  return (
    <div>
      <div style={{
        fontSize: 11, fontWeight: 600, color: "var(--fg-tertiary)",
        textTransform: "uppercase", letterSpacing: "0.10em",
        marginBottom: 8,
      }}>
        {eyebrow}
      </div>
      <div style={{
        fontSize: 15, fontWeight: 500, color: "var(--fg-primary)",
        letterSpacing: "-0.2px", lineHeight: "22px",
      }}>
        {name || "—"}
        {relationship && (
          <span style={{ fontSize: 13, color: "var(--fg-secondary)", marginLeft: 10, letterSpacing: "-0.05px", fontWeight: 400 }}>
            {relationship}
          </span>
        )}
      </div>
      <div style={{ marginTop: 8, display: "flex", flexWrap: "wrap", gap: "6px 24px" }}>
        {phone && (
          <span style={{ display: "inline-flex", alignItems: "center", gap: 6, fontSize: 13, color: "var(--fg-primary)", fontFeatureSettings: "'tnum'" }}>
            <SerIcons.Phone size={14} color="var(--fg-secondary)" />{fmtPhone(phone)}
          </span>
        )}
        {email && (
          <span style={{ display: "inline-flex", alignItems: "center", gap: 6, fontSize: 13, color: "var(--fg-primary)" }}>
            <SerIcons.Mail size={14} color="var(--fg-secondary)" />{email}
          </span>
        )}
      </div>
    </div>
  );
}

function FamilyTreeBlock({ groups }) {
  return (
    <div style={{ display: "flex", flexDirection: "column", gap: 18 }}>
      {groups.map((group) => group.total > 0 && (
        <div key={group.name}>
          <div style={{
            fontSize: 11, fontWeight: 600, color: "var(--fg-tertiary)",
            textTransform: "uppercase", letterSpacing: "0.10em",
            marginBottom: 8,
          }}>
            {group.name}
          </div>
          <div style={{ display: "flex", flexWrap: "wrap", gap: "6px 10px" }}>
            {group.items.filter((it) => it[2] > 0).map((it) => (
              <span key={it[0]} style={{
                fontSize: 13, color: "var(--fg-primary)", fontWeight: 500,
                padding: "4px 10px", borderRadius: 6,
                background: "var(--slate-100)",
                border: "1px solid var(--border-subtle)",
                letterSpacing: "-0.1px",
              }}>
                {it[2]} {it[1]}
              </span>
            ))}
          </div>
        </div>
      ))}
    </div>
  );
}

function VersionList({ versions, onView }) {
  return (
    <div style={{ display: "flex", flexDirection: "column", gap: 8 }}>
      {versions.map((v, i) => (
        <button
          key={i}
          onClick={() => onView && onView(v)}
          onMouseEnter={(e) => { e.currentTarget.style.background = "var(--slate-100)"; }}
          onMouseLeave={(e) => { e.currentTarget.style.background = "var(--surface-card)"; }}
          style={{
            all: "unset", cursor: "pointer",
            display: "flex", justifyContent: "space-between", alignItems: "center",
            padding: "13px 16px", borderRadius: 10,
            width: "100%", boxSizing: "border-box",
            background: "var(--surface-card)", border: "1px solid var(--border-subtle)",
            transition: "background 120ms",
          }}
        >
          <div style={{ display: "flex", alignItems: "center", gap: 10 }}>
            <SerIcons.History size={16} color="var(--fg-secondary)" />
            <span style={{ fontSize: 14, fontWeight: 500, color: "var(--fg-primary)", letterSpacing: "-0.15px" }}>{v.label}</span>
            <span style={{
              fontSize: 10, fontWeight: 600, color: "var(--status-success-fg)",
              background: "rgba(156,174,130,0.14)", border: "1px solid rgba(156,174,130,0.45)",
              padding: "2px 7px", borderRadius: 4,
              textTransform: "uppercase", letterSpacing: "0.08em",
            }}>Signed</span>
          </div>
          <div style={{ display: "flex", alignItems: "center", gap: 12 }}>
            <span style={{ fontSize: 12, color: "var(--fg-tertiary)" }}>
              {v.timestamp ? new Date(v.timestamp).toLocaleDateString("en-SG", { day: "numeric", month: "short", year: "numeric" }) : "—"}
            </span>
            <SerIcons.Arrow size={14} color="var(--fg-tertiary)" />
          </div>
        </button>
      ))}
    </div>
  );
}

function EmptyState({ children }) {
  return (
    <div style={{
      padding: "18px 20px",
      background: "var(--slate-100)",
      border: "1px dashed var(--border-subtle)",
      borderRadius: 10,
      fontSize: 14, color: "var(--fg-secondary)",
      letterSpacing: "-0.1px",
    }}>
      {children}
    </div>
  );
}

function PrototypeSimulateBlock({ onSimulateSign }) {
  return (
    <div style={{
      padding: "14px 18px",
      borderRadius: 10,
      border: "1px dashed var(--slate-300)",
      background: "var(--surface-card)",
    }}>
      <p style={{
        fontSize: 11, fontWeight: 600, color: "var(--fg-tertiary)",
        margin: "0 0 8px", letterSpacing: "0.10em", textTransform: "uppercase",
      }}>
        Prototype only — not visible in production
      </p>
      <Button variant="dashed" size="sm" onClick={onSimulateSign}>
        ⚙ Simulate: Customer Signs &amp; Confirms in Odoo
      </Button>
    </div>
  );
}

/* ═════════════════════════════════════════════════════════════════
   HistoricalVersionScreen — frozen snapshot view
   ═════════════════════════════════════════════════════════════════ */
function HistoricalVersionScreen({ version: v, caseDetails, onBack }) {
  const [showPdfOverlay, setShowPdfOverlay] = React.useState(false);

  React.useEffect(() => { window.scrollTo({ top: 0, behavior: "instant" }); }, []);

  React.useEffect(() => {
    if (!showPdfOverlay) return;
    const handler = (e) => { if (e.key === "Escape") setShowPdfOverlay(false); };
    document.addEventListener("keydown", handler);
    return () => document.removeEventListener("keydown", handler);
  }, [showPdfOverlay]);

  const sd = v.serviceData  || {};
  const cd = v.caseDetails  || caseDetails || {};
  const frozenContacts = v.contacts || [];

  const pkgPrice      = v.package ? v.package.price : 0;
  const casketUpgrade = v.casket  ? (v.casket.included ? 0 : (v.casket.upgrade || 0)) : 0;
  const subtotal      = pkgPrice + casketUpgrade + (v.addOnTotal || 0);
  const vCoupons      = Array.isArray(v.appliedCoupon) ? v.appliedCoupon : (v.appliedCoupon ? [v.appliedCoupon] : []);
  const vDiscountCs   = vCoupons.filter((c) => c.type === "discount");
  const couponAmt     = vDiscountCs.reduce((sum, c) => sum + (c.amount || 0), 0);
  const adjSubtotal   = Math.max(0, subtotal - couponAmt);
  const gst           = adjSubtotal * 0.09;
  const finalTotal    = adjSubtotal * 1.09;

  const roDate = (iso) => {
    if (!iso) return null;
    try { return new Date(iso.length > 10 ? iso : iso + "T12:00:00").toLocaleDateString("en-SG", { day: "numeric", month: "short", year: "numeric" }); }
    catch { return iso; }
  };
  const roDT = (val) => {
    if (!val) return null;
    const [datePart, timePart] = val.split("T");
    const d = roDate(datePart);
    const t = timePart ? timePart.slice(0, 5) : null;
    return [d, t].filter(Boolean).join(", ");
  };

  const contactsById     = Object.fromEntries((frozenContacts || []).map(c => [c.id, c]));
  const primaryContact   = sd.primaryContactId   ? contactsById[sd.primaryContactId]   : null;
  const secondaryContact = sd.secondaryContactId ? contactsById[sd.secondaryContactId] : null;

  const isFountains = (cd.brand || "").toLowerCase().includes("fountain");

  const signedDateStr = v.timestamp
    ? new Date(v.timestamp).toLocaleDateString("en-SG", { day: "numeric", month: "long", year: "numeric" })
    : null;
  const signedTimeStr = v.timestamp
    ? new Date(v.timestamp).toLocaleTimeString("en-SG", { hour: "2-digit", minute: "2-digit" })
    : null;

  return (
    <div style={{ minHeight: "calc(100vh - 84px)", background: "var(--slate-100)" }}>
      <div style={{
        position: "sticky", top: 84, zIndex: 51,
        background: "var(--surface-chip)",
        borderBottom: "1px solid var(--brand-tan-soft)",
      }}>
        <div style={{
          maxWidth: 1180, margin: "0 auto", padding: "10px 48px",
          display: "flex", alignItems: "center", gap: 10, flexWrap: "wrap",
          fontSize: 12, letterSpacing: "-0.05px",
        }}>
          <SerIcons.Archive size={14} color="var(--fg-secondary)" />
          <span style={{ fontWeight: 600, color: "var(--fg-primary)", letterSpacing: "-0.05px", whiteSpace: "nowrap" }}>
            Viewing Historical Version
          </span>
          <span style={{ color: "var(--border-strong)" }}>·</span>
          <span style={{ color: "var(--fg-secondary)", whiteSpace: "nowrap" }}>
            Read-only · This version cannot be edited.
          </span>
        </div>
      </div>

      <div style={{
        position: "sticky", top: 122, zIndex: 50,
        background: "var(--surface-card)",
        borderBottom: "1px solid var(--border-subtle)",
        boxShadow: "0 1px 3px rgba(15,23,42,0.04)",
      }}>
        <div style={{
          maxWidth: 1180, margin: "0 auto", padding: "0 48px",
          display: "flex", alignItems: "center", gap: 18, height: 72,
        }}>
          <div style={{ display: "flex", alignItems: "center", gap: 14, flex: 1, minWidth: 0 }}>
            <IconButton onClick={onBack} title="Back to current case" ariaLabel="Back to current case">
              <SerIcons.ChevronLeft size={20} />
            </IconButton>
            <div style={{ width: 1, height: 28, background: "var(--border-subtle)" }} />
            <div style={{ display: "flex", flexDirection: "column", gap: 1, minWidth: 0 }}>
              <span style={{ fontSize: 15, fontWeight: 600, color: "var(--fg-primary)", letterSpacing: "-0.2px" }}>
                {v.label}
              </span>
              <span style={{ fontSize: 12, color: "var(--fg-secondary)" }}>
                {signedDateStr}{signedTimeStr ? ` at ${signedTimeStr}` : ""} · Historical record
              </span>
            </div>
            <div style={{
              display: "inline-flex", alignItems: "center", gap: 6,
              padding: "4px 12px", borderRadius: 9999,
              background: "rgba(156,174,130,0.14)", border: "1px solid rgba(156,174,130,0.45)",
            }}>
              <span style={{ width: 7, height: 7, borderRadius: "50%", background: "var(--status-success)" }} />
              <span style={{ fontSize: 12, fontWeight: 600, color: "var(--status-success-fg)", letterSpacing: "-0.05px" }}>Signed</span>
            </div>
          </div>
          <Button variant="outline" size="sm" icon={<SerIcons.Document size={16} />} onClick={() => setShowPdfOverlay(true)}>
            View Signed PDF
          </Button>
          <Button variant="ghost" size="sm" icon={<SerIcons.ChevronLeft size={16} />} onClick={onBack}>
            Back to Current Case
          </Button>
        </div>
      </div>

      <div style={{
        maxWidth: 1180, margin: "0 auto",
        padding: "32px 48px 96px",
        display: "flex", flexDirection: "column", gap: 18,
      }}>
        <HeroCover caseDetails={cd} serviceData={sd} primaryContact={primaryContact} roDate={roDate} />

        <ProposalSection title="Selected Package">
          <PackageFeature pkg={v.package} price={pkgPrice} />
        </ProposalSection>

        <ProposalSection title="Selected Casket">
          <CasketFeature casket={v.casket} upgrade={casketUpgrade} />
        </ProposalSection>

        <ProposalSection title="Wake & Service">
          <DetailStrip rows={[
            ["Wake Venue", (() => {
              const type = sd.wakeVenueType;
              if (!type && !sd.wakeVenue) return null;
              if (type === "Parlour") {
                const p = sd.wakeVenueParlour;
                if (!p) return "Parlour";
                const loc = p === "Others" ? (sd.wakeVenueRemarks || null) : p;
                return loc ? `Parlour – ${loc}` : "Parlour";
              }
              if (type === "Church") {
                const c = sd.wakeVenueChurch;
                if (!c) return "Church";
                const loc = c === "Others" ? (sd.wakeVenueRemarks || null) : c;
                return loc ? `Church – ${loc}` : "Church";
              }
              if (type === "HDB") {
                const addr = sd.wakeVenueRemarks;
                return addr ? `HDB – ${addr}` : "HDB";
              }
              if (type === "Others") {
                const custom = sd.wakeVenueRemarks;
                return custom ? `Others – ${custom}` : "Others";
              }
              return type || sd.wakeVenue;
            })()],
            ["Wake commences", roDate(sd.wakeStartDate)],
            ["Wake concludes", roDate(sd.wakeEndDate)],
            ["Duration",       sd.wakeDuration ? `${sd.wakeDuration} day${sd.wakeDuration !== "1" ? "s" : ""}` : null],
            ["Visiting hours", sd.visitingHours],
          ].filter(Boolean)} />
        </ProposalSection>

        <ProposalSection title="Final Resting">
          <DetailStrip rows={[
            ["Funeral Arrangement",
              sd.cremationOrBurial === "cremation" ? "Cremation"
              : sd.cremationOrBurial === "burial" ? "Burial"
              : sd.cremationOrBurial === "others" ? "Others"
              : null],
            ["Funeral Date", roDate(sd.dispositionDate)],
            [sd.cremationOrBurial === "cremation" ? "Cremation location"
              : sd.cremationOrBurial === "burial" ? "Burial location"
              : "Location",
              sd.cremationOrBurial === "cremation" ? sd.cremationLocation
              : sd.cremationOrBurial === "burial" ? sd.burialLocation
              : null],
            sd.cremationOrBurial === "cremation" ? (() => {
              const arr = sd.restingArrangement === "Others"
                ? (sd.finalRestingLocationOthers || null)
                : (sd.restingArrangement || null);
              const loc = sd.finalRestingLocation === "Others"
                ? (sd.finalRestingLocationOthers || null)
                : (sd.finalRestingLocation || null);
              const display = arr && loc ? `${arr} – ${loc}` : (arr || loc || null);
              return display ? ["Final resting", display] : null;
            })() : null,
            sd.cremationOrBurial === "cremation" ? ["Final resting date / time", roDT(sd.finalRestingDate)] : null,
          ].filter(Boolean)} />
        </ProposalSection>

        <ProposalSection title="Add-on Items">
          <AddonsList items={v.addOns || []} total={v.addOnTotal || 0} />
        </ProposalSection>

        {v.notes && v.notes.trim() && (
          <ProposalSection title="Notes">
            <InternalNote>{v.notes}</InternalNote>
          </ProposalSection>
        )}

        <ProposalSection title="Pricing Summary">
          <PricingSummary subtotal={subtotal} discountCs={vDiscountCs} gst={gst} finalTotal={finalTotal} />
        </ProposalSection>

        <SecondaryDivider>Case &amp; Family Information</SecondaryDivider>

        <ProposalSection title="Deceased Profile" muted>
          <DetailStrip rows={[
            ["Salutation",    sd.salutations],
            ["Gender",        sd.gender === "M" ? "Male" : sd.gender === "F" ? "Female" : sd.gender],
            ["Age",           sd.age ? String(sd.age) : null],
            ["Date of birth", roDate(sd.dateOfBirth)],
            ["Date of death", roDate(sd.dateOfDeath)],
            ["Time of death", sd.timeOfDeath],
          ].filter(Boolean)} />
        </ProposalSection>

        <ProposalSection title="Family Contacts" muted>
          <ContactsBlock
            primary={primaryContact}
            secondary={secondaryContact}
            primaryRelationship={sd.primaryRelationship}
            secondaryRelationship={sd.secondaryRelationship}
            fallbackName={cd.contact}
            fallbackPhone={cd.phone}
          />
        </ProposalSection>
      </div>

      {showPdfOverlay && (
        <div
          onClick={(e) => { if (e.target === e.currentTarget) setShowPdfOverlay(false); }}
          style={{
            position: "fixed", inset: 0, zIndex: 200,
            background: "rgba(10,18,30,0.72)",
            backdropFilter: "blur(3px)",
            display: "flex", alignItems: "flex-start", justifyContent: "center",
            padding: "32px 24px",
            overflowY: "auto",
          }}
        >
          <div style={{
            width: "100%", maxWidth: 780,
            borderRadius: 16,
            background: "var(--surface-card)",
            boxShadow: "0 24px 80px rgba(0,0,0,0.38)",
            overflow: "hidden",
            flexShrink: 0,
          }}>
            <div style={{
              display: "flex", alignItems: "center", justifyContent: "space-between",
              padding: "14px 20px",
              background: "var(--brand-navy)",
              borderBottom: "1px solid rgba(255,255,255,0.08)",
            }}>
              <div style={{ display: "flex", alignItems: "center", gap: 10 }}>
                <SerIcons.Document size={16} color="rgba(255,255,255,0.7)" />
                <span style={{ fontSize: 14, fontWeight: 600, color: "#FFFFFF", letterSpacing: "-0.15px" }}>
                  Service Summary Form — {v.label}
                </span>
                <span style={{
                  display: "inline-flex", alignItems: "center", gap: 4,
                  fontSize: 11, fontWeight: 600, color: "#8FCF7E",
                  background: "rgba(91,125,79,0.18)", border: "1px solid rgba(91,125,79,0.35)",
                  padding: "2px 9px", borderRadius: 4,
                  textTransform: "uppercase", letterSpacing: "0.08em",
                }}>
                  <SerIcons.Check size={10} color="#8FCF7E" />
                  Signed
                </span>
              </div>
              <button
                onClick={() => setShowPdfOverlay(false)}
                style={{
                  all: "unset", cursor: "pointer",
                  width: 30, height: 30, borderRadius: 6,
                  display: "flex", alignItems: "center", justifyContent: "center",
                  color: "rgba(255,255,255,0.7)",
                  background: "rgba(255,255,255,0.08)",
                }}
                onMouseEnter={e => e.currentTarget.style.background = "rgba(255,255,255,0.15)"}
                onMouseLeave={e => e.currentTarget.style.background = "rgba(255,255,255,0.08)"}
              >
                <SerIcons.Close size={18} color="#FFFFFF" />
              </button>
            </div>

            <div style={{ background: "var(--slate-50)" }}>
              {window.PdfDocumentContent ? (
                <window.PdfDocumentContent
                  caseDetails={cd}
                  serviceData={sd}
                  contacts={frozenContacts}
                  selectedPackage={v.package}
                  selectedCasket={v.casket}
                  selectedAddOns={v.addOns || []}
                  addOnTotal={v.addOnTotal || 0}
                  notes={v.notes || ""}
                  isSigned={true}
                  confirmedAt={v.timestamp}
                  appliedCoupon={vCoupons}
                />
              ) : (
                <div style={{ padding: 40, color: "var(--fg-secondary)" }}>PDF preview unavailable.</div>
              )}
            </div>

            <div style={{
              display: "flex", justifyContent: "center",
              padding: "16px 20px",
              background: "var(--slate-100)",
              borderTop: "1px solid var(--border-subtle)",
            }}>
              <Button variant="outline" size="md" onClick={() => setShowPdfOverlay(false)}>
                Close
              </Button>
            </div>
          </div>
        </div>
      )}
    </div>
  );
}

Object.assign(window, { ReadOnlyArrangementScreen, HistoricalVersionScreen });
