// Merchant Portal — rewards.com.sg

const { useState: useStateM, useRef: useRefM } = React;

const mInputStyle = {
  borderRadius:12, border:"1px solid rgba(132,227,243,0.18)",
  background:"rgba(255,255,255,0.04)", color:"#f1ece7",
  padding:"11px 14px", fontSize:"0.88rem", width:"100%",
  boxSizing:"border-box",
};

const mTextarea = {
  ...mInputStyle, minHeight:90, resize:"vertical",
  fontFamily:"'Manrope','Avenir Next','Segoe UI',sans-serif",
};

// ── OFFER STATUS BADGE ─────────────────────────────────────
function StatusBadge({ status }) {
  const map = {
    active:  { bg:"rgba(150,231,178,0.14)", color:"#96e7b2", label:"Active" },
    paused:  { bg:"rgba(255,150,70,0.14)",  color:"#ff9570", label:"Paused" },
    draft:   { bg:"rgba(139,151,171,0.14)", color:"#8b97ab", label:"Draft" },
    removed: { bg:"rgba(255,105,126,0.14)", color:"#ff697e", label:"Removed" },
    review:  { bg:"rgba(196,181,253,0.14)", color:"#c4b5fd", label:"In review" },
  };
  const s = map[status] || map.draft;
  return (
    <span style={{ padding:"3px 11px", borderRadius:999, fontSize:"0.69rem", fontWeight:800, background:s.bg, color:s.color }}>{s.label}</span>
  );
}

// ── OFFER CARD ─────────────────────────────────────────────
function OfferCard({ offer, onEdit, onPause, onRemove }) {
  const [confirmRemove, setConfirmRemove] = useStateM(false);
  return (
    <div style={{ borderRadius:18, background:"rgba(255,255,255,0.04)", border:"1px solid rgba(255,255,255,0.08)", overflow:"hidden" }}>
      <div style={{ height:4, background: offer.status === "active" ? "linear-gradient(90deg,#96e7b2,#84e3f3)" : offer.status === "paused" ? "linear-gradient(90deg,#ff9570,#ff697e44)" : "rgba(255,255,255,0.12)" }} />
      <div style={{ padding:"16px 18px" }}>
        <div style={{ display:"flex", justifyContent:"space-between", alignItems:"flex-start", marginBottom:10 }}>
          <div>
            <div style={{ fontWeight:700, color:"#f1ece7", fontSize:"0.94rem" }}>{offer.title}</div>
            <div style={{ fontSize:"0.74rem", color:"#8b97ab", marginTop:2 }}>{offer.audience} · {offer.channel} · {offer.category}</div>
          </div>
          <StatusBadge status={offer.status} />
        </div>

        {offer.subtitle && <div style={{ fontSize:"0.8rem", color:"#c6cedd", marginBottom:8 }}>{offer.subtitle}</div>}
        {offer.description && <div style={{ fontSize:"0.8rem", color:"#aeb8c9", lineHeight:1.65, marginBottom:12 }}>{offer.description}</div>}

        {offer.details?.length ? (
          <div style={{ display:"grid", gridTemplateColumns:"repeat(3,1fr)", gap:8, marginBottom:12 }}>
          {offer.details.map(([label,val]) => (
            <div key={label} style={{ borderRadius:10, padding:"10px 10px", background:"rgba(255,255,255,0.04)", border:"1px solid rgba(255,255,255,0.06)" }}>
              <div style={{ fontSize:"0.64rem", fontWeight:800, textTransform:"uppercase", letterSpacing:"0.1em", color:"#8b97ab", marginBottom:4 }}>{label}</div>
              <div style={{ fontSize:"0.82rem", fontWeight:700, color:"#84e3f3", lineHeight:1.45 }}>{val}</div>
            </div>
          ))}
          </div>
        ) : null}

        {offer.programs?.length ? (
          <div style={{ display:"grid", gap:8, marginBottom:12 }}>
            {offer.programs.map(program => (
              <div key={`${offer.id}-${program.title}`} style={{ borderRadius:12, padding:"12px 14px", background:"rgba(255,255,255,0.03)", border:"1px solid rgba(255,255,255,0.06)" }}>
                <div style={{ display:"flex", justifyContent:"space-between", gap:10, flexWrap:"wrap", marginBottom:4 }}>
                  <div style={{ fontWeight:700, fontSize:"0.83rem", color:"#f1ece7" }}>{program.title}</div>
                  {program.price ? <div style={{ fontSize:"0.74rem", fontWeight:800, color:"#fbbf24" }}>{program.price}</div> : null}
                </div>
                {program.description ? <div style={{ fontSize:"0.76rem", color:"#8b97ab", lineHeight:1.6 }}>{program.description}</div> : null}
              </div>
            ))}
          </div>
        ) : null}

        {offer.tags?.length ? (
          <div style={{ display:"flex", gap:8, flexWrap:"wrap", marginBottom:12 }}>
            {offer.tags.map(tag => (
              <span key={`${offer.id}-${tag}`} style={{ padding:"5px 10px", borderRadius:999, background:"rgba(255,255,255,0.06)", color:"#c6cedd", fontSize:"0.71rem", fontWeight:700 }}>{tag}</span>
            ))}
          </div>
        ) : null}

        {offer.notes?.length ? (
          <div style={{ display:"grid", gap:5, marginBottom:14 }}>
            {offer.notes.map(note => (
              <div key={`${offer.id}-${note}`} style={{ fontSize:"0.74rem", color:"#8b97ab", lineHeight:1.55 }}>• {note}</div>
            ))}
          </div>
        ) : null}

        <div style={{ display:"flex", gap:8 }}>
          <button onClick={onEdit} style={{ all:"unset", cursor:"pointer", padding:"7px 14px", borderRadius:999, border:"1px solid rgba(255,255,255,0.12)", color:"#c6cedd", fontSize:"0.78rem" }}>✏️ Edit</button>
          <button onClick={onPause}
            style={{ all:"unset", cursor:"pointer", padding:"7px 14px", borderRadius:999, border: offer.status === "paused" ? "1px solid rgba(150,231,178,0.3)" : "1px solid rgba(255,150,70,0.3)", color: offer.status === "paused" ? "#96e7b2" : "#ff9570", fontSize:"0.78rem" }}>
            {offer.status === "paused" ? "▶ Resume" : "⏸ Pause"}
          </button>
          {!confirmRemove ? (
            <button onClick={() => setConfirmRemove(true)} style={{ all:"unset", cursor:"pointer", padding:"7px 14px", borderRadius:999, border:"1px solid rgba(255,105,126,0.2)", color:"#ff697e", fontSize:"0.78rem" }}>🗑 Remove</button>
          ) : (
            <div style={{ display:"flex", gap:6, alignItems:"center" }}>
              <span style={{ fontSize:"0.76rem", color:"#ff697e" }}>Sure?</span>
              <button onClick={() => { onRemove(); setConfirmRemove(false); }} style={{ all:"unset", cursor:"pointer", padding:"6px 12px", borderRadius:999, background:"rgba(255,105,126,0.15)", color:"#ff697e", fontSize:"0.76rem", fontWeight:800 }}>Yes, remove</button>
              <button onClick={() => setConfirmRemove(false)} style={{ all:"unset", cursor:"pointer", padding:"6px 12px", borderRadius:999, border:"1px solid rgba(255,255,255,0.1)", color:"#8b97ab", fontSize:"0.76rem" }}>Cancel</button>
            </div>
          )}
        </div>
      </div>
    </div>
  );
}

// ── OFFER FORM (add / edit) ────────────────────────────────
const OFFER_CATEGORIES = ["Beauty","Health","Food & Drink","Flowers & Gifts","Wellness","Finance","Other"];
const REDEMPTION_MODES = [
  { id:"physical", label:"Physical visit", sub:"Client visits your outlet" },
  { id:"whatsapp", label:"WhatsApp", sub:"Client messages you to redeem" },
  { id:"digital", label:"Digital", sub:"Online / remote fulfilment" },
];
const MAX_CLAIM_WINDOWS = [
  { id:"daily", label:"Daily" },
  { id:"weekly", label:"Weekly" },
  { id:"fortnightly", label:"Every 2 weeks" },
  { id:"monthly", label:"Monthly" },
];
const RULE_OPTIONS = [
  ["meetingRequired","Client to meet the agent to claim","Useful when the agent wants a proper sit-down before releasing the voucher"],
  ["existingClientsOnly","Existing policyholders only","Keep this offer reserved for current policyholders if preferred"],
  ["agentFundedOnRedemption","Agent pays on redemption","Only charge the agent wallet after the client actually redeems"],
  ["promoCreditEligible","Promo credit eligible","Allow platform promo credits to offset part of the redemption"],
];

const toMoneyNumber = value => {
  const num = Number.parseFloat(String(value ?? "").replace(/[^0-9.]/g, ""));
  return Number.isFinite(num) ? num : 0;
};

const formatMoney = value => {
  const rounded = Math.round(value * 100) / 100;
  return rounded % 1 === 0 ? String(rounded.toFixed(0)) : String(rounded.toFixed(2));
};

function OfferForm({ initial, onSave, onCancel }) {
  const blank = {
    title:"",
    category:"Beauty",
    value:"",
    description:"",
    expiryDays:"",
    meetingRequired:false,
    existingClientsOnly:false,
    maxClaims:"",
    maxClaimsWindow:"monthly",
    agentFundedOnRedemption:false,
    promoCreditEligible:false,
    totalPrice:"",
    merchantDiscount:"",
    agentSpend:"",
    clientPays:"",
    redemptionModes:["physical"],
  };
  const [form, setForm] = useStateM(() => ({
    ...blank,
    ...(initial || {}),
    redemptionModes: Array.isArray(initial?.redemptionModes)
      ? initial.redemptionModes
      : initial?.redemptionMode
        ? [initial.redemptionMode]
        : blank.redemptionModes,
  }));
  const set = (k, v) => setForm(f => ({ ...f, [k]: v }));
  const toggleMulti = (k, v) => setForm(f => ({
    ...f,
    [k]: f[k].includes(v) ? f[k].filter(item => item !== v) : [...f[k], v],
  }));
  const pricingFieldOrder = ["totalPrice", "merchantDiscount", "agentSpend", "clientPays"];
  const filledPricingKeys = pricingFieldOrder.filter(key => String(form[key] ?? "").trim() !== "");
  const autoPricingKey = filledPricingKeys.length === 3 ? pricingFieldOrder.find(key => !filledPricingKeys.includes(key)) : null;
  const computedPricingValue = (() => {
    if (!autoPricingKey) return null;
    if (autoPricingKey === "totalPrice") {
      return toMoneyNumber(form.merchantDiscount) + toMoneyNumber(form.agentSpend) + toMoneyNumber(form.clientPays);
    }
    const total = toMoneyNumber(form.totalPrice);
    const otherKeys = pricingFieldOrder.filter(key => key !== "totalPrice" && key !== autoPricingKey);
    const remainder = total - otherKeys.reduce((sum, key) => sum + toMoneyNumber(form[key]), 0);
    return remainder >= 0 ? remainder : null;
  })();
  const getPricingDisplayValue = key => {
    if (autoPricingKey === key && computedPricingValue !== null && String(form[key] ?? "").trim() === "") {
      return formatMoney(computedPricingValue);
    }
    return form[key];
  };
  const getPricingNumericValue = key => toMoneyNumber(getPricingDisplayValue(key));
  const totalPrice = getPricingNumericValue("totalPrice");
  const merchantDiscount = getPricingNumericValue("merchantDiscount");
  const agentSpend = getPricingNumericValue("agentSpend");
  const clientPays = getPricingNumericValue("clientPays");
  const allocatedTotal = merchantDiscount + agentSpend + clientPays;
  const remainingAmount = Math.max(totalPrice - allocatedTotal, 0);
  const overAllocatedAmount = Math.max(allocatedTotal - totalPrice, 0);
  const barBase = totalPrice > 0 ? totalPrice : Math.max(allocatedTotal, 1);
  const pricingBarSegments = [
    { key:"merchantDiscount", label:"Merchant discount", value:merchantDiscount, color:"#96e7b2" },
    { key:"agentSpend", label:"Agent lead-gen spend", value:agentSpend, color:"#84e3f3" },
    { key:"clientPays", label:"Client pays", value:clientPays, color:"#fbbf24" },
  ];
  const submitForm = () => {
    onSave({
      ...form,
      totalPrice: getPricingDisplayValue("totalPrice"),
      merchantDiscount: getPricingDisplayValue("merchantDiscount"),
      agentSpend: getPricingDisplayValue("agentSpend"),
      clientPays: getPricingDisplayValue("clientPays"),
      value: form.value || (clientPays ? `Client pays SGD ${formatMoney(clientPays)}` : totalPrice ? `Up to SGD ${formatMoney(totalPrice)}` : ""),
      redemptionMode: form.redemptionModes[0] || "",
    });
  };

  return (
    <div style={{ display:"grid", gap:16 }}>
      <div style={{ fontFamily:"'Barlow Condensed',sans-serif", fontSize:"1.8rem", fontWeight:800, color:"#f1ece7" }}>{initial ? "Edit offer" : "Add new offer"}</div>

      <div style={{ display:"grid", gridTemplateColumns:"1fr 1fr", gap:12 }}>
        <label style={{ display:"grid", gap:6, fontWeight:700, fontSize:"0.82rem", color:"#c6cedd" }}>
          Offer title
          <input style={mInputStyle} value={form.title} onChange={e => set("title", e.target.value)} placeholder="e.g. Classic Mani + Pedi" />
        </label>
        <label style={{ display:"grid", gap:6, fontWeight:700, fontSize:"0.82rem", color:"#c6cedd" }}>
          Category
          <select style={mInputStyle} value={form.category} onChange={e => set("category", e.target.value)}>
            {OFFER_CATEGORIES.map(c => <option key={c}>{c}</option>)}
          </select>
        </label>
      </div>

      <label style={{ display:"grid", gap:6, fontWeight:700, fontSize:"0.82rem", color:"#c6cedd" }}>
        Short description <span style={{ color:"#8b97ab", fontWeight:400 }}>(shown on voucher card)</span>
        <textarea style={mTextarea} value={form.description} onChange={e => set("description", e.target.value)} placeholder="What does the client receive? Be specific." />
      </label>

      {/* Pricing model */}
      <div>
        <div style={{ fontWeight:700, fontSize:"0.82rem", color:"#c6cedd", marginBottom:8 }}>Pricing model</div>
        <div style={{ borderRadius:16, padding:"16px 16px 14px", background:"rgba(255,255,255,0.04)", border:"1px solid rgba(255,255,255,0.08)" }}>
          <div style={{ display:"flex", justifyContent:"space-between", alignItems:"baseline", gap:12, marginBottom:10, flexWrap:"wrap" }}>
            <div>
              <div style={{ fontWeight:800, fontSize:"0.88rem", color:"#f1ece7" }}>Proposed pricing split</div>
              <div style={{ fontSize:"0.73rem", color:"#8b97ab", marginTop:3 }}>Show merchants how the value is shared across subsidy, agent spend, and what the client still pays.</div>
            </div>
            <div style={{ fontSize:"0.76rem", color:"#8b97ab" }}>
              Total value {totalPrice > 0 ? <span style={{ color:"#84e3f3", fontWeight:800 }}>SGD {formatMoney(totalPrice)}</span> : "not set yet"}
            </div>
          </div>

          <div style={{ display:"flex", height:14, borderRadius:999, overflow:"hidden", background:"rgba(255,255,255,0.06)", border:"1px solid rgba(255,255,255,0.08)", marginBottom:10 }}>
            {pricingBarSegments.map(segment => (
              segment.value > 0 ? (
                <div
                  key={segment.key}
                  title={`${segment.label}: SGD ${formatMoney(segment.value)}`}
                  style={{ width:`${(segment.value / barBase) * 100}%`, minWidth:8, background:segment.color }}
                />
              ) : null
            ))}
            {remainingAmount > 0 && (
              <div title={`Unallocated: SGD ${formatMoney(remainingAmount)}`} style={{ width:`${(remainingAmount / barBase) * 100}%`, background:"rgba(255,255,255,0.14)" }} />
            )}
          </div>

          <div style={{ display:"flex", gap:8, flexWrap:"wrap" }}>
            {pricingBarSegments.map(segment => (
              <div key={segment.key} style={{ display:"flex", alignItems:"center", gap:6, fontSize:"0.72rem", color:"#8b97ab" }}>
                <span style={{ width:10, height:10, borderRadius:999, background:segment.color, flexShrink:0 }} />
                <span>{segment.label}</span>
              </div>
            ))}
            {remainingAmount > 0 && (
              <div style={{ display:"flex", alignItems:"center", gap:6, fontSize:"0.72rem", color:"#8b97ab" }}>
                <span style={{ width:10, height:10, borderRadius:999, background:"rgba(255,255,255,0.25)", flexShrink:0 }} />
                <span>Remaining amount</span>
              </div>
            )}
          </div>
        </div>
      </div>

      <div style={{ display:"grid", gridTemplateColumns:"1fr 1fr", gap:12 }}>
        <label style={{ display:"grid", gap:6, fontWeight:700, fontSize:"0.82rem", color:"#c6cedd" }}>
          Original or total price of product / service
          <input style={mInputStyle} value={getPricingDisplayValue("totalPrice")} onChange={e => set("totalPrice", e.target.value)} placeholder="SGD 280" />
        </label>
        <label style={{ display:"grid", gap:6, fontWeight:700, fontSize:"0.82rem", color:"#c6cedd" }}>
          How much discount the merchant wants to provide
          <input style={mInputStyle} value={getPricingDisplayValue("merchantDiscount")} onChange={e => set("merchantDiscount", e.target.value)} placeholder="SGD 120" />
        </label>
        <label style={{ display:"grid", gap:6, fontWeight:700, fontSize:"0.82rem", color:"#c6cedd" }}>
          How much an agent may be willing to spend on lead gen
          <input style={mInputStyle} value={getPricingDisplayValue("agentSpend")} onChange={e => set("agentSpend", e.target.value)} placeholder="SGD 80" />
        </label>
        <label style={{ display:"grid", gap:6, fontWeight:700, fontSize:"0.82rem", color:"#c6cedd" }}>
          How much the client themselves should be paying
          <input style={mInputStyle} value={getPricingDisplayValue("clientPays")} onChange={e => set("clientPays", e.target.value)} placeholder="SGD 80" />
        </label>
      </div>

      {autoPricingKey && computedPricingValue !== null && (
        <div style={{ fontSize:"0.74rem", color:"#84e3f3", marginTop:-4 }}>
          The {autoPricingKey === "totalPrice" ? "total price" : autoPricingKey === "merchantDiscount" ? "merchant discount" : autoPricingKey === "agentSpend" ? "agent spend" : "client payment"} field has been auto-calculated from the other three values.
        </div>
      )}

      <div style={{ display:"grid", gridTemplateColumns:"1fr 1fr 1fr", gap:12 }}>
        <label style={{ display:"grid", gap:6, fontWeight:700, fontSize:"0.82rem", color:"#c6cedd" }}>
          Value label <span style={{ color:"#8b97ab", fontWeight:400 }}>(e.g. SGD 68)</span>
          <input style={mInputStyle} value={form.value} onChange={e => set("value", e.target.value)} placeholder="SGD 68" />
        </label>
        <label style={{ display:"grid", gap:6, fontWeight:700, fontSize:"0.82rem", color:"#c6cedd" }}>
          Expiry (days after voucher claim) <span style={{ color:"#8b97ab", fontWeight:400 }}>(leave blank for no expiry)</span>
          <input style={mInputStyle} type="number" value={form.expiryDays} onChange={e => set("expiryDays", e.target.value)} min={1} max={365} placeholder="No expiry" />
        </label>
        <label style={{ display:"grid", gap:6, fontWeight:700, fontSize:"0.82rem", color:"#c6cedd" }}>
          Max claims <span style={{ color:"#8b97ab", fontWeight:400 }}>(blank = unlimited)</span>
          <div style={{ display:"grid", gridTemplateColumns:"1fr 170px", gap:10 }}>
            <input style={mInputStyle} value={form.maxClaims} onChange={e => set("maxClaims", e.target.value)} placeholder="Unlimited" />
            <select style={mInputStyle} value={form.maxClaimsWindow} onChange={e => set("maxClaimsWindow", e.target.value)}>
              {MAX_CLAIM_WINDOWS.map(option => <option key={option.id} value={option.id}>{option.label}</option>)}
            </select>
          </div>
        </label>
      </div>

      {(remainingAmount > 0 || overAllocatedAmount > 0) && (
        <div style={{
          borderRadius:12,
          padding:"12px 14px",
          background: overAllocatedAmount > 0 ? "rgba(255,105,126,0.08)" : "rgba(132,227,243,0.06)",
          border: overAllocatedAmount > 0 ? "1px solid rgba(255,105,126,0.18)" : "1px solid rgba(132,227,243,0.15)",
        }}>
          <div style={{ fontWeight:800, fontSize:"0.8rem", color: overAllocatedAmount > 0 ? "#ff9dac" : "#84e3f3", marginBottom:4 }}>
            {overAllocatedAmount > 0 ? "Pricing exceeds the original total" : "There is still value left to allocate"}
          </div>
          <div style={{ fontSize:"0.75rem", color:"#8b97ab", lineHeight:1.55 }}>
            {overAllocatedAmount > 0
              ? `The discount, agent spend, and client payment add up to SGD ${formatMoney(allocatedTotal)}, which is SGD ${formatMoney(overAllocatedAmount)} above the total price.`
              : `The current split adds up to SGD ${formatMoney(allocatedTotal)}, leaving SGD ${formatMoney(remainingAmount)} not yet assigned.`}
          </div>
        </div>
      )}

      {/* Redemption mode */}
      <div>
        <div style={{ fontWeight:700, fontSize:"0.82rem", color:"#c6cedd", marginBottom:8 }}>How clients redeem</div>
        <div style={{ display:"grid", gridTemplateColumns:"repeat(3,1fr)", gap:8 }}>
          {REDEMPTION_MODES.map(rm => (
            <button key={rm.id} onClick={() => toggleMulti("redemptionModes", rm.id)}
              style={{ all:"unset", cursor:"pointer", borderRadius:12, padding:"12px 14px", textAlign:"left",
                border: form.redemptionModes.includes(rm.id) ? "1.5px solid #84e3f3" : "1px solid rgba(255,255,255,0.1)",
                background: form.redemptionModes.includes(rm.id) ? "rgba(132,227,243,0.1)" : "rgba(255,255,255,0.03)",
                transition:"all 150ms",
              }}>
              <div style={{ display:"flex", justifyContent:"space-between", gap:10, alignItems:"center" }}>
                <div style={{ fontWeight:800, fontSize:"0.84rem", color: form.redemptionModes.includes(rm.id) ? "#84e3f3" : "#c6cedd" }}>{rm.label}</div>
                <div style={{
                  width:18, height:18, borderRadius:5,
                  border: form.redemptionModes.includes(rm.id) ? "none" : "1px solid rgba(255,255,255,0.24)",
                  background: form.redemptionModes.includes(rm.id) ? "#84e3f3" : "transparent",
                  color:"#08111f", display:"grid", placeItems:"center", fontSize:"0.7rem", fontWeight:800,
                }}>
                  {form.redemptionModes.includes(rm.id) ? "✓" : ""}
                </div>
              </div>
              <div style={{ fontSize:"0.72rem", color:"#8b97ab", marginTop:3 }}>{rm.sub}</div>
            </button>
          ))}
        </div>
        <div style={{ fontSize:"0.72rem", color:"#8b97ab", marginTop:8 }}>Select one or more methods if clients can redeem in multiple ways.</div>
      </div>

      {/* Agent rules */}
      <div>
        <div style={{ fontWeight:800, fontSize:"0.94rem", color:"#f1ece7", marginBottom:4 }}>Let insurance agents make the rules</div>
        <div style={{ fontSize:"0.74rem", color:"#8b97ab", marginBottom:10 }}>Insurance agents can require or allow the following before a client redeems.</div>
        <div style={{ display:"grid", gridTemplateColumns:"1fr 1fr", gap:10 }}>
        {RULE_OPTIONS.map(([key, label, sub]) => (
          <button key={key} onClick={() => set(key, !form[key])}
            style={{ all:"unset", cursor:"pointer", borderRadius:12, padding:"12px 14px",
              border: form[key] ? "1.5px solid rgba(132,227,243,0.4)" : "1px solid rgba(255,255,255,0.08)",
              background: form[key] ? "rgba(132,227,243,0.08)" : "rgba(255,255,255,0.03)",
              display:"flex", gap:10, alignItems:"flex-start", transition:"all 150ms",
            }}>
            <div style={{ width:18, height:18, borderRadius:5, border: form[key] ? "none" : "1.5px solid rgba(255,255,255,0.2)", background: form[key] ? "#84e3f3" : "transparent", display:"grid", placeItems:"center", fontSize:"0.72rem", color:"#08111f", flexShrink:0, marginTop:1 }}>
              {form[key] && "✓"}
            </div>
            <div>
              <div style={{ fontWeight:700, fontSize:"0.82rem", color: form[key] ? "#84e3f3" : "#c6cedd" }}>{label}</div>
              <div style={{ fontSize:"0.7rem", color:"#8b97ab", marginTop:2 }}>{sub}</div>
            </div>
          </button>
        ))}
        </div>
      </div>

      <div style={{ display:"flex", gap:10, justifyContent:"flex-end", paddingTop:4 }}>
        <button onClick={onCancel} style={{ all:"unset", cursor:"pointer", padding:"11px 22px", borderRadius:999, border:"1px solid rgba(255,255,255,0.12)", color:"#8b97ab", fontWeight:700, fontSize:"0.88rem" }}>Cancel</button>
        <button onClick={submitForm}
          style={{ all:"unset", cursor:"pointer", padding:"11px 24px", borderRadius:999, background:"linear-gradient(90deg,#84e3f3,#84e3f3cc)", color:"#08111f", fontWeight:800, fontSize:"0.9rem" }}>
          {initial ? "Save changes" : "Submit for review"}
        </button>
      </div>
    </div>
  );
}

// ── FAQ EDITOR ─────────────────────────────────────────────
function FaqEditor() {
  const [faqs, setFaqs] = useStateM(RP.MERCHANT_FAQS_DEMO);
  const [audience, setAudience] = useStateM("client");
  const [editIdx, setEditIdx] = useStateM(null);
  const [draft, setDraft] = useStateM({ q:"", a:"" });

  const list = faqs[audience];

  const save = () => {
    if (!draft.q.trim() || !draft.a.trim()) return;
    if (editIdx === "new") {
      setFaqs(f => ({ ...f, [audience]: [...f[audience], { id:`${audience}${Date.now()}`, ...draft }] }));
    } else {
      setFaqs(f => ({ ...f, [audience]: f[audience].map((item,i) => i === editIdx ? { ...item, ...draft } : item) }));
    }
    setEditIdx(null); setDraft({ q:"", a:"" });
  };

  const remove = idx => setFaqs(f => ({ ...f, [audience]: f[audience].filter((_,i) => i !== idx) }));

  return (
    <div style={{ display:"grid", gap:20 }}>
      <div>
        <div style={{ fontFamily:"'Barlow Condensed',sans-serif", fontSize:"1.8rem", fontWeight:800, color:"#f1ece7", marginBottom:4 }}>FAQ editor</div>
        <div style={{ fontSize:"0.82rem", color:"#8b97ab" }}>Manage separate FAQ sections for clients and insurance agents.</div>
      </div>

      {/* Audience toggle */}
      <div style={{ display:"grid", gridTemplateColumns:"1fr 1fr", gap:10 }}>
        {[["client","👤 Client FAQ","Shown on offer pages to clients browsing vouchers"],["agent","🤝 Agent FAQ","Shown to insurance agents sponsoring or promoting this offer"]].map(([id, label, sub]) => (
          <button key={id} onClick={() => { setAudience(id); setEditIdx(null); }}
            style={{ all:"unset", cursor:"pointer", borderRadius:14, padding:"14px 16px",
              border: audience === id ? "1.5px solid #84e3f3" : "1px solid rgba(255,255,255,0.1)",
              background: audience === id ? "rgba(132,227,243,0.1)" : "rgba(255,255,255,0.03)",
              transition:"all 150ms", textAlign:"left",
            }}>
            <div style={{ fontWeight:800, fontSize:"0.9rem", color: audience === id ? "#84e3f3" : "#c6cedd" }}>{label}</div>
            <div style={{ fontSize:"0.73rem", color:"#8b97ab", marginTop:3, lineHeight:1.4 }}>{sub}</div>
          </button>
        ))}
      </div>

      {/* FAQ list */}
      <div style={{ display:"grid", gap:8 }}>
        {list.map((item, i) => (
          <div key={item.id} style={{ borderRadius:14, overflow:"hidden", border:"1px solid rgba(255,255,255,0.08)" }}>
            {editIdx === i ? (
              <div style={{ padding:"14px 16px", background:"rgba(132,227,243,0.05)", display:"grid", gap:10 }}>
                <label style={{ display:"grid", gap:5, fontSize:"0.8rem", fontWeight:700, color:"#c6cedd" }}>
                  Question
                  <input style={mInputStyle} value={draft.q} onChange={e => setDraft(d => ({ ...d, q:e.target.value }))} />
                </label>
                <label style={{ display:"grid", gap:5, fontSize:"0.8rem", fontWeight:700, color:"#c6cedd" }}>
                  Answer
                  <textarea style={mTextarea} value={draft.a} onChange={e => setDraft(d => ({ ...d, a:e.target.value }))} />
                </label>
                <div style={{ display:"flex", gap:8 }}>
                  <button onClick={save} style={{ all:"unset", cursor:"pointer", padding:"8px 16px", borderRadius:999, background:"#84e3f3", color:"#08111f", fontWeight:800, fontSize:"0.8rem" }}>Save</button>
                  <button onClick={() => setEditIdx(null)} style={{ all:"unset", cursor:"pointer", padding:"8px 16px", borderRadius:999, border:"1px solid rgba(255,255,255,0.1)", color:"#8b97ab", fontSize:"0.8rem" }}>Cancel</button>
                </div>
              </div>
            ) : (
              <div style={{ padding:"12px 14px" }}>
                <div style={{ fontWeight:700, fontSize:"0.86rem", color:"#f1ece7", marginBottom:4 }}>{item.q}</div>
                <div style={{ fontSize:"0.8rem", color:"#8b97ab", lineHeight:1.6, marginBottom:10 }}>{item.a}</div>
                <div style={{ display:"flex", gap:8 }}>
                  <button onClick={() => { setDraft({ q:item.q, a:item.a }); setEditIdx(i); }}
                    style={{ all:"unset", cursor:"pointer", padding:"5px 12px", borderRadius:999, border:"1px solid rgba(255,255,255,0.1)", color:"#c6cedd", fontSize:"0.74rem" }}>✏️ Edit</button>
                  <button onClick={() => remove(i)}
                    style={{ all:"unset", cursor:"pointer", padding:"5px 12px", borderRadius:999, border:"1px solid rgba(255,105,126,0.2)", color:"#ff697e", fontSize:"0.74rem" }}>🗑 Remove</button>
                </div>
              </div>
            )}
          </div>
        ))}

        {/* Add new */}
        {editIdx === "new" ? (
          <div style={{ borderRadius:14, padding:"14px 16px", border:"1.5px dashed rgba(132,227,243,0.3)", background:"rgba(132,227,243,0.04)", display:"grid", gap:10 }}>
            <label style={{ display:"grid", gap:5, fontSize:"0.8rem", fontWeight:700, color:"#c6cedd" }}>
              New question
              <input style={mInputStyle} value={draft.q} onChange={e => setDraft(d => ({ ...d, q:e.target.value }))} placeholder="What would a client ask?" />
            </label>
            <label style={{ display:"grid", gap:5, fontSize:"0.8rem", fontWeight:700, color:"#c6cedd" }}>
              Answer
              <textarea style={mTextarea} value={draft.a} onChange={e => setDraft(d => ({ ...d, a:e.target.value }))} placeholder="Your clear, helpful answer…" />
            </label>
            <div style={{ display:"flex", gap:8 }}>
              <button onClick={save} style={{ all:"unset", cursor:"pointer", padding:"8px 16px", borderRadius:999, background:"#84e3f3", color:"#08111f", fontWeight:800, fontSize:"0.8rem" }}>Add FAQ</button>
              <button onClick={() => { setEditIdx(null); setDraft({ q:"", a:"" }); }} style={{ all:"unset", cursor:"pointer", padding:"8px 16px", borderRadius:999, border:"1px solid rgba(255,255,255,0.1)", color:"#8b97ab", fontSize:"0.8rem" }}>Cancel</button>
            </div>
          </div>
        ) : (
          <button onClick={() => { setDraft({ q:"", a:"" }); setEditIdx("new"); }}
            style={{ all:"unset", cursor:"pointer", padding:"12px", borderRadius:14, border:"1px dashed rgba(132,227,243,0.3)", color:"#84e3f3", fontWeight:800, textAlign:"center", fontSize:"0.84rem" }}>
            + Add FAQ for {audience === "client" ? "clients" : "agents"}
          </button>
        )}
      </div>
    </div>
  );
}

// ── MERCHANT ONBOARDING ────────────────────────────────────
const MERCHANT_STEPS = ["Business info","Offer details","Redemption setup","FAQ & terms","Preview"];

function MerchantOnboarding({ onComplete }) {
  const [step, setStep] = useStateM(0);
  const [biz, setBiz] = useStateM({ businessName:"", contactName:"", email:"", mobile:"", uen:"", category:"Beauty", address:"", website:"" });
  const setBizField = (k,v) => setBiz(b => ({ ...b, [k]:v }));

  return (
    <div style={{ display:"grid", gap:0, height:"100%" }}>
      {/* Step indicator */}
      <div style={{ marginBottom:0 }}>
        <div style={{ display:"flex", alignItems:"center", gap:0, marginBottom:20 }}>
          {MERCHANT_STEPS.map((label, i) => (
            <React.Fragment key={i}>
              <div style={{
                width: i === step ? 28 : 22, height: i === step ? 28 : 22, borderRadius:999,
                display:"grid", placeItems:"center",
                background: i < step ? "#96e7b2" : i === step ? "#84e3f3" : "rgba(255,255,255,0.08)",
                color: i <= step ? "#08111f" : "#8b97ab",
                fontWeight:800, fontSize:"0.75rem", flexShrink:0, transition:"all 200ms",
              }}>{i < step ? "✓" : i + 1}</div>
              {i < MERCHANT_STEPS.length - 1 && <div style={{ flex:1, height:2, background: i < step ? "#96e7b2" : "rgba(255,255,255,0.08)", minWidth:10, transition:"all 300ms" }} />}
            </React.Fragment>
          ))}
        </div>
        <div style={{ fontFamily:"'Barlow Condensed',sans-serif", fontSize:"1.9rem", fontWeight:800, color:"#f1ece7", marginBottom:4 }}>{MERCHANT_STEPS[step]}</div>
        <div style={{ fontSize:"0.78rem", color:"#8b97ab", marginBottom:22 }}>Step {step + 1} of {MERCHANT_STEPS.length}</div>
      </div>

      <div style={{ flex:1, overflowY:"auto" }}>
        {step === 0 && (
          <div style={{ display:"grid", gap:14 }}>
            <div style={{ borderRadius:14, padding:"14px 16px", background:"rgba(255,191,94,0.08)", border:"1px solid rgba(255,191,94,0.22)" }}>
              <div style={{ fontWeight:800, fontSize:"0.82rem", color:"#fbbf24", marginBottom:5 }}>Note for New Merchants</div>
              <div style={{ fontSize:"0.8rem", color:"#e5d5b3", lineHeight:1.6 }}>
                Invitation to join this platform is contingent on non-competition with our existing merchants.
              </div>
            </div>
            <div style={{ display:"grid", gridTemplateColumns:"1fr 1fr", gap:12 }}>
              <label style={{ display:"grid", gap:6, fontWeight:700, fontSize:"0.82rem", color:"#c6cedd" }}>
                Business display name
                <input style={mInputStyle} value={biz.businessName} onChange={e => setBizField("businessName",e.target.value)} placeholder="The Nail Lab" />
              </label>
              <label style={{ display:"grid", gap:6, fontWeight:700, fontSize:"0.82rem", color:"#c6cedd" }}>
                Business category
                <select style={mInputStyle} value={biz.category} onChange={e => setBizField("category",e.target.value)}>
                  {OFFER_CATEGORIES.map(c => <option key={c}>{c}</option>)}
                </select>
              </label>
            </div>
            <div style={{ display:"grid", gridTemplateColumns:"1fr 1fr", gap:12 }}>
              <label style={{ display:"grid", gap:6, fontWeight:700, fontSize:"0.82rem", color:"#c6cedd" }}>
                Contact person name
                <input style={mInputStyle} value={biz.contactName} onChange={e => setBizField("contactName",e.target.value)} placeholder="Full name" />
              </label>
              <label style={{ display:"grid", gap:6, fontWeight:700, fontSize:"0.82rem", color:"#c6cedd" }}>
                UEN (business registration)
                <input style={mInputStyle} value={biz.uen} onChange={e => setBizField("uen",e.target.value)} placeholder="202312345A" />
              </label>
            </div>
            <div style={{ display:"grid", gridTemplateColumns:"1fr 1fr", gap:12 }}>
              <label style={{ display:"grid", gap:6, fontWeight:700, fontSize:"0.82rem", color:"#c6cedd" }}>
                Email
                <input style={mInputStyle} type="email" value={biz.email} onChange={e => setBizField("email",e.target.value)} placeholder="hello@yourbusiness.sg" />
              </label>
              <label style={{ display:"grid", gap:6, fontWeight:700, fontSize:"0.82rem", color:"#c6cedd" }}>
                Mobile / WhatsApp
                <input style={mInputStyle} value={biz.mobile} onChange={e => setBizField("mobile",e.target.value)} placeholder="+65 9000 0000" />
              </label>
            </div>
            <label style={{ display:"grid", gap:6, fontWeight:700, fontSize:"0.82rem", color:"#c6cedd" }}>
              Primary outlet address or service area
              <input style={mInputStyle} value={biz.address} onChange={e => setBizField("address",e.target.value)} placeholder="10 Anson Road #02-01, Singapore 079903" />
            </label>
          </div>
        )}

        {step === 1 && <OfferForm onSave={() => setStep(2)} onCancel={() => setStep(0)} />}

        {step === 2 && (
          <div style={{ display:"grid", gap:14 }}>
            <div style={{ fontSize:"0.84rem", color:"#8b97ab", lineHeight:1.6 }}>Set up how clients will physically or digitally redeem their vouchers.</div>
            <label style={{ display:"grid", gap:6, fontWeight:700, fontSize:"0.82rem", color:"#c6cedd" }}>
              Staff WhatsApp number for digital redemption
              <input style={mInputStyle} placeholder="+65 9000 0000" />
            </label>
            <label style={{ display:"grid", gap:6, fontWeight:700, fontSize:"0.82rem", color:"#c6cedd" }}>
              Operating hours / redemption window
              <input style={mInputStyle} placeholder="Mon–Sat 10am–8pm" />
            </label>
            <label style={{ display:"grid", gap:6, fontWeight:700, fontSize:"0.82rem", color:"#c6cedd" }}>
              Booking / advance notice requirement
              <input style={mInputStyle} placeholder="e.g. Book at least 24 hours in advance" />
            </label>
            <label style={{ display:"grid", gap:6, fontWeight:700, fontSize:"0.82rem", color:"#c6cedd" }}>
              Settlement bank details <span style={{ fontWeight:400, color:"#8b97ab" }}>(confidential — for payouts only)</span>
              <input style={mInputStyle} placeholder="Bank name / PayNow UEN" />
            </label>
          </div>
        )}

        {step === 3 && <FaqEditor />}

        {step === 4 && (
          <div style={{ display:"grid", gap:16 }}>
            <div style={{ fontSize:"0.84rem", color:"#c6cedd", lineHeight:1.6 }}>Your merchant profile is almost ready. ISPT will review and activate your first offer within 1–2 business days.</div>
            <div style={{ borderRadius:18, padding:20, background:"rgba(150,231,178,0.08)", border:"1px solid rgba(150,231,178,0.2)" }}>
              <div style={{ fontWeight:800, color:"#96e7b2", marginBottom:10 }}>✓ Checklist before going live</div>
              <ul style={{ margin:0, padding:"0 0 0 16px", color:"#c6cedd", fontSize:"0.84rem", lineHeight:2 }}>
                <li>Business name and UEN verified</li>
                <li>Offer title, value, and description complete</li>
                <li>Redemption method and operating hours set</li>
                <li>Settlement bank details provided</li>
                <li>At least one FAQ for clients added</li>
              </ul>
            </div>
            <button onClick={() => onComplete(biz)}
              style={{ all:"unset", cursor:"pointer", padding:"14px", borderRadius:999, background:"linear-gradient(90deg,#96e7b2,#84e3f3)", color:"#08111f", fontWeight:800, textAlign:"center", fontSize:"0.95rem" }}>
              Submit for ISPT review →
            </button>
          </div>
        )}
      </div>

      {/* Nav */}
      {step !== 1 && step !== 3 && (
        <div style={{ display:"flex", gap:10, marginTop:24, paddingTop:16, borderTop:"1px solid rgba(255,255,255,0.07)" }}>
          {step > 0 && <button onClick={() => setStep(s => Math.max(0,s-1))} style={{ all:"unset", cursor:"pointer", padding:"12px 20px", borderRadius:999, border:"1px solid rgba(132,227,243,0.2)", color:"#84e3f3", fontWeight:700, fontSize:"0.88rem" }}>← Back</button>}
          <div style={{ flex:1 }} />
          {step < MERCHANT_STEPS.length - 1 && step !== 4 && (
            <button onClick={() => setStep(s => Math.min(MERCHANT_STEPS.length-1, s+1))} style={{ all:"unset", cursor:"pointer", padding:"12px 24px", borderRadius:999, background:"#84e3f3", color:"#08111f", fontWeight:800, fontSize:"0.9rem" }}>Continue →</button>
          )}
        </div>
      )}
    </div>
  );
}

// ── MERCHANT OFFER MANAGEMENT DASHBOARD ───────────────────
const merchantSlug = name => String(name || "")
  .normalize("NFD")
  .replace(/[\u0300-\u036f]/g, "")
  .toLowerCase()
  .replace(/[^a-z0-9]+/g, "-")
  .replace(/^-|-$/g, "");

const categoryLabel = categoryId => {
  const fromCatalog = RP.CATEGORIES?.find(item => item.id === categoryId)?.label;
  if (fromCatalog) return fromCatalog;
  return String(categoryId || "Other")
    .split("-")
    .map(word => word ? word[0].toUpperCase() + word.slice(1) : "")
    .join(" ");
};

const expiryLabel = days => String(days ?? "").trim() ? `${days} days after voucher claim` : "No expiry";

const pricingLabelFromForm = form => {
  if (String(form.value || "").trim()) return form.value;
  if (String(form.clientPays || "").trim()) return `Client pays SGD ${form.clientPays}`;
  if (String(form.totalPrice || "").trim()) return `Up to SGD ${form.totalPrice}`;
  return "Custom offer";
};

function createMerchantAdminSeed() {
  const merchantMap = new Map();

  const ensureMerchant = (name, category) => {
    const id = merchantSlug(name);
    if (!merchantMap.has(id)) {
      merchantMap.set(id, {
        id,
        name,
        category: categoryLabel(category),
        clientOffers: [],
        agentOffers: [],
      });
    }
    return merchantMap.get(id);
  };

  (RP.VOUCHERS || []).forEach(voucher => {
    const merchant = ensureMerchant(voucher.merchant, voucher.category);
    merchant.clientOffers.push({
      id: `client-${voucher.id}`,
      status: "active",
      audience: "Insurance clients",
      channel: "Client marketplace",
      title: voucher.title,
      subtitle: voucher.subtitle,
      category: categoryLabel(voucher.category),
      description: voucher.description,
      details: [
        ["Value", voucher.value === "Free" && voucher.originalPrice ? `Free · was ${voucher.originalPrice}` : voucher.value],
        ["Claim flow", voucher.claimRule],
        ["Expiry", voucher.expiryText || "No expiry"],
      ],
      notes: [voucher.priceNote, voucher.meetingRule, voucher.redemptionRule].filter(Boolean),
      tags: [voucher.tag, voucher.voucherTypeLabel].filter(Boolean),
      programs: [],
      formSeed: {
        title: voucher.title,
        category: categoryLabel(voucher.category),
        value: voucher.value,
        description: voucher.description,
        expiryDays: (voucher.expiryText || "").match(/^\d+/)?.[0] || "",
        promoCreditEligible: !!voucher.promoCreditEligible,
        clientPays: voucher.funding?.clientPays ?? "",
        agentSpend: voucher.funding?.agentPays ?? "",
        merchantDiscount: typeof voucher.funding?.merchantDiscount === "number" ? voucher.funding.merchantDiscount : "",
        totalPrice: voucher.funding?.totalValue ?? "",
        redemptionModes: voucher.redemptionRule?.toLowerCase().includes("visit") ? ["physical"] : ["digital"],
      },
    });
  });

  (RP.AGENT_COLLAB_OFFERS || []).forEach(offer => {
    const merchant = ensureMerchant(offer.name, offer.category);
    merchant.agentOffers.push({
      id: `agent-${offer.id}`,
      status: "active",
      audience: "Insurance agents",
      channel: "Direct Agent Collaboration Offers",
      title: offer.name,
      subtitle: offer.tagline,
      category: offer.category,
      description: offer.offer,
      details: [
        ["Offer type", "Direct collaboration"],
        ["Programs", String(offer.programs?.length || 1)],
        ["Access", offer.badges?.map(badge => badge.label).join(", ") || "Agent only"],
      ],
      notes: offer.notes || [],
      tags: offer.badges?.map(badge => badge.label) || [],
      programs: offer.programs || [],
      formSeed: {
        title: offer.name,
        category: offer.category,
        description: offer.offer,
        value: offer.programs?.[0]?.price || "",
      },
    });
  });

  (RP.RELATIONSHIP_SPACES || []).forEach(offer => {
    const merchant = ensureMerchant(offer.name, offer.category);
    merchant.agentOffers.push({
      id: `agent-${offer.id}`,
      status: "active",
      audience: "Insurance agents",
      channel: "Intimate spaces",
      title: offer.name,
      subtitle: offer.tagline,
      category: offer.category,
      description: offer.offer,
      details: [
        ["Offer type", "Relationship-building venue"],
        ["Programs", String(offer.programs?.length || 1)],
        ["Use case", offer.talkFormats?.[0] || "Warm client touchpoint"],
      ],
      notes: [],
      tags: offer.talkFormats || [],
      programs: offer.programs || [],
      formSeed: {
        title: offer.name,
        category: offer.category,
        description: offer.offer,
        value: offer.programs?.[0]?.price || "",
      },
    });
  });

  (RP.TALK_PARTNERS || []).forEach(offer => {
    const merchant = ensureMerchant(offer.name, offer.category);
    merchant.agentOffers.push({
      id: `agent-${offer.id}`,
      status: "active",
      audience: "Insurance agents",
      channel: "Invite speakers to give a talk",
      title: offer.name,
      subtitle: offer.tagline,
      category: offer.category,
      description: offer.offer,
      details: [
        ["Offer type", "Talk or workshop"],
        ["Programs", String(offer.programs?.length || 1)],
        ["Use case", offer.talkFormats?.[0] || "Team or client event"],
      ],
      notes: [],
      tags: [offer.featuredLabel, ...(offer.talkFormats || [])].filter(Boolean),
      programs: offer.programs?.length ? offer.programs : [{ title: offer.tagline, description: offer.offer }],
      formSeed: {
        title: offer.name,
        category: offer.category,
        description: offer.offer,
        value: offer.programs?.[0]?.price || "",
      },
    });
  });

  const merchantDirectory = Array.from(merchantMap.values()).map(merchant => ({
    id: merchant.id,
    name: merchant.name,
    category: merchant.category,
    note:
      merchant.clientOffers.length && merchant.agentOffers.length
        ? "Live on both the client and agent-facing pages"
        : merchant.clientOffers.length
          ? "Live on the client-facing page"
          : "Live on the insurance agent-facing pages",
    contact: "Main admin view",
  }));

  const offersByMerchant = Object.fromEntries(
    Array.from(merchantMap.values()).map(merchant => [merchant.id, {
      clientOffers: merchant.clientOffers,
      agentOffers: merchant.agentOffers,
    }])
  );

  return { merchantDirectory, offersByMerchant };
}

const createManagedOfferFromForm = (form, bucket) => ({
  id: `${bucket}-${Date.now()}`,
  status: "review",
  audience: bucket === "clientOffers" ? "Insurance clients" : "Insurance agents",
  channel: bucket === "clientOffers" ? "Client marketplace" : "Agent collaboration",
  title: form.title,
  subtitle: bucket === "clientOffers" ? pricingLabelFromForm(form) : "Custom merchant-managed offer",
  category: form.category,
  description: form.description,
  details: bucket === "clientOffers"
    ? [
        ["Value", pricingLabelFromForm(form)],
        ["Claim flow", "To be configured by admin"],
        ["Expiry", expiryLabel(form.expiryDays)],
      ]
    : [
        ["Offer type", "Agent-facing offer"],
        ["Programs", "1"],
        ["Use case", "To be configured by admin"],
      ],
  notes: [],
  tags: [],
  programs: bucket === "agentOffers"
    ? [{ title: form.title, price: form.value || "", description: form.description }]
    : [],
  formSeed: { ...form },
});

const mergeManagedOfferWithForm = (offer, form) => ({
  ...offer,
  title: form.title || offer.title,
  category: form.category || offer.category,
  description: form.description || offer.description,
  subtitle: offer.audience === "Insurance clients" ? pricingLabelFromForm(form) : offer.subtitle,
  details: offer.audience === "Insurance clients"
    ? [
        ["Value", pricingLabelFromForm(form)],
        [offer.details?.[1]?.[0] || "Claim flow", offer.details?.[1]?.[1] || "To be configured by admin"],
        ["Expiry", expiryLabel(form.expiryDays)],
      ]
    : offer.details,
  programs: offer.audience === "Insurance agents" && offer.programs?.length
    ? offer.programs.map((program, index) => index === 0 ? {
        ...program,
        title: form.title || program.title,
        price: form.value || program.price,
        description: form.description || program.description,
      } : program)
    : offer.programs,
  formSeed: { ...(offer.formSeed || {}), ...form },
});

function MerchantOfferDashboard() {
  const seed = createMerchantAdminSeed();
  const merchantDirectory = seed.merchantDirectory;
  const defaultMerchantId = merchantDirectory[0]?.id || "";
  const [selectedMerchantId, setSelectedMerchantId] = useStateM(defaultMerchantId);
  const [offersByMerchant, setOffersByMerchant] = useStateM(seed.offersByMerchant);
  const [editOffer, setEditOffer] = useStateM(null);
  const [addingBucket, setAddingBucket] = useStateM(null);
  const selectedMerchant = merchantDirectory.find(merchant => merchant.id === selectedMerchantId) || merchantDirectory[0] || null;
  const selectedBuckets = offersByMerchant[selectedMerchantId] || { clientOffers: [], agentOffers: [] };

  const updateSelectedMerchantBucket = (bucket, updater) => {
    setOffersByMerchant(store => ({
      ...store,
      [selectedMerchantId]: {
        ...(store[selectedMerchantId] || { clientOffers: [], agentOffers: [] }),
        [bucket]: updater(store[selectedMerchantId]?.[bucket] || []),
      },
    }));
  };

  const togglePause = (bucket, id) => updateSelectedMerchantBucket(bucket, list => list.map(o => o.id === id ? { ...o, status: o.status === "active" ? "paused" : "active" } : o));
  const removeOffer = (bucket, id) => updateSelectedMerchantBucket(bucket, list => list.filter(o => o.id !== id));
  const renderSection = (title, description, bucket, offers) => (
    <div style={{ display:"grid", gap:10 }}>
      <div style={{ display:"flex", justifyContent:"space-between", alignItems:"center", gap:12, flexWrap:"wrap" }}>
        <div>
          <div style={{ fontWeight:800, fontSize:"1rem", color:"#f1ece7" }}>{title}</div>
          <div style={{ fontSize:"0.76rem", color:"#8b97ab", marginTop:3 }}>{description}</div>
        </div>
        <button onClick={() => setAddingBucket(bucket)} style={{ all:"unset", cursor:"pointer", padding:"9px 16px", borderRadius:999, background:"rgba(132,227,243,0.12)", color:"#84e3f3", fontWeight:800, fontSize:"0.78rem" }}>
          + Add {bucket === "clientOffers" ? "client-facing" : "agent-facing"} offer
        </button>
      </div>
      {offers.length ? offers.map(offer => (
        <OfferCard
          key={offer.id}
          offer={offer}
          onEdit={() => setEditOffer({ bucket, offer })}
          onPause={() => togglePause(bucket, offer.id)}
          onRemove={() => removeOffer(bucket, offer.id)}
        />
      )) : (
        <div style={{ borderRadius:18, padding:"20px 18px", background:"rgba(255,255,255,0.03)", border:"1px dashed rgba(255,255,255,0.12)", color:"#8b97ab", fontSize:"0.82rem" }}>
          No {bucket === "clientOffers" ? "client-facing" : "agent-facing"} offers are linked to this merchant yet.
        </div>
      )}
    </div>
  );

  if (editOffer) return (
    <div>
      <OfferForm
        initial={editOffer.offer.formSeed}
        onSave={updated => {
          updateSelectedMerchantBucket(editOffer.bucket, list => list.map(item => item.id === editOffer.offer.id ? mergeManagedOfferWithForm(item, updated) : item));
          setEditOffer(null);
        }}
        onCancel={() => setEditOffer(null)}
      />
    </div>
  );

  if (addingBucket) return (
    <div>
      <OfferForm
        onSave={newOffer => {
          updateSelectedMerchantBucket(addingBucket, list => [...list, createManagedOfferFromForm(newOffer, addingBucket)]);
          setAddingBucket(null);
        }}
        onCancel={() => setAddingBucket(null)}
      />
    </div>
  );

  return (
    <div style={{ display:"grid", gap:14 }}>
      <div style={{ display:"flex", justifyContent:"space-between", alignItems:"flex-start", gap:16, flexWrap:"wrap" }}>
        <div style={{ minWidth:320 }}>
          <div style={{ fontFamily:"'Barlow Condensed',sans-serif", fontSize:"1.8rem", fontWeight:800, color:"#f1ece7" }}>My offers</div>
          <div style={{ fontSize:"0.8rem", color:"#8b97ab" }}>As the main admin, select any existing merchant below to amend the separate offers they show to insurance clients and insurance agents.</div>
        </div>
        <div style={{ display:"flex", gap:10, alignItems:"center", flexWrap:"wrap", justifyContent:"flex-end" }}>
          <label style={{ display:"grid", gap:6, fontWeight:700, fontSize:"0.78rem", color:"#c6cedd", minWidth:260 }}>
            Choose merchant
            <select
              style={mInputStyle}
              value={selectedMerchantId}
              onChange={e => {
                setSelectedMerchantId(e.target.value);
                setEditOffer(null);
                setAddingBucket(null);
              }}
            >
              {merchantDirectory.map(merchant => (
                <option key={merchant.id} value={merchant.id}>{merchant.name}</option>
              ))}
            </select>
          </label>
        </div>
      </div>

      {selectedMerchant && (
        <div style={{ borderRadius:18, padding:"16px 18px", background:"rgba(255,255,255,0.04)", border:"1px solid rgba(255,255,255,0.08)", display:"flex", justifyContent:"space-between", gap:16, flexWrap:"wrap" }}>
          <div>
            <div style={{ fontWeight:800, fontSize:"1rem", color:"#f1ece7" }}>{selectedMerchant.name}</div>
            <div style={{ fontSize:"0.76rem", color:"#8b97ab", marginTop:3 }}>{selectedMerchant.category} · {selectedMerchant.note}</div>
          </div>
          <div style={{ display:"flex", gap:10, flexWrap:"wrap" }}>
            <div style={{ borderRadius:12, padding:"10px 12px", background:"rgba(255,255,255,0.04)", border:"1px solid rgba(255,255,255,0.06)", minWidth:112 }}>
              <div style={{ fontSize:"0.63rem", fontWeight:800, textTransform:"uppercase", letterSpacing:"0.1em", color:"#8b97ab", marginBottom:4 }}>Client</div>
              <div style={{ fontFamily:"'Barlow Condensed',sans-serif", fontSize:"1.5rem", fontWeight:800, color:"#84e3f3" }}>{selectedBuckets.clientOffers.length}</div>
            </div>
            <div style={{ borderRadius:12, padding:"10px 12px", background:"rgba(255,255,255,0.04)", border:"1px solid rgba(255,255,255,0.06)", minWidth:112 }}>
              <div style={{ fontSize:"0.63rem", fontWeight:800, textTransform:"uppercase", letterSpacing:"0.1em", color:"#8b97ab", marginBottom:4 }}>Agent</div>
              <div style={{ fontFamily:"'Barlow Condensed',sans-serif", fontSize:"1.5rem", fontWeight:800, color:"#96e7b2" }}>{selectedBuckets.agentOffers.length}</div>
            </div>
            <div style={{ borderRadius:12, padding:"10px 12px", background:"rgba(255,255,255,0.04)", border:"1px solid rgba(255,255,255,0.06)", minWidth:112 }}>
              <div style={{ fontSize:"0.63rem", fontWeight:800, textTransform:"uppercase", letterSpacing:"0.1em", color:"#8b97ab", marginBottom:4 }}>Live now</div>
              <div style={{ fontFamily:"'Barlow Condensed',sans-serif", fontSize:"1.5rem", fontWeight:800, color:"#fbbf24" }}>{[...selectedBuckets.clientOffers, ...selectedBuckets.agentOffers].filter(offer => offer.status === "active").length}</div>
            </div>
          </div>
        </div>
      )}

      <div style={{ display:"flex", gap:8, flexWrap:"wrap" }}>
        {merchantDirectory.map(merchant => (
          <button
            key={merchant.id}
            onClick={() => {
              setSelectedMerchantId(merchant.id);
              setEditOffer(null);
              setAddingBucket(null);
            }}
            style={{
              all:"unset",
              cursor:"pointer",
              padding:"8px 14px",
              borderRadius:999,
              border: selectedMerchantId === merchant.id ? "1px solid rgba(132,227,243,0.34)" : "1px solid rgba(255,255,255,0.1)",
              background: selectedMerchantId === merchant.id ? "rgba(132,227,243,0.1)" : "rgba(255,255,255,0.03)",
              color: selectedMerchantId === merchant.id ? "#84e3f3" : "#c6cedd",
              fontWeight:700,
              fontSize:"0.76rem",
            }}
          >
            {merchant.name}
          </button>
        ))}
      </div>

      {renderSection("Insurance clients", "These are the offers this merchant currently shows on the client-facing marketplace.", "clientOffers", selectedBuckets.clientOffers)}
      {renderSection("Insurance agents", "These are the offers this merchant currently shows on the insurance agent-facing pages.", "agentOffers", selectedBuckets.agentOffers)}
    </div>
  );
}

// ── MAIN MERCHANT PORTAL ───────────────────────────────────
function MerchantPortal() {
  const [view, setView] = useStateM("onboarding"); // onboarding | dashboard
  const [tab, setTab] = useStateM("offers"); // offers | faq | analytics

  return (
    <div style={{ display:"flex", flexDirection:"column", height:"100vh", overflow:"hidden", fontFamily:"'Manrope','Avenir Next','Segoe UI',sans-serif", background:"linear-gradient(180deg,#0b1829 0%,#060d18 100%)", color:"#f1ece7" }}>
      {/* TOP BAR */}
      <div style={{ display:"flex", alignItems:"center", gap:12, padding:"12px 24px", borderBottom:"1px solid rgba(255,255,255,0.07)", flexShrink:0 }}>
        <div style={{ display:"flex", alignItems:"center", gap:10 }}>
          <BrandLockup subtitle="Merchant portal" />
        </div>
        <div style={{ flex:1 }} />
        <div style={{ display:"flex", borderRadius:10, border:"1px solid rgba(255,255,255,0.1)", overflow:"hidden" }}>
          {[["onboarding","Onboarding"],["dashboard","Dashboard"]].map(([id,label]) => (
            <button key={id} onClick={() => setView(id)} style={{ all:"unset", cursor:"pointer", padding:"7px 16px", fontSize:"0.82rem", background: view===id ? "rgba(150,231,178,0.12)" : "transparent", color: view===id ? "#96e7b2" : "#8b97ab", borderRight: id!=="dashboard" ? "1px solid rgba(255,255,255,0.08)" : "none", transition:"all 150ms" }}>{label}</button>
          ))}
        </div>
      </div>

      {/* MAIN */}
      {view === "onboarding" ? (
        <div style={{ flex:1, overflowY:"auto", padding:"28px 32px", maxWidth:720, margin:"0 auto", width:"100%" }}>
          <MerchantOnboarding onComplete={() => setView("dashboard")} />
        </div>
      ) : (
        <div style={{ flex:1, overflow:"hidden", display:"flex", flexDirection:"column" }}>
          {/* Sub-tabs */}
          <div style={{ display:"flex", gap:0, borderBottom:"1px solid rgba(255,255,255,0.08)", padding:"0 24px", flexShrink:0 }}>
            {[["offers","My Offers"],["faq","FAQ Editor"],["analytics","Analytics"]].map(([id,label]) => (
              <button key={id} onClick={() => setTab(id)} style={{ all:"unset", cursor:"pointer", padding:"12px 18px", fontSize:"0.84rem", fontWeight: tab===id ? 800 : 500, color: tab===id ? "#96e7b2" : "#8b97ab", borderBottom: tab===id ? "2px solid #96e7b2" : "2px solid transparent", transition:"all 150ms" }}>{label}</button>
            ))}
          </div>
          <div style={{ flex:1, overflowY:"auto", padding:"24px 32px" }}>
            {tab === "offers" && <MerchantOfferDashboard />}
            {tab === "faq" && <FaqEditor />}
            {tab === "analytics" && (
              <div style={{ display:"grid", gap:16 }}>
                <div style={{ fontFamily:"'Barlow Condensed',sans-serif", fontSize:"1.8rem", fontWeight:800, color:"#f1ece7" }}>Analytics</div>
                <div style={{ display:"grid", gridTemplateColumns:"repeat(4,1fr)", gap:10 }}>
                  {[["Total claimed","47","All offers"],["Redeemed","34","Confirmed"],["Redemption rate","72%","↑ from 65%"],["Top agent","Alicia Tan","18 redemptions"]].map(([label,val,sub]) => (
                    <div key={label} style={{ borderRadius:16, padding:"16px 14px", background:"rgba(255,255,255,0.04)", border:"1px solid rgba(255,255,255,0.08)" }}>
                      <div style={{ fontSize:"0.66rem", fontWeight:800, textTransform:"uppercase", letterSpacing:"0.1em", color:"#8b97ab", marginBottom:6 }}>{label}</div>
                      <div style={{ fontFamily:"'Barlow Condensed',sans-serif", fontSize:"1.9rem", fontWeight:800, color:"#96e7b2", lineHeight:1 }}>{val}</div>
                      <div style={{ fontSize:"0.7rem", color:"#8b97ab", marginTop:4 }}>{sub}</div>
                    </div>
                  ))}
                </div>
                <div style={{ borderRadius:16, padding:"18px 20px", background:"rgba(255,255,255,0.04)", border:"1px solid rgba(255,255,255,0.07)" }}>
                  <div style={{ fontWeight:800, color:"#c6cedd", marginBottom:14 }}>Top referring agents</div>
                  {[["Alicia Tan","North Star","18 redemptions","#84e3f3"],["Marcus Goh","Harbourfront","9 redemptions","#ff9570"],["Elaine Lim","Verdant Risk","7 redemptions","#96e7b2"]].map(([name,agency,stat,color]) => (
                    <div key={name} style={{ display:"flex", alignItems:"center", gap:12, padding:"10px 0", borderBottom:"1px solid rgba(255,255,255,0.06)" }}>
                      <div style={{ width:34, height:34, borderRadius:10, background:`${color}22`, display:"grid", placeItems:"center", fontFamily:"'Barlow Condensed',sans-serif", fontWeight:800, color, fontSize:"0.9rem", flexShrink:0 }}>
                        {name.split(" ").map(w=>w[0]).join("")}
                      </div>
                      <div style={{ flex:1 }}>
                        <div style={{ fontWeight:700, fontSize:"0.86rem", color:"#f1ece7" }}>{name}</div>
                        <div style={{ fontSize:"0.72rem", color:"#8b97ab" }}>{agency}</div>
                      </div>
                      <div style={{ fontFamily:"'Barlow Condensed',sans-serif", fontSize:"1.1rem", fontWeight:800, color }}>{stat}</div>
                    </div>
                  ))}
                </div>
              </div>
            )}
          </div>
        </div>
      )}
    </div>
  );
}

window.MerchantPortal = MerchantPortal;
