/*
 * cenora-bundle-12-commerce.tsx — E-commerce Storefront module (V4 · #2)
 * ----------------------------------------------------------------------------
 * Native commerce — NOT a Shopify integration. Storefront, online orders,
 * promotions, B2B account portal. Live inventory & price pulled from
 * Warehouse + Products with NO SYNC (surfaced via <FlowChip dir="in">).
 * Online orders flow to CRM Sales Orders + Finance AR (FlowChip dir="out").
 *
 * Screens: Dashboard · Storefront editor · Orders · Promotions · B2B portal.
 *
 * Lift-out (engineers): split into
 *   apps/web/lib/mock/commerce.tsx
 *   apps/web/components/commerce/{dashboard,storefront,orders,promotions,b2b}.tsx
 * Globals referenced: TopBar, ActionBar, KpiTile, Card, CardHeader, CardTitle,
 * CardContent, Button, Badge, Icon, AICallout, Sheet, SearchBox, FilterChip,
 * FlowChip, formatCurrency, useRouter, cn.
 */
;/*__IIFE_WRAP_START__*/(function(){

/* ════════════════════════════════════════════════════════════════════════
 * Mock data — "Helios Direct", the group's native storefront.
 * Lift-out → apps/web/lib/mock/commerce.tsx
 * ════════════════════════════════════════════════════════════════════════ */
const COM_KPIS = {
  revenueMtd: 482300, revenueDeltaPct: 12.4,
  orders: 1147, ordersDeltaPct: 8.1,
  aov: 420, conversionPct: 3.2, conversionDeltaPct: 0.4,
  sessions: 35840, cartAbandonPct: 68.4,
  b2bShare: 61,
}
/* 14-day revenue sparkline (USD, thousands) */
const COM_REV_14D = [22, 25, 24, 28, 31, 27, 34, 36, 33, 39, 41, 38, 44, 48]
/* online order channel split */
const COM_CHANNELS = [
  { label: "B2B account portal", value: 61, tone: "brand" },
  { label: "Direct B2C web", value: 27, tone: "info" },
  { label: "Marketplace feeds", value: 8, tone: "accent" },
  { label: "POS · click-collect", value: 4, tone: "success" },
]

interface ComProduct { sku: string; name: string; price: number; currency: string; sold: number; revenue: number; stock: number; img: string }
const COM_TOP_PRODUCTS: ComProduct[] = [
  { sku: "HV-PMP-220", name: "Centrifugal Pump — 220kW",        price: 8400, currency: "USD", sold: 38, revenue: 319200, stock: 24, img: "box" },
  { sku: "HV-VLV-080", name: "Industrial Gate Valve 8\"",        price: 640,  currency: "USD", sold: 212, revenue: 135680, stock: 480, img: "sliders" },
  { sku: "HV-BRG-SKF", name: "SKF Spherical Bearing Set",        price: 295,  currency: "USD", sold: 318, revenue: 93810, stock: 96, img: "target" },
  { sku: "HV-FLT-HEPA",name: "HEPA Filter Cartridge (12-pack)",  price: 180,  currency: "USD", sold: 264, revenue: 47520, stock: 14, img: "layers" },
  { sku: "HV-LUB-X5",  name: "Synthetic Gear Oil X5 — 20L",      price: 145,  currency: "USD", sold: 410, revenue: 59450, stock: 0,  img: "package" },
]

interface ComOrder {
  id: string; customer: string; entity: string; channel: "B2B" | "B2C" | "Marketplace"
  items: number; total: number; currency: string; placed: string
  status: "paid" | "fulfilling" | "shipped" | "pending" | "refunded"
  soRef?: string
}
const COM_ORDERS: ComOrder[] = [
  { id: "WEB-2026-4821", customer: "Metro Rail Transit Corp", entity: "HVPH", channel: "B2B", items: 6, total: 18420, currency: "USD", placed: "2026-05-30 09:12", status: "paid", soRef: "SO-PH-2041" },
  { id: "WEB-2026-4820", customer: "Orchard Retail Group", entity: "HVSG", channel: "B2B", items: 3, total: 4260, currency: "SGD", placed: "2026-05-30 08:47", status: "fulfilling", soRef: "SO-SG-1188" },
  { id: "WEB-2026-4819", customer: "Walk-in · J. Tan", entity: "HVSG", channel: "B2C", items: 1, total: 295, currency: "SGD", placed: "2026-05-30 08:21", status: "shipped", soRef: "SO-SG-1187" },
  { id: "WEB-2026-4818", customer: "Kowloon Logistics Ltd", entity: "HVHK", channel: "B2B", items: 12, total: 31200, currency: "HKD", placed: "2026-05-29 17:55", status: "paid", soRef: "SO-HK-0904" },
  { id: "WEB-2026-4817", customer: "Walk-in · A. Reyes", entity: "HVPH", channel: "B2C", items: 2, total: 360, currency: "USD", placed: "2026-05-29 16:30", status: "pending" },
  { id: "WEB-2026-4816", customer: "Victoria Mining Pty", entity: "HVAU", channel: "B2B", items: 4, total: 33600, currency: "USD", placed: "2026-05-29 14:02", status: "shipped", soRef: "SO-AU-0455" },
  { id: "WEB-2026-4815", customer: "Sunrise Agri Holdings", entity: "HVIN", channel: "Marketplace", items: 1, total: 8400, currency: "USD", placed: "2026-05-29 11:40", status: "paid", soRef: "SO-IN-0231" },
  { id: "WEB-2026-4814", customer: "Walk-in · L. Cruz", entity: "HVPH", channel: "B2C", items: 5, total: 725, currency: "USD", placed: "2026-05-29 10:18", status: "refunded" },
  { id: "WEB-2026-4813", customer: "Pacific Steel Works", entity: "HVPH", channel: "B2B", items: 8, total: 5120, currency: "USD", placed: "2026-05-28 15:33", status: "shipped", soRef: "SO-PH-2039" },
  { id: "WEB-2026-4812", customer: "Darwin Port Services", entity: "HVAU", channel: "B2B", items: 2, total: 1280, currency: "USD", placed: "2026-05-28 13:09", status: "fulfilling", soRef: "SO-AU-0454" },
]

interface ComPromo {
  code: string; kind: "Percent" | "Fixed" | "Bundle" | "Tiered"
  detail: string; uses: number; cap?: number; revenue: number
  status: "active" | "scheduled" | "expired"; ends: string
}
const COM_PROMOS: ComPromo[] = [
  { code: "FLEET25",     kind: "Percent", detail: "25% off pumps & motors", uses: 84,  cap: 200, revenue: 142800, status: "active",    ends: "2026-06-30" },
  { code: "BULKVALVE",   kind: "Tiered",  detail: "Buy 50+ valves → 18% off", uses: 31, revenue: 58400, status: "active",    ends: "2026-07-15" },
  { code: "MAINTKIT",    kind: "Bundle",  detail: "Filter + Oil + Bearing kit", uses: 127, revenue: 41200, status: "active",   ends: "2026-08-01" },
  { code: "NEWB2B100",   kind: "Fixed",   detail: "$100 off first B2B order", uses: 46, cap: 100, revenue: 18400, status: "active",  ends: "2026-12-31" },
  { code: "EOFY2026",    kind: "Percent", detail: "End-of-FY · 15% sitewide", uses: 0, revenue: 0, status: "scheduled", ends: "2026-06-30" },
  { code: "SPRING10",    kind: "Percent", detail: "10% spring promo", uses: 312, revenue: 96400, status: "expired",  ends: "2026-04-30" },
]

interface B2BAccount {
  id: string; name: string; entity: string; tier: "Platinum" | "Gold" | "Silver"
  priceList: string; terms: string; creditLimit: number; creditUsed: number; currency: string
  ytdSpend: number; status: "good" | "watch" | "hold"
}
const COM_B2B: B2BAccount[] = [
  { id: "ACC-2041", name: "Metro Rail Transit Corp", entity: "HVPH", tier: "Platinum", priceList: "Rail OEM −22%", terms: "Net 60", creditLimit: 500000, creditUsed: 318400, currency: "USD", ytdSpend: 1284000, status: "good" },
  { id: "ACC-2044", name: "Victoria Mining Pty", entity: "HVAU", tier: "Platinum", priceList: "Mining −18%", terms: "Net 45", creditLimit: 750000, creditUsed: 612000, currency: "USD", ytdSpend: 2140000, status: "watch" },
  { id: "ACC-1188", name: "Orchard Retail Group", entity: "HVSG", tier: "Gold", priceList: "Retail −12%", terms: "Net 30", creditLimit: 200000, creditUsed: 44600, currency: "SGD", ytdSpend: 412000, status: "good" },
  { id: "ACC-0904", name: "Kowloon Logistics Ltd", entity: "HVHK", tier: "Gold", priceList: "Logistics −12%", terms: "Net 30", creditLimit: 300000, creditUsed: 298200, currency: "HKD", ytdSpend: 688000, status: "hold" },
  { id: "ACC-2039", name: "Pacific Steel Works", entity: "HVPH", tier: "Silver", priceList: "Standard −6%", terms: "Net 30", creditLimit: 120000, creditUsed: 31200, currency: "USD", ytdSpend: 196000, status: "good" },
  { id: "ACC-0231", name: "Sunrise Agri Holdings", entity: "HVIN", tier: "Silver", priceList: "Agri −8%", terms: "Net 30", creditLimit: 150000, creditUsed: 18400, currency: "USD", ytdSpend: 88000, status: "good" },
]

const COM_ORD_TONE: Record<string, string> = { paid: "success", fulfilling: "info", shipped: "brand", pending: "warn", refunded: "danger" }
const COM_PROMO_TONE: Record<string, string> = { active: "success", scheduled: "info", expired: "neutral" }
const COM_TIER_TONE: Record<string, string> = { Platinum: "brand", Gold: "accent", Silver: "neutral" }
const COM_ACC_TONE: Record<string, string> = { good: "success", watch: "warn", hold: "danger" }

/* ── small shared bits ─────────────────────────────────────────────── */
function ComSpark({ data, className }: { data: number[]; className?: string }) {
  const max = Math.max(...data) * 1.05, min = Math.min(...data) * 0.85
  const pts = data.map((v, i) => `${i === 0 ? "M" : "L"}${(i / (data.length - 1)) * 100},${(100 - ((v - min) / (max - min)) * 100).toFixed(2)}`).join(" ")
  return (
    <svg viewBox="0 0 100 100" preserveAspectRatio="none" className={cn("w-full h-full", className)}>
      <defs><linearGradient id="comFill" x1="0" x2="0" y1="0" y2="1"><stop offset="0%" stopColor="var(--brand)" stopOpacity="0.2" /><stop offset="100%" stopColor="var(--brand)" stopOpacity="0" /></linearGradient></defs>
      <path d={`${pts} L100,100 L0,100 Z`} fill="url(#comFill)" />
      <path d={pts} fill="none" stroke="var(--brand)" strokeWidth="1.5" vectorEffect="non-scaling-stroke" />
    </svg>
  )
}

/* ════════════════════════════════════════════════════════════════════════
 * 1 · DASHBOARD  /commerce
 * ════════════════════════════════════════════════════════════════════════ */
function CommerceDashboard() {
  const { push } = useRouter()
  return (
    <>
      <TopBar
        breadcrumb={[{ label: "E-commerce" }, { label: "Dashboard" }]}
        actions={
          <>
            <Button variant="ghost" leadingIcon="external" size="sm" onClick={() => push("/commerce/storefront")}>View storefront</Button>
            <Button variant="primary" leadingIcon="plus" size="sm" onClick={() => push("/commerce/orders")}>New order</Button>
          </>
        }
      />
      <div className="flex-1 overflow-y-auto bg-app">
        <div className="max-w-[1440px] mx-auto p-6 space-y-5">

          <div className="flex items-center gap-2 flex-wrap">
            <FlowChip to="/warehouse" label="Warehouse · live stock" icon="box" dir="in" />
            <FlowChip to="/products/list" label="Products · live price" icon="tag" dir="in" />
            <span className="text-[11px] text-ink-mute">— storefront reads master data directly. <strong className="text-ink-soft">No sync, no connector.</strong></span>
          </div>

          <div className="grid grid-cols-5 gap-3">
            <KpiTile accent="brand"   label="Online revenue · MTD" value={formatCurrency(COM_KPIS.revenueMtd)} sub="across 5 entities" delta={`+${COM_KPIS.revenueDeltaPct}%`} deltaDir="up" />
            <KpiTile accent="info"    label="Orders" value={COM_KPIS.orders.toLocaleString()} sub={`AOV ${formatCurrency(COM_KPIS.aov)}`} delta={`+${COM_KPIS.ordersDeltaPct}%`} deltaDir="up" />
            <KpiTile accent="success" label="Conversion" value={`${COM_KPIS.conversionPct}%`} sub={`${COM_KPIS.sessions.toLocaleString()} sessions`} delta={`+${COM_KPIS.conversionDeltaPct}pp`} deltaDir="up" />
            <KpiTile accent="accent"  label="B2B share" value={`${COM_KPIS.b2bShare}%`} sub="of online revenue" />
            <KpiTile accent="warn"    label="Cart abandon" value={`${COM_KPIS.cartAbandonPct}%`} sub="recovery email armed" />
          </div>

          <AICallout
            title="Stockout risk on 2 fast-moving SKUs — auto-replenish suggested"
            body="Synthetic Gear Oil X5 (HV-LUB-X5) is sold out and HEPA Filter Cartridge is down to 14 units against a 264/mo run-rate. Cenora AI drafted replenishment requisitions in Procurement and flagged the storefront listings to switch to 'backorder + ETA' rather than hide — preserving the demand signal."
          />

          <div className="grid grid-cols-[1.4fr_1fr] gap-4">
            <Card>
              <CardHeader>
                <CardTitle>Online revenue — last 14 days</CardTitle>
                <Badge variant="success" dot>+{COM_KPIS.revenueDeltaPct}% vs prior</Badge>
              </CardHeader>
              <div className="p-4 pt-3">
                <div className="font-serif text-3xl text-ink mb-1">{formatCurrency(COM_KPIS.revenueMtd)}</div>
                <div className="h-24"><ComSpark data={COM_REV_14D} /></div>
              </div>
            </Card>
            <Card>
              <CardHeader><CardTitle>Orders by channel</CardTitle></CardHeader>
              <CardContent className="space-y-3">
                {COM_CHANNELS.map(c => (
                  <div key={c.label}>
                    <div className="flex items-center justify-between text-[11.5px] mb-1">
                      <span className="text-ink-soft font-medium">{c.label}</span>
                      <span className="font-mono text-ink font-semibold">{c.value}%</span>
                    </div>
                    <div className="h-2 bg-cream-deep rounded-full overflow-hidden">
                      <div className="h-full rounded-full" style={{ width: `${c.value}%`, background: c.tone === "brand" ? "var(--brand)" : c.tone === "info" ? "var(--info)" : c.tone === "accent" ? "var(--accent)" : "var(--success)" }} />
                    </div>
                  </div>
                ))}
              </CardContent>
            </Card>
          </div>

          <Card>
            <CardHeader>
              <CardTitle>Top products — this month</CardTitle>
              <div className="flex items-center gap-2">
                <FlowChip to="/warehouse" label="Stock from Warehouse" icon="box" dir="in" />
                <button onClick={() => push("/products/list")} className="text-[11px] text-brand font-semibold hover:underline">All products →</button>
              </div>
            </CardHeader>
            <div className="grid grid-cols-[1.2fr_90px_90px_110px_130px_120px] px-4 py-2 bg-cream text-[10px] uppercase tracking-wider font-bold text-ink-mute border-b border-divider">
              <span>Product</span><span className="text-right">Price</span><span className="text-right">Sold</span><span className="text-right">Revenue</span><span className="text-right">Live stock</span><span></span>
            </div>
            {COM_TOP_PRODUCTS.map(p => (
              <div key={p.sku} className="grid grid-cols-[1.2fr_90px_90px_110px_130px_120px] px-4 py-2.5 items-center border-b border-divider-soft hover:bg-cream/60 transition-colors">
                <span className="flex items-center gap-2.5 min-w-0">
                  <span className="size-8 rounded-md bg-brand-soft text-brand flex items-center justify-center shrink-0"><Icon name={p.img as any} size={15} /></span>
                  <span className="min-w-0"><span className="block text-[12.5px] text-ink truncate">{p.name}</span><span className="font-mono text-[10px] text-ink-mute">{p.sku}</span></span>
                </span>
                <span className="text-right font-mono text-[12px] text-ink">{formatCurrency(p.price, p.currency)}</span>
                <span className="text-right font-mono text-[12px] text-ink-soft">{p.sold}</span>
                <span className="text-right font-mono text-[12px] text-ink">{formatCurrency(p.revenue)}</span>
                <span className="text-right">
                  {p.stock === 0
                    ? <Badge variant="danger" dot>Sold out</Badge>
                    : p.stock < 20 ? <Badge variant="warn" dot>{p.stock} left</Badge>
                    : <span className="font-mono text-[12px] text-success">{p.stock}</span>}
                </span>
                <span className="text-right"><FlowChip to="/warehouse" label="Warehouse" icon="box" dir="in" /></span>
              </div>
            ))}
          </Card>

        </div>
      </div>
    </>
  )
}

/* ════════════════════════════════════════════════════════════════════════
 * 2 · STOREFRONT EDITOR  /commerce/storefront  (rendered mini storefront)
 * ════════════════════════════════════════════════════════════════════════ */
const STORE_THEMES = [
  { id: "industrial", name: "Industrial", swatch: "#0D4A4A" },
  { id: "slate",      name: "Slate Pro",  swatch: "#334155" },
  { id: "sand",       name: "Warm Sand",  swatch: "#D4A96A" },
]
function CommerceStorefront() {
  const [theme, setTheme] = React.useState("industrial")
  const [device, setDevice] = React.useState<"desktop" | "mobile">("desktop")
  const [hero, setHero] = React.useState("Industrial parts, shipped same-day across APAC")
  const accent = STORE_THEMES.find(t => t.id === theme)?.swatch || "#0D4A4A"
  return (
    <>
      <TopBar breadcrumb={[{ label: "E-commerce" }, { label: "Storefront" }]} actions={<><Button variant="ghost" leadingIcon="external" size="sm">Open live</Button><Button variant="primary" leadingIcon="check" size="sm">Publish theme</Button></>} />
      <div className="flex-1 overflow-hidden bg-app grid grid-cols-[320px_1fr]">
        {/* Editor rail */}
        <div className="border-r border-divider bg-surface overflow-y-auto p-5 space-y-6">
          <div>
            <div className="text-[10px] uppercase tracking-wider font-bold text-ink-mute mb-2">Theme</div>
            <div className="grid grid-cols-3 gap-2">
              {STORE_THEMES.map(t => (
                <button key={t.id} onClick={() => setTheme(t.id)} className={cn("rounded-lg border p-2 text-left transition-all", theme === t.id ? "border-brand ring-1 ring-brand" : "border-divider hover:border-divider-strong")}>
                  <span className="block h-8 rounded mb-1.5" style={{ background: t.swatch }} />
                  <span className="text-[10.5px] font-medium text-ink">{t.name}</span>
                </button>
              ))}
            </div>
          </div>
          <div>
            <div className="text-[10px] uppercase tracking-wider font-bold text-ink-mute mb-2">Hero headline</div>
            <textarea value={hero} onChange={e => setHero(e.target.value)} rows={3} className="w-full text-[12.5px] rounded-md border border-divider bg-cream/50 p-2.5 resize-none focus:outline-none focus:ring-1 focus:ring-brand" />
          </div>
          <div>
            <div className="text-[10px] uppercase tracking-wider font-bold text-ink-mute mb-2">Sections</div>
            <div className="space-y-1.5">
              {["Hero banner","Featured categories","Best sellers","B2B sign-in CTA","Footer"].map((s, i) => (
                <div key={s} className="flex items-center gap-2 px-2.5 py-2 rounded-md border border-divider bg-cream/40 text-[11.5px] text-ink-soft">
                  <Icon name="menu" size={12} className="text-ink-faint" /><span className="flex-1">{s}</span>
                  {i < 3 && <Badge variant="success" dot>on</Badge>}
                </div>
              ))}
            </div>
          </div>
          <div className="bg-brand-soft/40 border border-brand/20 rounded-lg p-3">
            <div className="flex items-center gap-2 mb-1.5"><Icon name="box" size={13} className="text-brand" /><span className="text-[11px] font-semibold text-ink">Catalog source</span></div>
            <p className="text-[10.5px] text-ink-soft leading-relaxed">Listings render live from <strong>Products</strong> + <strong>Warehouse</strong>. Edits to price or stock there reflect instantly — no export, no sync job.</p>
            <div className="mt-2 flex gap-1.5"><FlowChip to="/products/list" label="Products" icon="tag" dir="in" /><FlowChip to="/warehouse" label="Stock" icon="box" dir="in" /></div>
          </div>
        </div>

        {/* Preview */}
        <div className="overflow-y-auto p-6 flex flex-col items-center">
          <div className="flex items-center gap-1 bg-cream border border-divider rounded-md p-0.5 mb-4">
            {(["desktop","mobile"] as const).map(d => (
              <button key={d} onClick={() => setDevice(d)} className={cn("h-7 px-3 rounded text-[11px] font-semibold inline-flex items-center gap-1.5 transition-colors", device === d ? "bg-surface text-brand shadow-sm" : "text-ink-mute")}>
                <Icon name={d === "desktop" ? "monitor" : "smartphone"} size={12} />{d === "desktop" ? "Desktop" : "Mobile"}
              </button>
            ))}
          </div>
          <div className={cn("bg-white rounded-xl border border-divider shadow-lg overflow-hidden transition-all", device === "desktop" ? "w-full max-w-[760px]" : "w-[300px]")}>
            {/* mini storefront */}
            <div className="h-10 flex items-center justify-between px-4 border-b" style={{ background: accent }}>
              <span className="text-white font-serif text-[15px]">Helios Direct</span>
              <div className="flex items-center gap-3 text-white/90"><Icon name="search" size={13} /><Icon name="user" size={13} /><Icon name="wallet" size={13} /></div>
            </div>
            <div className="p-5 text-center" style={{ background: `${accent}10` }}>
              <div className="font-serif text-[20px] text-slate-800 leading-tight max-w-[420px] mx-auto">{hero}</div>
              <button className="mt-3 h-9 px-5 rounded-md text-white text-[12px] font-semibold" style={{ background: accent }}>Shop industrial parts</button>
            </div>
            <div className="p-4">
              <div className="text-[11px] font-bold uppercase tracking-wider text-slate-400 mb-2">Best sellers</div>
              <div className={cn("grid gap-3", device === "desktop" ? "grid-cols-3" : "grid-cols-2")}>
                {COM_TOP_PRODUCTS.slice(0, device === "desktop" ? 3 : 2).map(p => (
                  <div key={p.sku} className="border border-slate-200 rounded-lg p-2.5">
                    <div className="h-14 rounded bg-slate-100 flex items-center justify-center mb-2 text-slate-400"><Icon name={p.img as any} size={20} /></div>
                    <div className="text-[10.5px] font-medium text-slate-700 leading-tight line-clamp-2">{p.name}</div>
                    <div className="flex items-center justify-between mt-1.5">
                      <span className="font-mono text-[11px] font-bold text-slate-900">{formatCurrency(p.price, p.currency)}</span>
                      {p.stock === 0 ? <span className="text-[8.5px] font-bold text-rose-600 uppercase">Backorder</span> : <span className="text-[8.5px] font-bold text-emerald-600 uppercase">In stock</span>}
                    </div>
                  </div>
                ))}
              </div>
            </div>
          </div>
          <div className="mt-3 text-[10.5px] text-ink-mute">Live preview · {device} · theme “{STORE_THEMES.find(t => t.id === theme)?.name}”</div>
        </div>
      </div>
    </>
  )
}

/* ════════════════════════════════════════════════════════════════════════
 * 3 · ORDERS  /commerce/orders  (online → Sales Orders + AR)
 * ════════════════════════════════════════════════════════════════════════ */
function CommerceOrders() {
  const { push } = useRouter()
  const [channel, setChannel] = React.useState("all")
  const [query, setQuery] = React.useState("")
  const list = COM_ORDERS.filter(o =>
    (channel === "all" || o.channel === channel) &&
    (!query.trim() || o.customer.toLowerCase().includes(query.toLowerCase()) || o.id.toLowerCase().includes(query.toLowerCase()))
  )
  const counts = { all: COM_ORDERS.length, B2B: COM_ORDERS.filter(o => o.channel === "B2B").length, B2C: COM_ORDERS.filter(o => o.channel === "B2C").length, Marketplace: COM_ORDERS.filter(o => o.channel === "Marketplace").length }
  return (
    <>
      <TopBar breadcrumb={[{ label: "E-commerce" }, { label: "Orders" }]} />
      <ActionBar
        title="Online Orders"
        status={`${COM_ORDERS.length} orders this cycle · each posts a Sales Order + AR invoice automatically`}
        search={<SearchBox value={query} onChange={setQuery} placeholder="Search orders…" className="w-56" />}
        primary={<Button variant="primary" leadingIcon="plus" size="sm">New order</Button>}
        filters={(["all","B2B","B2C","Marketplace"] as const).map(c => (
          <FilterChip key={c} active={channel === c} count={(counts as any)[c]} onClick={() => setChannel(c)}>{c === "all" ? "All channels" : c}</FilterChip>
        ))}
      />
      <div className="flex-1 overflow-y-auto bg-app">
        <div className="max-w-[1440px] mx-auto p-6 space-y-4">
          <div className="bg-brand-soft/40 border border-brand/20 rounded-lg px-4 py-3 flex items-center gap-3">
            <div className="size-7 rounded-full bg-brand-soft text-brand flex items-center justify-center shrink-0"><Icon name="git-branch" size={14} /></div>
            <div className="flex-1 text-[12px] text-ink-soft">Every paid web order drops a <strong className="text-ink">Sales Order</strong> into CRM and an <strong className="text-ink">AR invoice</strong> into Finance — fulfilment pulls stock straight from Warehouse.</div>
            <FlowChip to="/crm/sales-orders" label="CRM · Sales Orders" icon="receipt" />
            <FlowChip to="/finance/ar" label="Finance · AR" icon="dollar" />
          </div>
          <Card>
            <div className="grid grid-cols-[150px_1.5fr_80px_100px_70px_120px_110px_130px] px-4 py-2 bg-cream text-[10px] uppercase tracking-wider font-bold text-ink-mute border-b border-divider">
              <span>Order</span><span>Customer</span><span>Entity</span><span>Channel</span><span className="text-right">Items</span><span className="text-right">Total</span><span>Status</span><span>Sales Order</span>
            </div>
            {list.map(o => (
              <div key={o.id} className="grid grid-cols-[150px_1.5fr_80px_100px_70px_120px_110px_130px] px-4 py-2.5 items-center border-b border-divider-soft hover:bg-cream/60 transition-colors">
                <span className="font-mono text-[11px] text-brand-mid">{o.id}</span>
                <span className="text-[12.5px] text-ink truncate">{o.customer}</span>
                <span className="text-[11px] text-ink-mute">{o.entity}</span>
                <span><Badge variant={o.channel === "B2B" ? "brand" : o.channel === "B2C" ? "info" : "accent"}>{o.channel}</Badge></span>
                <span className="text-right font-mono text-[12px] text-ink-soft">{o.items}</span>
                <span className="text-right font-mono text-[12px] text-ink">{formatCurrency(o.total, o.currency)}</span>
                <span><Badge variant={COM_ORD_TONE[o.status] as any} dot>{o.status}</Badge></span>
                <span>{o.soRef ? <button onClick={() => push("/crm/sales-orders")} className="font-mono text-[10.5px] text-brand hover:underline">{o.soRef}</button> : <span className="text-[10.5px] text-ink-faint">— pending —</span>}</span>
              </div>
            ))}
          </Card>
        </div>
      </div>
    </>
  )
}

/* ════════════════════════════════════════════════════════════════════════
 * 4 · PROMOTIONS  /commerce/promotions
 * ════════════════════════════════════════════════════════════════════════ */
function CommercePromotions() {
  const [status, setStatus] = React.useState("all")
  const list = COM_PROMOS.filter(p => status === "all" || p.status === status)
  const active = COM_PROMOS.filter(p => p.status === "active")
  const revenue = active.reduce((s, p) => s + p.revenue, 0)
  return (
    <>
      <TopBar breadcrumb={[{ label: "E-commerce" }, { label: "Promotions" }]} />
      <ActionBar
        title="Promotions & Discounts"
        status={`${active.length} live promos · ${formatCurrency(revenue)} attributed revenue`}
        primary={<Button variant="primary" leadingIcon="plus" size="sm">New promotion</Button>}
        filters={(["all","active","scheduled","expired"] as const).map(s => (
          <FilterChip key={s} active={status === s} onClick={() => setStatus(s)}>{s === "all" ? "All" : s[0].toUpperCase() + s.slice(1)}</FilterChip>
        ))}
      />
      <div className="flex-1 overflow-y-auto bg-app">
        <div className="max-w-[1440px] mx-auto p-6">
          <div className="grid grid-cols-3 gap-4">
            {list.map(p => (
              <div key={p.code} className="bg-surface border border-divider rounded-lg p-4">
                <div className="flex items-start justify-between gap-2">
                  <div>
                    <div className="font-mono text-[15px] font-bold text-brand tracking-wide">{p.code}</div>
                    <div className="text-[11.5px] text-ink-soft mt-0.5">{p.detail}</div>
                  </div>
                  <Badge variant={COM_PROMO_TONE[p.status] as any} dot>{p.status}</Badge>
                </div>
                <div className="flex items-center gap-2 mt-3"><Badge variant="neutral">{p.kind}</Badge><span className="text-[10.5px] text-ink-mute">ends {p.ends}</span></div>
                <div className="grid grid-cols-2 gap-2 mt-3 pt-3 border-t border-divider-soft text-[11px]">
                  <div><div className="text-ink-mute text-[10px] uppercase tracking-wide">Redemptions</div><div className="font-mono font-semibold text-ink mt-0.5">{p.uses}{p.cap ? ` / ${p.cap}` : ""}</div></div>
                  <div><div className="text-ink-mute text-[10px] uppercase tracking-wide">Revenue</div><div className="font-mono font-semibold text-ink mt-0.5">{formatCurrency(p.revenue)}</div></div>
                </div>
                {p.cap && <div className="mt-2 h-1.5 bg-cream-deep rounded-full overflow-hidden"><div className="h-full rounded-full bg-brand" style={{ width: `${Math.min((p.uses / p.cap) * 100, 100)}%` }} /></div>}
              </div>
            ))}
          </div>
        </div>
      </div>
    </>
  )
}

/* ════════════════════════════════════════════════════════════════════════
 * 5 · B2B PORTAL  /commerce/b2b
 * ════════════════════════════════════════════════════════════════════════ */
function CommerceB2B() {
  const { push } = useRouter()
  const [query, setQuery] = React.useState("")
  const [sel, setSel] = React.useState<B2BAccount | null>(null)
  const list = COM_B2B.filter(a => !query.trim() || a.name.toLowerCase().includes(query.toLowerCase()) || a.id.toLowerCase().includes(query.toLowerCase()))
  return (
    <>
      <TopBar breadcrumb={[{ label: "E-commerce" }, { label: "B2B Accounts" }]} />
      <ActionBar
        title="B2B Account Portal"
        status={`${COM_B2B.length} contract accounts · negotiated price lists · credit terms`}
        search={<SearchBox value={query} onChange={setQuery} placeholder="Search accounts…" className="w-56" />}
        primary={<Button variant="primary" leadingIcon="plus" size="sm">Invite account</Button>}
      />
      <div className="flex-1 overflow-y-auto bg-app">
        <div className="max-w-[1440px] mx-auto p-6">
          <Card>
            <div className="grid grid-cols-[110px_1.6fr_90px_1.1fr_100px_1.4fr_120px] px-4 py-2 bg-cream text-[10px] uppercase tracking-wider font-bold text-ink-mute border-b border-divider">
              <span>Account</span><span>Company</span><span>Tier</span><span>Price list</span><span>Terms</span><span>Credit used</span><span className="text-right">YTD spend</span>
            </div>
            {list.map(a => {
              const pct = (a.creditUsed / a.creditLimit) * 100
              return (
                <button key={a.id} onClick={() => setSel(a)} className="w-full grid grid-cols-[110px_1.6fr_90px_1.1fr_100px_1.4fr_120px] px-4 py-2.5 text-left items-center border-b border-divider-soft hover:bg-cream/60 transition-colors">
                  <span className="font-mono text-[11px] text-brand-mid">{a.id}</span>
                  <span className="text-[12.5px] text-ink truncate">{a.name}</span>
                  <span><Badge variant={COM_TIER_TONE[a.tier] as any}>{a.tier}</Badge></span>
                  <span className="text-[11.5px] text-ink-soft truncate">{a.priceList}</span>
                  <span className="text-[11px] text-ink-mute">{a.terms}</span>
                  <span className="flex items-center gap-2">
                    <span className="flex-1 h-2 bg-cream-deep rounded-full overflow-hidden"><span className={cn("block h-full rounded-full", pct > 90 ? "bg-danger" : pct > 70 ? "bg-warn" : "bg-success")} style={{ width: `${pct}%` }} /></span>
                    <span className="font-mono text-[10px] text-ink-mute">{pct.toFixed(0)}%</span>
                  </span>
                  <span className="text-right font-mono text-[12px] text-ink">{formatCurrency(a.ytdSpend)}</span>
                </button>
              )
            })}
          </Card>
        </div>
      </div>

      <Sheet open={!!sel} onOpenChange={(o: boolean) => !o && setSel(null)}>
        {sel && (
          <div className="w-[460px] h-full flex flex-col bg-surface">
            <div className="px-5 py-4 border-b border-divider flex items-start justify-between">
              <div>
                <div className="flex items-center gap-2"><span className="font-mono text-[10.5px] text-ink-mute">{sel.id}</span><Badge variant={COM_TIER_TONE[sel.tier] as any}>{sel.tier}</Badge><Badge variant={COM_ACC_TONE[sel.status] as any} dot>{sel.status}</Badge></div>
                <div className="font-serif text-xl text-ink mt-1">{sel.name}</div>
                <div className="text-[11.5px] text-ink-mute">{sel.entity} · {sel.priceList}</div>
              </div>
              <button onClick={() => setSel(null)} className="text-ink-mute hover:text-ink p-1"><Icon name="x" size={16} /></button>
            </div>
            <div className="flex-1 overflow-y-auto p-5 space-y-4">
              <div className="grid grid-cols-2 gap-2">
                <div className="bg-cream border border-divider rounded-lg px-3 py-2"><div className="text-[9.5px] uppercase tracking-wider font-bold text-ink-mute">Credit limit</div><div className="font-mono text-[14px] text-ink font-semibold mt-0.5">{formatCurrency(sel.creditLimit, sel.currency)}</div></div>
                <div className="bg-cream border border-divider rounded-lg px-3 py-2"><div className="text-[9.5px] uppercase tracking-wider font-bold text-ink-mute">Available</div><div className="font-mono text-[14px] text-ink font-semibold mt-0.5">{formatCurrency(sel.creditLimit - sel.creditUsed, sel.currency)}</div></div>
              </div>
              <div>
                <div className="flex items-center justify-between text-[11px] mb-1.5"><span className="text-[10px] uppercase tracking-wider font-bold text-ink-mute">Credit utilization</span><span className="font-mono text-ink font-semibold">{((sel.creditUsed / sel.creditLimit) * 100).toFixed(0)}%</span></div>
                <div className="h-2.5 bg-cream-deep rounded-full overflow-hidden"><div className={cn("h-full rounded-full", (sel.creditUsed / sel.creditLimit) > 0.9 ? "bg-danger" : "bg-brand")} style={{ width: `${(sel.creditUsed / sel.creditLimit) * 100}%` }} /></div>
              </div>
              <div className="flex items-center gap-2"><FlowChip to="/finance/ar" label="Finance · AR ledger" icon="dollar" /><FlowChip to="/crm/customers" label="CRM record" icon="user" /></div>
              {sel.status === "hold" && <div className="bg-danger-soft/50 border border-danger/30 rounded-lg p-3 text-[11.5px] text-ink-soft"><strong className="text-danger">Credit hold.</strong> New web orders require prepayment until balance clears.</div>}
            </div>
            <div className="px-5 py-3 border-t border-divider flex items-center gap-2">
              <Button variant="primary" size="sm" leadingIcon="edit">Edit price list</Button>
              <Button variant="ghost" size="sm" leadingIcon="x" className="ml-auto" onClick={() => setSel(null)}>Close</Button>
            </div>
          </div>
        )}
      </Sheet>
    </>
  )
}

/* ════════════════════════════════════════════════════════════════════════
 * Exports → globals
 * ════════════════════════════════════════════════════════════════════════ */
Object.assign(globalThis as any, {
  CommerceDashboard, CommerceStorefront, CommerceOrders, CommercePromotions, CommerceB2B,
})

})();/*__IIFE_WRAP_END__*/
