// ============================================================
// Nami Order Portal — Wizard shell + steps 1-4
// ============================================================

const WIZARD_STEPS = [
  { id: 1, name: "Deal info",                sub: "Name and primary contact" },
  { id: 2, name: "Account & services",       sub: "Customer details, apps, support" },
  { id: 3, name: "Commercial terms",         sub: "Trim, term, volume, billing, add-ons" },
  { id: 4, name: "Variants",                 sub: "Amendment Addendum builder" },
  { id: 5, name: "Post-signature workflow",  sub: "Stripe invoice automation, renewal hooks" },
  { id: 6, name: "Preview & send",           sub: "Validate and send draft to the customer" },
];

const ADDONS = [
  { id: "concierge",      name: "Concierge support", desc: "15-min P1 response, dedicated TAM", bundled: ["elite"] },
  { id: "carrier-grade",  name: "Carrier-Grade Infrastructure", desc: "Dedicated tenancy, 99.999% SLA" },
  { id: "co-create",      name: "Co-Create Pro Services", desc: "Joint design + experimentation engagement" },
  { id: "fully-managed",  name: "Fully Managed Pro Services", desc: "Nami runs your funnel end-to-end" },
];

// 3-year-deal YoY growth choices — mirror website pricing-engine's
// `Escalator = 0.10 | 0.20 | 0.30` constant.
const ESCALATOR_OPTIONS = [
  { value: 0.10, label: "Conservative", desc: "For stable, mature subscriber bases." },
  { value: 0.20, label: "Default",      desc: "Typical for actively-growing programs." },
  { value: 0.30, label: "Aggressive",   desc: "For early-stage hypergrowth." },
];

// ----- Wizard Shell -----

const Wizard = ({ deal, step, onStepChange, onUpdate, onCancel, onSendModal, onSubmitForLegal, onRequestException, onOpenPreview, getValidation, variantLayout }) => {
  const goNext = () => onStepChange(Math.min(6, step + 1));
  const goBack = () => onStepChange(Math.max(1, step - 1));

  return (
    <div className="main__inner">
      <button className="detail-header__back" onClick={onCancel}>
        <Icon name="chevronLeft" size={14} />
        Back to deals
      </button>

      <div className="page-header">
        <div>
          <h1 className="page-header__title">{deal.name}</h1>
          <div className="page-header__subtitle">
            {deal.customer} · {deal.trim ? <TrimChip trim={deal.trim} /> : "Trim not set"}
            {deal.tcv ? <> · <strong style={{ color: "var(--navy)" }}>{money(deal.tcv, { compact: true })} TCV</strong></> : null}
          </div>
        </div>
        <div className="flex gap-3">
          <button className="btn btn--ghost btn--sm">
            <Icon name="save" size={14} />
            Save draft
          </button>
        </div>
      </div>

      <div className="wizard">
        <div className="wizard__steps">
          {WIZARD_STEPS.map((s) => {
            const isActive = s.id === step;
            const isDone = s.id < step;
            return (
              <button
                key={s.id}
                className={`wizard__step ${isActive ? "is-active" : ""} ${isDone ? "is-done" : ""}`}
                onClick={() => onStepChange(s.id)}
              >
                <div className="wizard__step-num">
                  {isDone ? <Icon name="check" size={13} /> : s.id}
                </div>
                <div className="wizard__step-label">
                  <div className="name">{s.name}</div>
                  <div className="sub">{s.sub}</div>
                </div>
                <div className="wizard__connector" />
              </button>
            );
          })}
        </div>

        <div className="wizard__panel">
          <div className="wizard__panel-header">
            <div>
              <div className="eyebrow">Step {step} of 6</div>
              <h2>{WIZARD_STEPS[step - 1].name}</h2>
              <p>{STEP_BLURBS[step]}</p>
            </div>
            {step === 4 && (
              <div className="text-xs text-dim">
                {Object.keys(deal.variants || {}).filter((k) => deal.variants[k]).length} variants selected
              </div>
            )}
          </div>

          <div className="wizard__panel-body">
            {step === 1 && <StepInfo     deal={deal} onUpdate={onUpdate} />}
            {step === 2 && <StepAccount  deal={deal} onUpdate={onUpdate} />}
            {step === 3 && <StepCommercial deal={deal} onUpdate={onUpdate} />}
            {step === 4 && <StepVariants deal={deal} onUpdate={onUpdate} layout={variantLayout} onOpenPreview={onOpenPreview} />}
            {step === 5 && <StepPostSignature deal={deal} onUpdate={onUpdate} />}
            {step === 6 && <StepPreview  deal={deal} validation={getValidation()} onSendModal={onSendModal} onJump={onStepChange} onRequestException={onRequestException} />}
          </div>

          <div className="wizard__panel-footer">
            <div className="save-status">
              <span className="dot" /> Draft saved — last edit 3 minutes ago
            </div>
            <div className="footer-actions">
              {step > 1 && (
                <button className="btn btn--outline btn--sm" onClick={goBack}>
                  <Icon name="chevronLeft" size={14} />
                  Back
                </button>
              )}
              {step < 6 && (
                <button className="btn btn--alloy btn--sm" onClick={goNext}>
                  Next: {WIZARD_STEPS[step].name}
                  <Icon name="chevronRight" size={14} />
                </button>
              )}
              {step === 6 && (() => {
                const needsLegal = window.NAMI_DATA.dealNeedsLegal(deal);
                const blockedByLegal = needsLegal && deal.status !== "approved";
                if (blockedByLegal) {
                  return (
                    <button
                      className="btn btn--alloy btn--sm"
                      onClick={onSubmitForLegal}
                      title="One or more selected variants need counsel sign-off before this deal can ship."
                    >
                      <Icon name="warn" size={14} />
                      Submit for legal review
                    </button>
                  );
                }
                return (
                  <button className="btn btn--alloy btn--sm" onClick={onSendModal}>
                    <Icon name="send" size={14} />
                    Send to customer
                  </button>
                );
              })()}
            </div>
          </div>
        </div>
      </div>
    </div>
  );
};

const STEP_BLURBS = {
  1: "Name the deal so it shows up in your list. The customer entity is the legal name as it'll appear on the contract.",
  2: "Customer addresses, A/P email, and legal notices for this deal. CRM pre-fill happens here in v2.",
  3: "Trim, term length, volume commitment, billing mode, and add-ons. Payment terms live in the variant menu (Step 4) — default is Net 30.",
  4: "Pick from the pre-approved variant menu. The Amendment Addendum builds itself on the right as you select.",
  5: "Post-signature automation — Stripe invoice trigger, renewal hooks. Fires after the customer countersigns.",
  6: "Final read-through before you ship. Hard blocks must clear; warnings are confirmable.",
};

// ============================================================
// Step 1 — Deal info
// ============================================================
const StepInfo = ({ deal, onUpdate }) => {
  const [autoName, setAutoName] = React.useState(true);
  return (
    <div style={{ maxWidth: 640 }}>
      <div className="field">
        <label className="field__label">Customer legal entity <span className="req">*</span></label>
        <input className="input" value={deal.customer || ""} onChange={(e) => onUpdate({ customer: e.target.value })} placeholder="e.g. Atlas Media, Inc." />
        <div className="field__hint">The full legal name as it appears on incorporation documents.</div>
      </div>

      <div className="field">
        <label className="field__label">Deal name</label>
        <input className="input" value={deal.name || ""} onChange={(e) => { setAutoName(false); onUpdate({ name: e.target.value }); }} />
        <div className="field__hint">
          {autoName
            ? <>Auto-suggested from customer name + quarter. <button onClick={() => onUpdate({ name: `${deal.customerShort || "Customer"} — ${deal.trim ? deal.trim.charAt(0).toUpperCase() + deal.trim.slice(1) : "Trim"} — 2026Q2` })} style={{ background: "transparent", border: 0, color: "var(--blue-alloy)", cursor: "pointer", padding: 0, fontWeight: 600, fontSize: 12 }}>Use suggestion</button></>
            : <>You're using a custom name.</>}
        </div>
      </div>

      <div className="row">
        <div className="field">
          <label className="field__label">Primary contact name</label>
          <input className="input" value={deal.primaryContact?.name || ""} onChange={(e) => onUpdate({ primaryContact: { ...deal.primaryContact, name: e.target.value } })} placeholder="Devon Park" />
        </div>
        <div className="field">
          <label className="field__label">Primary contact email</label>
          <input className="input" value={deal.primaryContact?.email || ""} onChange={(e) => onUpdate({ primaryContact: { ...deal.primaryContact, email: e.target.value } })} placeholder="devon.park@atlasmedia.com" />
        </div>
      </div>
      <div className="field__hint">
        The day-to-day point of contact for this deal. The authorized signer is
        captured separately below — the customer can also confirm or change it
        from their review link.
      </div>

      <div className="field" style={{ marginTop: 18 }}>
        <div style={{ fontSize: 11, fontWeight: 700, color: "var(--dark-grey)", textTransform: "uppercase", letterSpacing: "0.08em", marginBottom: 8 }}>
          Authorized signer
        </div>
        <div className="row">
          <div className="field">
            <label className="field__label">Name</label>
            <input className="input" value={deal.contractAdmin?.name || ""} onChange={(e) => onUpdate({ contractAdmin: { ...deal.contractAdmin, name: e.target.value } })} placeholder="Margaret Holloway" />
          </div>
          <div className="field">
            <label className="field__label">Title</label>
            <input className="input" value={deal.contractAdmin?.title || ""} onChange={(e) => onUpdate({ contractAdmin: { ...deal.contractAdmin, title: e.target.value } })} placeholder="Chief Financial Officer" />
          </div>
        </div>
        <div className="field">
          <label className="field__label">Signer email</label>
          <input className="input" value={deal.contractAdmin?.email || ""} onChange={(e) => onUpdate({ contractAdmin: { ...deal.contractAdmin, email: e.target.value } })} placeholder="m.holloway@atlasmedia.com" />
          <div className="field__hint">
            DocuSign will route the customer signature request to this email. Must
            have authority to bind the customer entity.
          </div>
        </div>
      </div>

      <div className="field">
        <label className="field__label">Account executive</label>
        <select className="input" value={deal.ae || "Sarah Kim"} onChange={(e) => onUpdate({ ae: e.target.value })}>
          <option>Sarah Kim</option>
          <option>Devon Park</option>
          <option>Marcus Reid</option>
          <option>Olivia Tran</option>
        </select>
        <div className="field__hint">Your name pre-fills. Change if you're configuring a deal for a teammate.</div>
      </div>
    </div>
  );
};

// ============================================================
// Step 2 — Account & services
// ============================================================
const StepAccount = ({ deal, onUpdate }) => {
  const [sameAsCustomer, setSameAsCustomer] = React.useState(true);

  return (
    <div>
      <div className="kv-section">
        <h3>Customer addresses</h3>
        <div className="field">
          <label className="field__label">Customer address <span className="req">*</span></label>
          <textarea className="input" value={deal.customerAddress || ""} onChange={(e) => onUpdate({ customerAddress: e.target.value })} placeholder="Street, city, state, ZIP" />
        </div>

        <div className="field">
          <label className="field__label" style={{ display: "flex", alignItems: "center", gap: 10 }}>
            <button className={`toggle ${sameAsCustomer ? "is-on" : ""}`} onClick={() => setSameAsCustomer(!sameAsCustomer)} type="button"><span className="toggle__thumb" /></button>
            Billing address is same as customer address
          </label>
          {!sameAsCustomer && (
            <textarea className="input" placeholder="Billing address" style={{ marginTop: 10 }} />
          )}
        </div>

        <div className="field">
          <label className="field__label">A/P email address</label>
          <input className="input" value={deal.billingContact?.email || ""} onChange={(e) => onUpdate({ billingContact: { ...deal.billingContact, email: e.target.value } })} placeholder="ap@customer.com" />
          <div className="field__hint">Where Stripe invoices are sent. Customer can update from their review link.</div>
        </div>

        <div className="field">
          <label className="field__label">Legal Notices</label>
          <input className="input" value={deal.noticeAddress || ""} onChange={(e) => onUpdate({ noticeAddress: e.target.value })} placeholder="Attn: General Counsel, ..." />
          <div className="field__hint">Where legal notices are sent. Often "Attn: General Counsel" at customer HQ.</div>
        </div>
      </div>

      {/* Services aren't picked here — they're inherent to the trim
          (see featuresForTrim in pricing-engine.js). The wizard's Step 3
          tier cards surface the cumulative feature list, and the Order
          Form / customer review / DocuSign HTML doc render it from the
          same source. */}
    </div>
  );
};

// ============================================================
// Step 3 — Commercial terms
// ============================================================
const StepCommercial = ({ deal, onUpdate }) => {
  const trims = window.NAMI_DATA.TRIM_TIERS;
  const PRICING = window.NAMI_PRICING;
  const trimKey = deal.trim || "premier";
  const trim = trims[trimKey];
  // Default Y1 commit = the trim's minimum. The user can dial up; below
  // the minimum is a hard block (caught by validators).
  const defaultY1 = trim.minCommit * 1_000_000;
  const commits = deal.commits || [defaultY1];
  // YoY growth escalator for 3-year deals — Y2/Y3 commits are derived
  // (Y1-locked CPM × Y1 × (1+esc)^year). Three approved levels mirror
  // the website's pricing engine: 0.10 / 0.20 / 0.30.
  const escalator = deal.escalator || 0.20;
  const escForY = (y) => Math.round((commits[0] || defaultY1) * Math.pow(1 + escalator, y));
  const rateCardCpm = PRICING.effectiveCpm(commits[0] / 1_000_000, trimKey);
  const cpm = deal.cpm || rateCardCpm;
  const cpmIsOverride = Math.abs(cpm - rateCardCpm) > 0.05;
  // Full TCV via the engine — includes Concierge / Carrier-grade add-ons
  // and the billing + multi-year discounts. The wizard's display field
  // below shows the engine-derived total.
  const { tcv } = PRICING.computeDealTcv({ ...deal, commits, cpm });

  React.useEffect(() => {
    onUpdate({ tcv });
  }, [tcv]);

  const updateCommit = (i, val) => {
    const next = [...commits];
    next[i] = parseInt(val.replace(/[^0-9]/g, ""), 10) || 0;
    const termYears = deal.termYears || 1;
    // When Y1 changes on a multi-year deal, recompute Y2/Y3 from the
    // new Y1 × escalator. Y2/Y3 are read-only — they exist only as a
    // function of Y1 and the chosen growth rate.
    if (i === 0 && termYears >= 3) {
      next[1] = Math.round(next[0] * (1 + escalator));
      next[2] = Math.round(next[0] * (1 + escalator) * (1 + escalator));
    } else if (i === 0 && termYears === 2) {
      next[1] = Math.round(next[0] * (1 + escalator));
    }
    // Re-auto-populate CPM from the new Y1 unless overridden.
    const patch = { commits: next };
    if (i === 0 && !cpmIsOverride) {
      patch.cpm = PRICING.effectiveCpm(next[0] / 1_000_000, trimKey);
    }
    onUpdate(patch);
  };

  const setEscalator = (val) => {
    const y1 = commits[0] || defaultY1;
    const next = [y1, Math.round(y1 * (1 + val)), Math.round(y1 * (1 + val) * (1 + val))];
    onUpdate({ escalator: val, commits: next });
  };

  const selectTrim = (key) => {
    const newTrim = trims[key];
    // Always reset Y1 to the new trim's minimum on trim change — the
    // tiers cover very different deal sizes and carrying a 100M Elite
    // commit into a Pro deal (or vice-versa) leaves the deal in an
    // implausible state. AE can dial up from the minimum once on the
    // new trim.
    const newY1 = newTrim.minCommit * 1_000_000;
    // For multi-year terms, rebuild the escalator from the new Y1 so
    // Y2/Y3 stay internally consistent.
    const termYears = deal.termYears || 1;
    const newCommits = termYears >= 3
      ? [newY1, Math.round(newY1 * 1.2), Math.round(newY1 * 1.44)]
      : termYears === 2
        ? [newY1, Math.round(newY1 * 1.2)]
        : [newY1];
    // Elite bundles Concierge; everything else defaults to Standard.
    const newSupport = key === "elite" ? "concierge" : "standard";
    onUpdate({
      trim: key,
      commits: newCommits,
      cpm: PRICING.effectiveCpm(newY1 / 1_000_000, key),
      support: newSupport,
    });
  };

  return (
    <div>
      <div className="kv-section">
        <h3>Trim</h3>
        <div className="tier-grid">
          {Object.entries(trims).map(([key, t]) => {
            const isSelected = deal.trim === key;
            // Show the rate-card-effective CPM at the trim's minimum
            // commit — the most expensive case. Larger deals get cheaper
            // per the tiered usage breaks.
            const repr = t.cpmRepresentative;
            return (
              <div key={key} className={`tier-card ${isSelected ? "is-selected" : ""}`} onClick={() => selectTrim(key)}>
                <div className="tier-card__name">
                  {t.name}
                </div>
                <div className="tier-card__cpm">
                  ${repr.toFixed(2)}<small>/1K impr.</small>
                </div>
                <div className="tier-card__min">
                  From {t.minCommit}M impr/yr · ${(t.fee / 1000).toFixed(0)}K platform fee
                </div>
                <div className="tier-card__features">
                  {key !== "pro" && (
                    <div className="tier-card__inherits">
                      Everything in {key === "premier" ? "Pro" : "Premier"}, plus:
                    </div>
                  )}
                  <ul>
                    {(t.features || []).map((f, i) => (
                      <li key={i}><Icon name="check" size={12} /> {f}</li>
                    ))}
                  </ul>
                </div>
              </div>
            );
          })}
        </div>
      </div>

      <div className="section-divider" />

      <div className="kv-section">
        <h3>Subscription term</h3>

        <div className="field">
          <label className="field__label">Start date</label>
          <input className="input" type="date" value={deal.startDate || ""} onChange={(e) => onUpdate({ startDate: e.target.value })} />
        </div>

        <div className="field mt-4">
          <label className="field__label">Term length</label>
          <div className="segmented">
            <button
              className={deal.termYears === 1 ? "is-active" : ""}
              onClick={() => onUpdate({ termYears: 1, commits: commits.slice(0, 1) })}
            >1 yr</button>
            <button
              className={deal.termYears === 3 ? "is-active" : ""}
              onClick={() => {
                const y1 = commits[0] || defaultY1;
                onUpdate({
                  termYears: 3,
                  escalator,
                  commits: [y1, Math.round(y1 * (1 + escalator)), Math.round(y1 * (1 + escalator) * (1 + escalator))],
                });
              }}
            >3 yr</button>
          </div>
        </div>
      </div>

      <div className="section-divider" />

      <div className="kv-section mt-4">
        <h3>Volume commitment</h3>
        <div className="field__hint" style={{ marginBottom: 12 }}>
          Year-1 impressions committed. {(deal.termYears || 1) >= 3
            ? "Year 2 and Year 3 are derived from Year 1 × the YoY growth escalator below."
            : "Year-1 rate is locked across the contract term."}
        </div>

        {(deal.termYears || 1) >= 3 && (
          <div className="escalator-picker">
            {ESCALATOR_OPTIONS.map((opt) => {
              const isOn = Math.abs(escalator - opt.value) < 1e-9;
              return (
                <button
                  key={opt.value}
                  type="button"
                  className={`escalator-option ${isOn ? "is-selected" : ""}`}
                  onClick={() => setEscalator(opt.value)}
                >
                  <span className="escalator-option__radio" aria-hidden="true">
                    {isOn && <span className="escalator-option__dot" />}
                  </span>
                  <span className="escalator-option__body">
                    <span className="escalator-option__title">
                      {(opt.value * 100).toFixed(0)}% — {opt.label}
                    </span>
                    <span className="escalator-option__desc">{opt.desc}</span>
                  </span>
                </button>
              );
            })}
          </div>
        )}

        <div className="row row--3">
          {Array.from({ length: deal.termYears || 1 }).map((_, i) => {
            const isDerived = i > 0 && (deal.termYears || 1) >= 3;
            return (
              <div className="field" key={i}>
                <label className="field__label">
                  Year {i + 1} commitment
                  {isDerived && <span style={{ marginLeft: 6, fontSize: 10, color: "var(--dark-grey)", fontWeight: 600 }}>(derived)</span>}
                </label>
                <div style={{ position: "relative" }}>
                  <input
                    className="input"
                    value={(commits[i] || 0).toLocaleString()}
                    onChange={(e) => !isDerived && updateCommit(i, e.target.value)}
                    readOnly={isDerived}
                    style={isDerived
                      ? { paddingRight: 60, background: "var(--alice-grey)", fontWeight: 600 }
                      : { paddingRight: 60 }}
                  />
                  <span style={{ position: "absolute", right: 14, top: "50%", transform: "translateY(-50%)", color: "var(--dark-grey)", fontSize: 12 }}>impr.</span>
                </div>
                <div className="field__hint">≈ {fmtImpressions(commits[i] || 0)} · {money(((commits[i] || 0) / 1000) * cpm, { compact: true })}</div>
              </div>
            );
          })}
        </div>
      </div>

      <div className="row">
        <div className="field">
          <label className="field__label">CPM rate</label>
          <div style={{ position: "relative" }}>
            <input
              className="input"
              value={`$${cpm.toFixed(2)}`}
              readOnly
              style={{ background: "var(--alice-grey)", fontWeight: 700 }}
            />
          </div>
          <div className="field__hint">
            Rate-card effective CPM at {trim.name} · {(commits[0] / 1_000_000).toFixed(0)}M Y1. Recomputes automatically when Y1 commit changes; overrides route through Deal Desk exception.
          </div>
        </div>
        <div className="field">
          <label className="field__label">Total contract value</label>
          <input className="input" value={money(tcv, { compact: false })} readOnly style={{ background: "var(--alice-grey)", fontWeight: 700 }} />
          <div className="field__hint">Computed from commitments × CPM. Read-only.</div>
        </div>
      </div>

      <div className="section-divider" />

      <BillingSection deal={deal} onUpdate={onUpdate} />

      <div className="section-divider" />

      <AddonsSection deal={deal} onUpdate={onUpdate} trim={trim} />
    </div>
  );
};

// Add-ons — three groups (Support, Pro Services, Infrastructure). Each
// surfaces price + hours where applicable so the AE sees the real
// economics. Concierge auto-toggles on Elite (bundled); the others are
// straightforward picks.
const AddonsSection = ({ deal, onUpdate, trim }) => {
  const PRICING = window.NAMI_PRICING;
  const conciergeIncluded = !!trim?.conciergeIncluded;
  // Compute Y1 Concierge dollar value so the card shows actual cost,
  // not "≈ 15%". When Elite, it's bundled; we show "Included".
  const y1Sub = (deal.commits?.[0] || trim.minCommit * 1_000_000) / 1000 * (deal.cpm || trim.cpmRepresentative);
  const conciergeY1 = conciergeIncluded ? 0 : Math.max(y1Sub * PRICING.CONCIERGE_PCT, PRICING.CONCIERGE_MIN);

  const setSupport = (val) => onUpdate({ support: val });
  const setPS = (val) => onUpdate({ proServices: val });
  const toggleAddon = (id, on) => {
    const current = deal.addons || [];
    const next = on ? [...current.filter((x) => x !== id), id] : current.filter((x) => x !== id);
    onUpdate({ addons: next });
  };

  const support = deal.support || (conciergeIncluded ? "concierge" : "standard");
  const proServices = deal.proServices || "none";
  const hasCarrier = (deal.addons || []).includes("carrier-grade");

  return (
    <div className="kv-section">
      <h3>Add-ons</h3>

      <div className="addon-group">
        <div className="addon-group__label">Support</div>
        <div className="addon-grid">
          <AddonCard
            selected={support === "standard"}
            onClick={() => setSupport("standard")}
            name="Standard Support"
            priceLabel="Included"
            desc="99.99% uptime, 2hr P1 response, shared CSM rotation."
            disabled={conciergeIncluded}
          />
          <AddonCard
            selected={support === "concierge"}
            onClick={() => !conciergeIncluded && setSupport("concierge")}
            name="Concierge Support"
            priceLabel={conciergeIncluded ? "Bundled with Elite" : `${money(conciergeY1, { compact: true })}/yr  (15% of sub, $40K min)`}
            desc="99.999% uptime, 15-min P1, dedicated CSM, 100hrs pro services."
            ribbon={conciergeIncluded ? "Bundled" : null}
          />
        </div>
      </div>

      <div className="addon-group">
        <div className="addon-group__label">Professional Services</div>
        <div className="addon-grid addon-grid--3">
          <AddonCard
            selected={proServices === "none"}
            onClick={() => setPS("none")}
            name="None"
            priceLabel="—"
            desc="Customer's team handles design + experimentation."
          />
          <AddonCard
            selected={proServices === "cocreate"}
            onClick={() => setPS("cocreate")}
            name="Co-Create"
            priceLabel={`${money(PRICING.PROSERVICES.cocreate.price, { compact: true })}/yr  (${PRICING.PROSERVICES.cocreate.hours}hrs)`}
            desc="Joint design + experimentation with Nami solutions engineering."
          />
          <AddonCard
            selected={proServices === "fullymanaged"}
            onClick={() => setPS("fullymanaged")}
            name="Fully Managed"
            priceLabel={`${money(PRICING.PROSERVICES.fullymanaged.price, { compact: true })}/yr  (${PRICING.PROSERVICES.fullymanaged.hours}hrs)`}
            desc="Nami runs the funnel end-to-end; quarterly business reviews."
          />
        </div>
      </div>

      <div className="addon-group">
        <div className="addon-group__label">Infrastructure</div>
        <div className="addon-grid">
          <AddonCard
            selected={!hasCarrier}
            onClick={() => toggleAddon("carrier-grade", false)}
            name="Standard Infrastructure"
            priceLabel="Included"
            desc="Multi-tenant, regional failover, standard observability."
          />
          <AddonCard
            selected={hasCarrier}
            onClick={() => toggleAddon("carrier-grade", true)}
            name="Carrier-Grade Infrastructure"
            priceLabel={`${money(PRICING.CARRIER_PRICE, { compact: true })}/yr`}
            desc="Dedicated single-tenant infra, isolated CDN edges, audit-grade observability."
          />
        </div>
      </div>
    </div>
  );
};

const AddonCard = ({ selected, onClick, name, priceLabel, desc, disabled, ribbon }) => (
  <div
    className={`addon-card ${selected ? "is-selected" : ""} ${disabled ? "is-disabled" : ""}`}
    onClick={disabled ? undefined : onClick}
  >
    {ribbon && <span className="addon-card__ribbon">{ribbon}</span>}
    <div className="addon-card__head">
      <div className="addon-card__check">{selected && <Icon name="check" size={11} />}</div>
      <div className="addon-card__name">{name}</div>
    </div>
    <div className="addon-card__price">{priceLabel}</div>
    <div className="addon-card__desc">{desc}</div>
  </div>
);

// ============================================================
// Step 4 — Payment terms
// ============================================================
const BILLING_OPTIONS = [
  {
    key: "usage",
    label: "Usage",
    discount: 0,
    desc: "Monthly invoices billed in arrears against actual delivered impressions. No upfront commitment, no discount.",
  },
  {
    key: "annual",
    label: "Annual upfront",
    discount: 0.25,
    desc: "Annual invoice in advance. Customer commits to the year's volume. 25% off subscription + add-ons.",
  },
  {
    key: "quarterly",
    label: "Quarterly",
    discount: 0.10,
    desc: "Four invoices per year, in advance. Customer commits to the year's volume. 10% off subscription + add-ons.",
  },
];

// Billing-mode picker + payment-schedule preview. Lives in Step 3 next
// to the rest of the commercial terms. Three billing options with their
// discount percentages surfaced as aqua pills.
const BillingSection = ({ deal, onUpdate }) => {
  const billing = deal.cadence || "annual";
  return (
    <div className="kv-section">
      <h3>Billing</h3>
      <div className="billing-grid">
        {BILLING_OPTIONS.map((opt) => {
          const isSelected = billing === opt.key;
          return (
            <button
              key={opt.key}
              type="button"
              className={`billing-card ${isSelected ? "is-selected" : ""}`}
              onClick={() => onUpdate({ cadence: opt.key })}
            >
              <div className="billing-card__head">
                <span className="billing-card__name">{opt.label}</span>
                {opt.discount > 0 && (
                  <span className="billing-card__pill">{(opt.discount * 100).toFixed(0)}% off</span>
                )}
              </div>
              <div className="billing-card__desc">{opt.desc}</div>
            </button>
          );
        })}
      </div>
      <div className="field__hint" style={{ marginTop: 12 }}>
        Discounts apply to the subscription fee plus Concierge / Carrier-grade add-ons. 3-year terms stack another 5% off.
      </div>

      <div className="card" style={{ background: "var(--alice-grey)", border: "1px solid var(--strokes)", marginTop: 16, padding: 16 }}>
        <div style={{ display: "flex", alignItems: "flex-start", gap: 12 }}>
          <div style={{ color: "var(--blue-alloy)", marginTop: 2 }}><Icon name="info" size={18} /></div>
          <div>
            <div style={{ fontWeight: 700, color: "var(--navy)", marginBottom: 4 }}>Payment schedule preview</div>
            <div style={{ fontSize: 13, color: "var(--dark-grey)", lineHeight: 1.55 }}>
              {(() => {
                const trim = window.NAMI_DATA.TRIM_TIERS[deal.trim || "premier"];
                const cpm = deal.cpm || trim.cpmRepresentative;
                const commits = deal.commits || [trim.minCommit * 1_000_000];
                const term = deal.termYears || 1;
                if (billing === "usage") {
                  return `${term * 12} monthly invoices in arrears against actual delivered impressions. No upfront commit.`;
                }
                if (billing === "annual") {
                  return `${term} annual invoice${term === 1 ? "" : "s"} (per-year fees): ${commits.map((c) => money(((c || 0) / 1000) * cpm, { compact: true })).join(", ")}.`;
                }
                return `${term * 4} quarterly invoices (one quarter of each year's fee per cycle). First invoice due ${deal.netTerms || "Net 30"} from Effective Date.`;
              })()}
            </div>
          </div>
        </div>
      </div>
    </div>
  );
};

// Step 5 — Post-signature workflow. Currently just the Stripe automation
// toggle; renewal hooks land here later.
// Step 5 — Post-signature workflow. Three configurable automations that
// fire when the DocuSign Connect webhook reports the envelope completed.
// Each card has its own toggle + minimal settings. Real integration
// wiring (Slack webhook, Dropbox API, Stripe invoice creation) is
// scaffolded server-side — captured in TODO.md as the next layer.
const StepPostSignature = ({ deal, onUpdate }) => (
  <div style={{ maxWidth: 720 }}>
    <div className="field__hint" style={{ marginBottom: 18 }}>
      These automations fire when the DocuSign Connect webhook reports
      the envelope as fully signed. They don't affect what the customer
      sees in DocuSign.
    </div>
    <div className="flex-col gap-3">
      <StripeSection deal={deal} onUpdate={onUpdate} />
      <SlackSection deal={deal} onUpdate={onUpdate} />
      <DropboxSection deal={deal} onUpdate={onUpdate} />
    </div>
  </div>
);

// Slack: post a notification to a channel when the deal closes. Channel
// is a free-text input for now; in a real integration this would be a
// channel picker authenticated against the Nami workspace.
const SlackSection = ({ deal, onUpdate }) => {
  const cfg = deal.postSignSlack || {};
  const enabled = !!cfg.enabled;
  return (
    <div className="stripe-card" style={{ borderColor: enabled ? "rgba(74, 21, 75, 0.35)" : undefined }}>
      <div className="stripe-card__head">
        <div className="stripe-card__head-left">
          <div className="stripe-card__logo" style={{ background: "#4A154B" }}>#</div>
          <div>
            <div className="stripe-card__title">Slack — deal-closed notification</div>
            <div className="stripe-card__sub">Post a summary to a channel when the envelope signs.</div>
          </div>
        </div>
        <button
          className={`toggle ${enabled ? "is-on" : ""}`}
          onClick={() => onUpdate({ postSignSlack: { ...cfg, enabled: !enabled } })}
        >
          <span className="toggle__thumb" />
        </button>
      </div>
      {enabled && (
        <div className="stripe-card__body">
          <div className="field">
            <label className="field__label">Channel</label>
            <input
              className="input"
              placeholder="#nami-closed-deals"
              value={cfg.channel || ""}
              onChange={(e) => onUpdate({ postSignSlack: { ...cfg, channel: e.target.value } })}
            />
            <div className="field__hint">
              Posts <strong>"{deal.customer || "Customer"} signed — {money(deal.tcv || 0)} TCV"</strong> with a link to the deal record.
            </div>
          </div>
          <div className="invoice-trigger-row">
            <Icon name="sparkle" size={15} />
            <div>Real channel picker needs Slack OAuth + the bot scope. Captured in TODO as a follow-up.</div>
          </div>
        </div>
      )}
    </div>
  );
};

// Dropbox: drop the signed PDF into a folder. Folder path is free-text;
// real integration would resolve the path against the team Dropbox.
const DropboxSection = ({ deal, onUpdate }) => {
  const cfg = deal.postSignDropbox || {};
  const enabled = !!cfg.enabled;
  return (
    <div className="stripe-card" style={{ borderColor: enabled ? "rgba(0, 97, 255, 0.35)" : undefined }}>
      <div className="stripe-card__head">
        <div className="stripe-card__head-left">
          <div className="stripe-card__logo" style={{ background: "#0061FF" }}>D</div>
          <div>
            <div className="stripe-card__title">Dropbox — archive signed envelope</div>
            <div className="stripe-card__sub">Drop the fully-signed PDF into a team folder.</div>
          </div>
        </div>
        <button
          className={`toggle ${enabled ? "is-on" : ""}`}
          onClick={() => onUpdate({ postSignDropbox: { ...cfg, enabled: !enabled } })}
        >
          <span className="toggle__thumb" />
        </button>
      </div>
      {enabled && (
        <div className="stripe-card__body">
          <div className="field">
            <label className="field__label">Folder path</label>
            <input
              className="input"
              placeholder="/Sales/Signed Contracts/2026"
              value={cfg.folder || ""}
              onChange={(e) => onUpdate({ postSignDropbox: { ...cfg, folder: e.target.value } })}
            />
            <div className="field__hint">
              File will be named <strong>{(deal.customerShort || "customer").replace(/\W+/g, "-").toLowerCase()}-{deal.id || "deal"}.pdf</strong>.
            </div>
          </div>
          <div className="invoice-trigger-row">
            <Icon name="sparkle" size={15} />
            <div>Real folder picker needs Dropbox OAuth. Captured in TODO as a follow-up.</div>
          </div>
        </div>
      )}
    </div>
  );
};

// ----- Stripe auto-invoice section -----
const StripeSection = ({ deal, onUpdate }) => {
  const trims = window.NAMI_DATA.TRIM_TIERS;
  const t = trims[deal.trim || "premier"];
  const cpm = deal.cpm || t.cpmRepresentative;
  const commits = deal.commits || [t.minCommit * 1_000_000];
  const firstFee = (commits[0] || 0) / 1000 * cpm;
  const enabled = deal.stripeAutoInvoice ?? false;
  const dueDays = parseInt((deal.netTerms || "Net 30").replace(/\D/g, ""), 10) || 30;
  const dueDate = deal.startDate ? new Date(new Date(deal.startDate).getTime() + dueDays * 86400000).toISOString().slice(0, 10) : null;
  const billing = deal.cadence || "annual";
  // First invoice amount: annual = full Y1 fees, quarterly = quarter of
  // Y1, usage = month of Y1 (rough estimate; real usage bills against
  // actual delivered impressions).
  const firstAmount =
    billing === "usage"     ? firstFee / 12 :
    billing === "quarterly" ? firstFee / 4  :
    /* annual */              firstFee;
  const cadenceLabel =
    billing === "usage"     ? "Month 1 usage" :
    billing === "quarterly" ? "Q1" :
    "Year 1";
  const triggerCopy =
    billing === "usage"
      ? "Trigger fires once the deal becomes Active. Subsequent invoices auto-queue monthly based on delivered impressions."
      : billing === "quarterly"
        ? "Trigger fires when the deal becomes Active and the Effective Date is reached. Subsequent quarterly invoices auto-queue on the same day of each quarter."
        : `Trigger fires when the deal becomes Active and the Effective Date is reached. ${(deal.termYears || 1) - 1} additional annual invoices will queue at each contract anniversary.`;

  return (
    <div className="stripe-card">
      <div className="stripe-card__head">
        <div className="stripe-card__head-left">
          <div className="stripe-card__logo">S</div>
          <div>
            <div className="stripe-card__title">Stripe — invoice automation</div>
            <div className="stripe-card__sub">Trigger the first invoice automatically on the Effective Date.</div>
          </div>
        </div>
        <button
          className={`toggle ${enabled ? "is-on" : ""}`}
          onClick={() => onUpdate({ stripeAutoInvoice: !enabled })}
        >
          <span className="toggle__thumb" />
        </button>
      </div>

      {enabled && (
        <div className="stripe-card__body">
          <div style={{ fontSize: 13, color: "var(--dark-grey)", lineHeight: 1.55 }}>
            On <strong style={{ color: "var(--navy)" }}>{fmtDate(deal.startDate) || "the Effective Date"}</strong>, Nami will create a Stripe invoice for the first {billing === "annual" ? "annual" : billing === "quarterly" ? "quarterly" : "monthly usage"} charge. The invoice is sent to your billing contact and is collectible at <strong>{deal.netTerms || "Net 30"}</strong>.
          </div>

          <div className="invoice-preview">
            <div className="invoice-preview__head">
              <div>
                <div className="label">Stripe invoice — preview</div>
                <div className="num">INV-{(deal.id || "atlas").slice(0, 6).toUpperCase()}-001 · {deal.currency || "USD"}</div>
              </div>
              <div className="total">{money(firstAmount)}</div>
            </div>
            <div className="invoice-preview__body">
              <div className="invoice-line">
                <div>
                  <div className="invoice-line__desc">{t.name} subscription — {cadenceLabel}</div>
                  <div className="invoice-line__meta">
                    {fmtImpressions(billing === "annual" ? commits[0] : billing === "quarterly" ? Math.round((commits[0] || 0) / 4) : Math.round((commits[0] || 0) / 12))} impressions {billing === "usage" ? "delivered" : "committed"} @ ${cpm.toFixed(2)} CPM
                  </div>
                </div>
                <div className="invoice-line__amt">{money(firstAmount)}</div>
              </div>
              <div className="invoice-line">
                <div>
                  <div className="invoice-line__desc">Customer record</div>
                  <div className="invoice-line__meta">cus_{deal.id ? deal.id.replace(/[^a-z0-9]/gi, "").slice(0, 10) : "atlasmedia0"} · {deal.billingContact?.email || "ap@customer.com"}</div>
                </div>
                <div className="invoice-line__amt text-dim">—</div>
              </div>
              <div className="invoice-line">
                <div>
                  <div className="invoice-line__desc">Due date</div>
                  <div className="invoice-line__meta">{dueDate ? fmtDate(dueDate) : "—"} ({deal.netTerms || "Net 30"} from Effective Date)</div>
                </div>
                <div className="invoice-line__amt text-dim">—</div>
              </div>
            </div>
          </div>

          <div className="invoice-trigger-row">
            <Icon name="sparkle" size={15} />
            <div>
              {triggerCopy}
            </div>
          </div>

          <div style={{ display: "flex", gap: 10, marginTop: 12, flexWrap: "wrap" }}>
            <div style={{ fontSize: 12, color: "var(--dark-grey)" }}>
              Linked Stripe customer:
              <strong style={{ color: "var(--navy)", marginLeft: 4 }}>{deal.customerShort || deal.customer || "—"}</strong>
              <span style={{ marginLeft: 6, fontFamily: "ui-monospace, Menlo, monospace", color: "var(--blue-alloy)", fontSize: 11 }}>
                cus_{deal.id ? deal.id.replace(/[^a-z0-9]/gi, "").slice(0, 10) : "atlasmedia"}
              </span>
            </div>
            <button className="btn btn--ghost btn--sm" style={{ marginLeft: "auto", height: 28, padding: "0 10px", fontSize: 11.5 }}>
              <Icon name="edit" size={12} /> Re-link
            </button>
          </div>
        </div>
      )}
    </div>
  );
};

window.Wizard = Wizard;
