// kova/price.jsx — Wave E · Pricing Lead
// ----------------------------------------------------------------
// Architecture v7 §8.4 implementation. Routes:
//   /price                  PriceOverviewPage
//   /price/rates            PriceRatesPage (metal + stone rate manager)
//   /price/cosign           PriceCosignQueuePage  (NEW · cross-module bridge)
//   /price/cosign/:id       PriceCosignDetailPage (DecisionCard reused)
//   /price/quotes           PriceQuotesPage
//   /price/quotes/:id       PriceQuoteDetailPage (View Formula drawer)
//   /price/skus/:id         PriceSkuDetailPage (lighter · linked from other pages)
//   /price/margin-risk      PriceMarginRiskPage
//
// PL workflow (architecture §8.4 + §2 runtime loop):
//   • Co-sign work · IM reprice actions, HoM ceiling-change briefs, anything
//     where chain has "Pricing Lead · state: now". Approve advances to CEO;
//     Reject returns to author with reason. This is the cross-module bridge
//     IM stress-tested.
//   • Rates · refresh from market feed, accept new rates, propose ceiling
//     updates as Decisions (CEO sign required).
//   • Quotes · draft → simulate (recalc) → submit to CEO if breach; otherwise
//     PL signs directly. "View Formula" shows the deterministic math.
//   • Margin risk · monitor SKUs near floor, hand off problem cases to IM
//     for reprice action.
//
// Architecture critical rule (§8.4):
//   "Agent explains. PRICE engine calculates."
// → every recommendation surfaces a formula. The "View Formula" button is
//   wired everywhere to open evidence with the math tab pre-selected.
// ----------------------------------------------------------------

const {
  Btn, Chip, Kbd, Icon, Card, PageHead, KPITile, Tabs, StatusBadge, RunBadge,
  VerificationStamp, ConfidenceMeter, ApprovalChain,
  EmptyState,
  DecisionCard, RunObject, EvidencePanel, WorkflowTimeline,
  ApprovalSurface,
  ModuleOverview, DetailObject, ListTable,
  SEED_PRICE_RATES, SEED_PRICE_QUOTES, SEED_PRICE_MARGIN_RISK,
  SEED_PRICING_COSIGN_QUEUE,
} = window.K;

const { useState, useMemo } = React;


/* ============================================================
   RATE ROW · new molecule for the rates table
   Composes atoms only (Chip + small layout)
   ============================================================ */
const RateRow = ({ rate, onEditRate, editable }) => {
  const isUp   = rate.deltaDir === 'up';
  const isDown = rate.deltaDir === 'down';
  const isFlat = rate.deltaDir === 'flat';
  return (
    <div style={{ display: 'grid', gridTemplateColumns: '1.3fr 1fr 0.8fr 1.2fr 0.8fr auto',
                  gap: 16, alignItems: 'center', padding: '12px 0',
                  borderTop: '1px solid var(--line-2)', fontSize: 13 }}>
      <div>
        <div style={{ color: 'var(--ink)', fontWeight: 500 }}>{rate.spec}</div>
        <div className="t-meta" style={{ marginTop: 2 }}>per {rate.per} · source: <span className="t-mono">{rate.source}</span></div>
      </div>
      <div style={{ fontFamily: 'var(--font-mono)', fontVariantNumeric: 'tabular-nums',
                    fontSize: 15, color: 'var(--ink)', fontWeight: 600 }}>
        {rate.rate.display}
      </div>
      <div className="t-mono" style={{
        color: isUp ? 'var(--success)' : isDown ? 'var(--danger)' : 'var(--mute)',
        fontSize: 12,
      }}>
        {isUp && '↑ '}{isDown && '↓ '}{rate.delta}
      </div>
      <div className="t-meta">updated · {rate.updatedAt}</div>
      <Chip variant={rate.kind === 'metal' ? 'info' : 'accent'}>{rate.kind}</Chip>
      <Btn size="sm" variant="ghost"
           disabled={!editable || rate.source === 'derived'}
           onClick={() => onEditRate?.(rate.id)}>
        Edit
      </Btn>
    </div>
  );
};


/* ============================================================
   COSIGN ROW · compact row for the PL cosign queue
   Reuses ApprovalRow CSS pattern. Composes only atoms/molecules.
   ============================================================ */
const CosignRow = ({ item, onOpen, onApprove, onReject }) => {
  const breach = item.ceilingCheck === 'breach';
  return (
    <div className="k-approval-row" style={{ '--m-mod': 'var(--m-price)' }}>
      <div className="k-approval-stripe" />
      <div className="k-approval-body" style={{ cursor: 'pointer' }} onClick={() => onOpen?.(item.id)}>
        <div className="k-approval-head">
          <Chip variant="mute" dot>FROM {(item.sourceModule || '').toUpperCase()}</Chip>
          <Chip variant={item.type === 'reprice' ? 'warn' : 'info'} dot>{item.type === 'ceiling_change' ? 'CEILING CHANGE' : item.type.toUpperCase()}</Chip>
          {breach && <Chip variant="danger" dot>CEILING BREACH</Chip>}
          <RunBadge id={item.runId} version={item.runVersion} when={item.runWhen} />
          <span className="t-meta" style={{ marginLeft: 'auto' }}>by · {item.submittedBy}</span>
        </div>
        <div className="k-approval-title">{item.title}</div>
        <div className="k-approval-stats">
          {item.stats.slice(0, 4).map((s, i) => (
            <div className="k-approval-stat" key={i}>
              <span className="l">{s.label}</span>
              <span className={`v${s.color === 'success' ? ' is-success' : s.color === 'danger' ? ' is-danger' : ''}`}>{s.value}</span>
            </div>
          ))}
        </div>
      </div>
      <div className="k-approval-actions" onClick={(e) => e.stopPropagation()}>
        <Btn size="sm" variant={breach ? 'reject' : 'primary'} onClick={() => onApprove?.(item.id)}>
          {breach ? 'Co-sign breach' : 'Co-sign'}
        </Btn>
        <Btn size="sm" variant="reject" onClick={() => onReject?.(item.id)}>Reject</Btn>
      </div>
    </div>
  );
};


/* ============================================================
   QUOTE ROW · compact row for the quote list
   ============================================================ */
const QuoteRow = ({ quote, onOpen }) => {
  const breach = quote.ceilingCheck === 'breach';
  return (
    <div className="k-approval-row" style={{ '--m-mod': 'var(--m-price)', cursor: 'pointer' }}
         onClick={() => onOpen?.(quote.id)}>
      <div className="k-approval-stripe" />
      <div className="k-approval-body">
        <div className="k-approval-head">
          <Chip variant={
            quote.status === 'approved' ? 'success' :
            quote.status === 'submitted' || quote.status === 'pending' ? 'warn' : 'mute'
          } dot>{quote.status.toUpperCase()}</Chip>
          {breach && <Chip variant="danger" dot>CEILING BREACH</Chip>}
          <span className="t-mono" style={{ fontSize: 11, color: 'var(--mute)' }}>{quote.id}</span>
          <span className="t-meta" style={{ marginLeft: 'auto' }}>updated · {quote.updatedAt}</span>
        </div>
        <div className="k-approval-title">{quote.customer}</div>
        <div className="t-meta" style={{ marginTop: 4 }}>{quote.segment}</div>
        <div className="k-approval-stats">
          <div className="k-approval-stat"><span className="l">SKUs</span><span className="v">{quote.skuCount}</span></div>
          <div className="k-approval-stat"><span className="l">Total</span><span className="v">{quote.totalAmount.display}</span></div>
          <div className="k-approval-stat"><span className="l">Discount</span><span className="v">{quote.discountPercent} %</span></div>
          <div className="k-approval-stat">
            <span className="l">Margin</span>
            <span className={`v${quote.margin < quote.marginFloor ? ' is-danger' : quote.margin >= quote.marginFloor + 4 ? ' is-success' : ''}`}>
              {quote.margin} %
            </span>
          </div>
        </div>
      </div>
    </div>
  );
};


/* ============================================================
   PRICE OVERVIEW
   Template: ModuleOverview
   ============================================================ */
const PriceOverviewPage = ({
  user = 'Karan', rates, quotes, cosignQueue, marginRisk,
  onRefreshRates, onCreateQuote, onOpenCosign, onApproveCosign, onRejectCosign,
  onOpenQuotes, onOpenRates, onOpenMarginRisk, onOpenCmdK,
}) => {
  const cosignPending = cosignQueue.filter(c => c.status === 'pending');
  const draftQuotes = quotes.filter(q => q.status === 'draft' || q.status === 'pending');
  const submittedQuotes = quotes.filter(q => q.status === 'submitted');
  const breaches = marginRisk.filter(r => r.risk === 'breach');
  const primary = cosignPending[0];

  const pageHead = (
    <PageHead
      crumb={['PRICE', 'today', '09:42 IST']}
      title={`Good morning, ${user}.`}
      subtitle={cosignPending.length === 0
        ? 'No co-signs waiting. Quotes and rates are clean.'
        : `${cosignPending.length} co-sign${cosignPending.length === 1 ? '' : 's'} waiting · ${draftQuotes.length} draft quote${draftQuotes.length === 1 ? '' : 's'} · ${breaches.length} margin-floor breach${breaches.length === 1 ? '' : 'es'}.`}
      actions={
        <>
          <Btn size="sm" onClick={onRefreshRates}>Refresh rates</Btn>
          <Btn size="sm" onClick={onCreateQuote}>Create quote</Btn>
          {primary
            ? <Btn size="sm" variant="primary" onClick={() => onOpenCosign?.(primary.id)} kbd="⌘⏎">
                Open next co-sign
              </Btn>
            : <Btn size="sm" variant="primary" onClick={onOpenQuotes}>Open quotes</Btn>}
        </>
      }
    />
  );

  const kpis = [
    <KPITile key="a" mod="price"     label="Co-signs awaiting"   value={String(cosignPending.length)}
             foot={cosignPending.length ? `${breaches.length ? `${breaches.length} ceiling breach` : 'all within floor'}` : 'inbox zero'} />,
    <KPITile key="b" mod="price"     label="Draft quotes"        value={String(draftQuotes.length)}
             foot={`${submittedQuotes.length} submitted to CEO`} />,
    <KPITile key="c" mod="approvals" label="Margin Δ · 7 d"      value="+ 6.4 %"
             valueColor="var(--success)"
             foot="weighted across all SKUs" />,
    <KPITile key="d" mod="connect"   label="Rates · 24K"         value={rates.find(r => r.id === 'r-24kg')?.rate.display || '—'}
             foot={`updated · ${rates.find(r => r.id === 'r-24kg')?.updatedAt || '—'}`} />,
  ];

  const primaryNode = primary && (
    <DecisionCard
      {...primary}
      onEvidence={() => onOpenCosign?.(primary.id)}
      onRunHistory={() => location.hash = `monitor/${primary.runId}`}
      onReject={() => onRejectCosign?.(primary.id)}
      onApprove={() => onApproveCosign?.(primary.id)}
      primaryKbd="⌘⏎"
    />
  );

  const cosignTeaser = cosignPending.length > 1 && (
    <Card>
      <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', marginBottom: 12 }}>
        <div className="t-eyebrow">More co-sign requests · {cosignPending.length - 1}</div>
        <Btn size="sm" variant="ghost" onClick={() => location.hash = 'price/cosign'}>See all ›</Btn>
      </div>
      <div style={{ display: 'flex', flexDirection: 'column', gap: 10 }}>
        {cosignPending.slice(1).map(item => (
          <CosignRow key={item.id} item={item}
                     onOpen={onOpenCosign}
                     onApprove={onApproveCosign}
                     onReject={onRejectCosign} />
        ))}
      </div>
    </Card>
  );

  const ratesSnapshot = (
    <Card>
      <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', marginBottom: 12 }}>
        <div className="t-eyebrow">Rate snapshot · top 5</div>
        <Btn size="sm" variant="ghost" onClick={onOpenRates}>All rates ›</Btn>
      </div>
      <div style={{ display: 'flex', flexDirection: 'column', gap: 8 }}>
        {rates.slice(0, 5).map(r => (
          <div key={r.id} style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'baseline', fontSize: 13 }}>
            <span style={{ color: 'var(--ink)' }}>{r.spec}</span>
            <span style={{ display: 'flex', gap: 10, alignItems: 'baseline' }}>
              <span className="t-mono" style={{ color: 'var(--ink)', fontWeight: 600 }}>{r.rate.display}</span>
              <span className="t-mono" style={{
                fontSize: 11,
                color: r.deltaDir === 'up' ? 'var(--success)' :
                       r.deltaDir === 'down' ? 'var(--danger)' : 'var(--mute)',
              }}>{r.delta}</span>
            </span>
          </div>
        ))}
      </div>
    </Card>
  );

  const side = [
    <Card key="quick">
      <div className="t-eyebrow" style={{ marginBottom: 10 }}>Quick actions</div>
      <div style={{ display: 'flex', flexDirection: 'column', gap: 6 }}>
        <Btn size="sm" variant="ghost" onClick={onRefreshRates}>Refresh rates</Btn>
        <Btn size="sm" variant="ghost" onClick={onCreateQuote}>Create new quote</Btn>
        <Btn size="sm" variant="ghost" onClick={() => location.hash = 'price/cosign'}>Open co-sign queue</Btn>
        <Btn size="sm" variant="ghost" onClick={onOpenMarginRisk}>Margin risk · {marginRisk.length}</Btn>
        <Btn size="sm" variant="ghost" onClick={onOpenCmdK} kbd="⌘ K">Jump to…</Btn>
      </div>
    </Card>,
    <Card key="risk">
      <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', marginBottom: 10 }}>
        <div className="t-eyebrow">Margin risk · {marginRisk.length} SKU{marginRisk.length === 1 ? '' : 's'}</div>
        <Btn size="sm" variant="ghost" onClick={onOpenMarginRisk}>Open ›</Btn>
      </div>
      <div style={{ display: 'flex', flexDirection: 'column', gap: 10 }}>
        {marginRisk.slice(0, 3).map(r => (
          <div key={r.id} style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'baseline', fontSize: 13 }}>
            <div style={{ minWidth: 0, flex: 1, paddingRight: 8 }}>
              <div className="t-mono" style={{ color: 'var(--ink)', fontSize: 12 }}>{r.id}</div>
              <div className="t-meta" style={{ marginTop: 2 }}>{r.city}</div>
            </div>
            <span className={`t-mono${r.risk === 'breach' ? '' : ''}`} style={{
              color: r.risk === 'breach' ? 'var(--danger)'
                   : r.risk === 'at'     ? 'var(--warn)' : 'var(--ink)',
              fontWeight: 600,
            }}>{r.margin} %</span>
          </div>
        ))}
      </div>
    </Card>,
    <Card key="health">
      <div className="t-eyebrow" style={{ marginBottom: 10 }}>Engine health</div>
      <div style={{ display: 'flex', flexDirection: 'column', gap: 10 }}>
        {[
          ['PRICE engine',      'green',           'var(--success)'],
          ['Market feed · gold', `${rates.find(r => r.id === 'r-24kg')?.updatedAt}`, 'var(--ink)'],
          ['Supplier feed · stones', `${rates.find(r => r.id === 'r-d-fsi')?.updatedAt}`, 'var(--ink)'],
          ['Ceiling policy',    'within floors', 'var(--success)'],
        ].map(([l, v, c]) => (
          <div key={l} style={{ display: 'flex', justifyContent: 'space-between', fontSize: 13 }}>
            <span className="t-meta">{l}</span>
            <span className="t-mono" style={{ color: c }}>{v}</span>
          </div>
        ))}
      </div>
    </Card>,
  ];

  return (
    <ModuleOverview
      pageHead={pageHead}
      kpis={kpis}
      primary={primaryNode}
      secondary={
        <>
          {cosignTeaser}
          {ratesSnapshot}
        </>
      }
      side={side}
      empty={cosignPending.length === 0 && draftQuotes.length === 0 ? (
        <Card>
          <EmptyState mark="P"
            title="Nothing waits on you."
            body="No co-signs in the queue and no draft quotes in flight. Refresh rates or open the queue."
            cta={<Btn size="sm" variant="primary" onClick={onRefreshRates}>Refresh rates</Btn>} />
        </Card>
      ) : null}
    />
  );
};


/* ============================================================
   COSIGN QUEUE PAGE · the cross-module bridge
   Template: ListTable
   ============================================================ */
const PriceCosignQueuePage = ({ items, onOpen, onApprove, onReject, onOpenCmdK }) => {
  const [tab, setTab] = useState('pending');

  const filtered = useMemo(() => {
    if (tab === 'pending')  return items.filter(i => i.status === 'pending');
    if (tab === 'cosigned') return items.filter(i => i.status === 'cosigned' || i.status === 'approved');
    if (tab === 'rejected') return items.filter(i => i.status === 'rejected');
    return items;
  }, [items, tab]);

  const counts = {
    pending:  items.filter(i => i.status === 'pending').length,
    cosigned: items.filter(i => i.status === 'cosigned' || i.status === 'approved').length,
    rejected: items.filter(i => i.status === 'rejected').length,
    all:      items.length,
  };

  return (
    <ListTable
      pageHead={
        <PageHead
          crumb={['PRICE', 'co-sign queue']}
          title="Pricing co-sign queue"
          subtitle="Cross-module items needing Pricing review. Source: IM reprice actions, HoM ceiling-change briefs, anything where the chain assigns Pricing as the next signer."
          actions={
            <>
              <Btn size="sm" onClick={onOpenCmdK} kbd="⌘K">Jump to…</Btn>
              <Btn size="sm" variant="primary" onClick={() => filtered[0] && onApprove?.(filtered[0].id)} kbd="⌘⏎"
                   disabled={!filtered.find(i => i.status === 'pending')}>
                Co-sign next
              </Btn>
            </>
          }
        />
      }
      tabs={
        <Tabs value={tab} onChange={setTab} mod="price" items={[
          { id: 'pending',  label: 'Pending',   count: counts.pending },
          { id: 'cosigned', label: 'Co-signed', count: counts.cosigned },
          { id: 'rejected', label: 'Rejected',  count: counts.rejected },
          { id: 'all',      label: 'All',       count: counts.all },
        ]} />
      }
      empty={filtered.length === 0 ? (
        <Card>
          <EmptyState mark="P"
            title={tab === 'pending' ? 'No co-signs waiting.' : `No ${tab} co-signs.`}
            body={tab === 'pending' ? 'When IM submits a reprice or HoM submits a ceiling change, it appears here.' : 'Switch tabs above.'} />
        </Card>
      ) : null}
      body={
        <div style={{ display: 'flex', flexDirection: 'column', gap: 12 }}>
          {filtered.map(item => (
            <CosignRow key={item.id} item={item}
                       onOpen={onOpen} onApprove={onApprove} onReject={onReject} />
          ))}
        </div>
      }
    />
  );
};


/* ============================================================
   COSIGN DETAIL PAGE · full review surface
   Template: DetailObject · reuses RunObject + EvidencePanel + ApprovalSurface
   ============================================================ */
const PriceCosignDetailPage = ({ item, onBack, onApprove, onReject, onRefine, onOpenFormula }) => {
  if (!item) {
    return (
      <DetailObject
        back={<button className="k-detail-back" onClick={onBack}>← Back to queue</button>}
        pageHead={<PageHead crumb={['PRICE', 'co-sign']} title="Co-sign request not found" />}
        main={[<Card key="x"><EmptyState mark="?" title="That request doesn't exist." body="It may have been co-signed, rejected, or returned to author."
                cta={<Btn size="sm" onClick={onBack}>Back</Btn>} /></Card>]}
        side={[]}
      />
    );
  }

  const breach = item.ceilingCheck === 'breach';

  return (
    <DetailObject
      back={<button className="k-detail-back" onClick={onBack}>← Back to queue</button>}
      pageHead={
        <PageHead
          crumb={['PRICE', 'co-sign', item.runId]}
          title={item.title}
          subtitle={item.reasoning}
          actions={
            <>
              <Btn size="sm" variant="ghost" onClick={() => onOpenFormula?.(item.id)}>View formula</Btn>
              <Btn size="sm" onClick={() => onRefine?.(item.id)}>Request revision</Btn>
              <Btn size="sm" variant="reject" onClick={() => onReject?.(item.id)}>Reject</Btn>
              <Btn size="sm" variant={breach ? 'reject' : 'primary'} onClick={() => onApprove?.(item.id)} kbd="⌘⏎">
                {breach ? 'Co-sign breach' : 'Co-sign'}
              </Btn>
            </>
          }
        />
      }
      statusRow={
        <>
          <VerificationStamp>{item.stamp}</VerificationStamp>
          <Chip variant="mute" dot>FROM {(item.sourceModule || '').toUpperCase()}</Chip>
          <Chip variant={item.type === 'reprice' ? 'warn' : 'info'} dot>{item.type === 'ceiling_change' ? 'CEILING CHANGE' : item.type.toUpperCase()}</Chip>
          {breach && <Chip variant="danger" dot>CEILING BREACH · 5.6 pp below floor</Chip>}
          <RunBadge id={item.runId} version={item.runVersion} when={item.runWhen} />
          <ConfidenceMeter level={item.confidence} label={item.confidenceLabel} mod="price" />
        </>
      }
      main={[
        <Card key="stats">
          <div className="t-eyebrow" style={{ marginBottom: 12 }}>Review summary</div>
          <div style={{ display: 'grid', gridTemplateColumns: 'repeat(4, 1fr)', gap: 16 }}>
            {item.stats.map((s, i) => (
              <div key={i} style={{ display: 'flex', flexDirection: 'column', gap: 4 }}>
                <span className="t-eyebrow" style={{ color: 'var(--mute)' }}>{s.label}</span>
                <span style={{ fontSize: 22, fontWeight: 600,
                              color: s.color === 'success' ? 'var(--success)'
                                   : s.color === 'danger'  ? 'var(--danger)' : 'var(--ink)',
                              fontVariantNumeric: 'tabular-nums', letterSpacing: '-0.01em' }}>{s.value}</span>
              </div>
            ))}
          </div>
        </Card>,
        <Card key="formula" style={{ background: breach ? 'var(--danger-soft)' : 'var(--success-soft)',
                                     borderColor: breach ? 'var(--danger-line)' : 'var(--success-line)' }}>
          <div className="t-eyebrow" style={{ marginBottom: 10, color: breach ? 'var(--danger)' : 'var(--success)' }}>
            {breach ? 'PRICE engine · ceiling check FAILED' : 'PRICE engine · deterministic math'}
          </div>
          <div style={{ display: 'flex', flexDirection: 'column', gap: 8, fontFamily: 'var(--font-mono)', fontSize: 12.5 }}>
            {item.math.map((m, i) => (
              <div key={i} style={{ display: 'flex', justifyContent: 'space-between',
                                    padding: '6px 0', borderTop: i ? '1px solid var(--line-2)' : 'none' }}>
                <span style={{ color: 'var(--ink-2)' }}>{m.expr}</span>
                <span style={{ color: 'var(--ink)', fontWeight: 600 }}>{m.value}</span>
              </div>
            ))}
          </div>
          <div className="t-meta" style={{ marginTop: 12, fontStyle: 'italic' }}>
            Architecture §8.4 — agent explains, PRICE engine calculates. The math above is deterministic and reproducible.
          </div>
        </Card>,
        <RunObject key="run"
          mod="price"
          runId={item.runId}
          status="pending"
          title={`${item.sourceModule}.${item.type} · ${item.runVersion}`}
          agent={`price_explain_agent · v2.1 (explained) · ${item.sourceModule}_action_agent (sourced)`}
          skillVersion="acme.price.skills @ 2026.05.18-3"
          memoryVersion="acme.memory @ 2026.05.20"
          startedAt={item.runWhen}
          cost="$0.014"
          latency="6.1 s"
          onOpenTrace={() => location.hash = `monitor/${item.runId}`}
        />,
        <WorkflowTimeline key="wf"
          title="Workflow · awaiting Pricing co-sign"
          actions={<Btn size="sm" variant="ghost" onClick={() => location.hash = `monitor/${item.runId}`}>Open in MONITOR ›</Btn>}
          steps={item.workflow}
        />,
      ]}
      side={[
        <EvidencePanel key="ev"
          runId={item.runId}
          claims={item.claims || []}
          receipts={item.receipts || []}
          math={item.math || []}
        />,
        <ApprovalSurface key="as"
          mod="price"
          runId={item.runId}
          title="Approval chain"
          chain={item.chain}
          onReject={() => onReject?.(item.id)}
          onApprove={() => onApprove?.(item.id)}
          primaryKbd="⌘⏎"
        />,
      ]}
      footer={
        <div className="k-detail-footer">
          <div className="k-detail-footer-left">
            <Icon name="check" />
            <span>
              {breach
                ? 'Ceiling breach · co-signing acknowledges policy override · CEO must still approve. Audited.'
                : 'Co-signing advances the chain to CEO. PRICE engine applies on CEO approval. Audited.'}
            </span>
          </div>
          <div className="k-detail-footer-right">
            <Btn variant="reject" onClick={() => onReject?.(item.id)} kbd="⌘⇧⏎">Reject</Btn>
            <Btn onClick={() => onRefine?.(item.id)}>Request revision</Btn>
            <Btn variant={breach ? 'reject' : 'primary'} onClick={() => onApprove?.(item.id)} kbd="⌘⏎">
              {breach ? 'Co-sign breach' : 'Co-sign'}
            </Btn>
          </div>
        </div>
      }
    />
  );
};


/* ============================================================
   RATES PAGE · metal + stone rate manager
   Template: ListTable
   ============================================================ */
const PriceRatesPage = ({ rates, onRefreshRates, onEditRate, onOpenCmdK }) => {
  const [tab, setTab] = useState('all');

  const filtered = useMemo(() => {
    if (tab === 'all')    return rates;
    if (tab === 'metals') return rates.filter(r => r.kind === 'metal');
    if (tab === 'stones') return rates.filter(r => r.kind === 'stone');
    return rates;
  }, [rates, tab]);

  return (
    <ListTable
      pageHead={
        <PageHead
          crumb={['PRICE', 'rates']}
          title="Metal & stone rates"
          subtitle="Current input rates that feed the PRICE engine. Metals refresh from market feed every 15 minutes; stones from supplier feed every 4 hours. Edit a rate to propose a ceiling adjustment (CEO sign required)."
          actions={
            <>
              <Btn size="sm" onClick={onOpenCmdK} kbd="⌘K">Jump to…</Btn>
              <Btn size="sm" variant="primary" onClick={onRefreshRates}>Refresh rates</Btn>
            </>
          }
        />
      }
      tabs={
        <Tabs value={tab} onChange={setTab} mod="price" items={[
          { id: 'all',    label: 'All',    count: rates.length },
          { id: 'metals', label: 'Metals', count: rates.filter(r => r.kind === 'metal').length },
          { id: 'stones', label: 'Stones', count: rates.filter(r => r.kind === 'stone').length },
        ]} />
      }
      body={
        <Card>
          <div style={{ display: 'grid', gridTemplateColumns: '1.3fr 1fr 0.8fr 1.2fr 0.8fr auto',
                        gap: 16, alignItems: 'center', padding: '8px 0' }}
               className="t-eyebrow">
            <span>Spec · source</span>
            <span>Rate</span>
            <span>Δ 24 h</span>
            <span>Updated</span>
            <span>Kind</span>
            <span></span>
          </div>
          {filtered.map(r => (
            <RateRow key={r.id} rate={r} onEditRate={onEditRate} editable />
          ))}
        </Card>
      }
    />
  );
};


/* ============================================================
   QUOTES PAGE
   ============================================================ */
const PriceQuotesPage = ({ quotes, onOpen, onCreateQuote, onOpenCmdK }) => {
  const [tab, setTab] = useState('all');

  const filtered = useMemo(() => {
    if (tab === 'draft')     return quotes.filter(q => q.status === 'draft' || q.status === 'pending');
    if (tab === 'submitted') return quotes.filter(q => q.status === 'submitted');
    if (tab === 'approved')  return quotes.filter(q => q.status === 'approved');
    return quotes;
  }, [quotes, tab]);

  const counts = {
    all:       quotes.length,
    draft:     quotes.filter(q => q.status === 'draft' || q.status === 'pending').length,
    submitted: quotes.filter(q => q.status === 'submitted').length,
    approved:  quotes.filter(q => q.status === 'approved').length,
  };

  return (
    <ListTable
      pageHead={
        <PageHead
          crumb={['PRICE', 'quotes']}
          title="Quote workspace"
          subtitle="Customer quotes drafted, submitted, and approved. Drafts under margin floor need CEO sign; drafts above can be approved by Pricing directly."
          actions={
            <>
              <Btn size="sm" onClick={onOpenCmdK} kbd="⌘K">Jump to…</Btn>
              <Btn size="sm" variant="primary" onClick={onCreateQuote}>Create quote</Btn>
            </>
          }
        />
      }
      tabs={
        <Tabs value={tab} onChange={setTab} mod="price" items={[
          { id: 'all',       label: 'All',       count: counts.all },
          { id: 'draft',     label: 'Draft',     count: counts.draft },
          { id: 'submitted', label: 'Submitted', count: counts.submitted },
          { id: 'approved',  label: 'Approved',  count: counts.approved },
        ]} />
      }
      empty={filtered.length === 0 ? (
        <Card>
          <EmptyState mark="P"
            title={tab === 'draft' ? 'No drafts.' : `No ${tab} quotes.`}
            body={tab === 'draft' ? 'Create a new quote to start.' : 'Switch tabs above.'}
            cta={tab === 'draft' ? <Btn size="sm" variant="primary" onClick={onCreateQuote}>Create quote</Btn> : null}
          />
        </Card>
      ) : null}
      body={
        <div style={{ display: 'flex', flexDirection: 'column', gap: 12 }}>
          {filtered.map(q => <QuoteRow key={q.id} quote={q} onOpen={onOpen} />)}
        </div>
      }
    />
  );
};


/* ============================================================
   QUOTE DETAIL PAGE · with View Formula drawer
   Template: DetailObject
   ============================================================ */
const PriceQuoteDetailPage = ({
  quote, onBack, onSimulate, onSubmit, onExport, onOpenFormula, onApprove,
}) => {
  if (!quote) {
    return (
      <DetailObject
        back={<button className="k-detail-back" onClick={onBack}>← Back to quotes</button>}
        pageHead={<PageHead crumb={['PRICE', 'quotes']} title="Quote not found" />}
        main={[<Card key="x"><EmptyState mark="?" title="That quote doesn't exist." body="It may have expired or been deleted."
                cta={<Btn size="sm" onClick={onBack}>Back</Btn>} /></Card>]}
        side={[]}
      />
    );
  }

  const breach = quote.ceilingCheck === 'breach';
  const isDraft = quote.status === 'draft' || quote.status === 'pending';
  const needsCeoSign = breach;

  return (
    <DetailObject
      back={<button className="k-detail-back" onClick={onBack}>← Back to quotes</button>}
      pageHead={
        <PageHead
          crumb={['PRICE', 'quotes', quote.id]}
          title={quote.customer}
          subtitle={`${quote.segment} · ${quote.skuCount} SKU${quote.skuCount === 1 ? '' : 's'} · ${quote.totalAmount.display} · valid for ${quote.validUntil}`}
          actions={
            <>
              <Btn size="sm" variant="ghost" onClick={() => onOpenFormula?.(quote.id)}>View formula</Btn>
              <Btn size="sm" onClick={() => onExport?.(quote.id)}>Export</Btn>
              {isDraft && (
                <Btn size="sm" onClick={() => onSimulate?.(quote.id)}>Simulate</Btn>
              )}
              {isDraft && !needsCeoSign && (
                <Btn size="sm" variant="primary" onClick={() => onApprove?.(quote.id)} kbd="⌘⏎">Approve quote</Btn>
              )}
              {isDraft && needsCeoSign && (
                <Btn size="sm" variant="primary" onClick={() => onSubmit?.(quote.id)} kbd="⌘⏎">Submit to CEO</Btn>
              )}
            </>
          }
        />
      }
      statusRow={
        <>
          <VerificationStamp>Verified · PRICE engine</VerificationStamp>
          <Chip variant={
            quote.status === 'approved' ? 'success' :
            quote.status === 'submitted' || quote.status === 'pending' ? 'warn' : 'mute'
          } dot>{quote.status.toUpperCase()}</Chip>
          {breach && <Chip variant="danger" dot>MARGIN BELOW FLOOR · CEO sign required</Chip>}
          <span className="t-mono" style={{ fontSize: 11, color: 'var(--mute)' }}>{quote.id}</span>
        </>
      }
      main={[
        <Card key="totals">
          <div className="t-eyebrow" style={{ marginBottom: 12 }}>Totals</div>
          <div style={{ display: 'grid', gridTemplateColumns: 'repeat(4, 1fr)', gap: 16 }}>
            <div>
              <span className="t-eyebrow" style={{ color: 'var(--mute)' }}>Quote total</span>
              <div style={{ fontSize: 22, fontWeight: 600, fontVariantNumeric: 'tabular-nums', marginTop: 4 }}>
                {quote.totalAmount.display}
              </div>
            </div>
            <div>
              <span className="t-eyebrow" style={{ color: 'var(--mute)' }}>Discount</span>
              <div style={{ fontSize: 22, fontWeight: 600, fontVariantNumeric: 'tabular-nums', marginTop: 4 }}>
                {quote.discountPercent} %
              </div>
            </div>
            <div>
              <span className="t-eyebrow" style={{ color: 'var(--mute)' }}>Weighted margin</span>
              <div style={{ fontSize: 22, fontWeight: 600, fontVariantNumeric: 'tabular-nums', marginTop: 4,
                            color: breach ? 'var(--danger)' : 'var(--success)' }}>
                {quote.margin} %
              </div>
            </div>
            <div>
              <span className="t-eyebrow" style={{ color: 'var(--mute)' }}>Margin floor</span>
              <div style={{ fontSize: 22, fontWeight: 600, fontVariantNumeric: 'tabular-nums', marginTop: 4 }}>
                {quote.marginFloor} %
              </div>
            </div>
          </div>
        </Card>,
        quote.items?.length > 0 && (
          <Card key="lines">
            <div className="t-eyebrow" style={{ marginBottom: 12 }}>Line items · {quote.items.length}</div>
            <div style={{ display: 'grid', gridTemplateColumns: '0.6fr 2fr 0.5fr 1fr 1fr 0.7fr',
                          gap: 16, padding: '8px 0' }} className="t-eyebrow">
              <span>SKU</span><span>Name</span><span>Qty</span><span>Listed</span><span>Final</span><span>Margin</span>
            </div>
            {quote.items.map((it, i) => (
              <div key={i} style={{ display: 'grid', gridTemplateColumns: '0.6fr 2fr 0.5fr 1fr 1fr 0.7fr',
                                    gap: 16, padding: '10px 0', borderTop: '1px solid var(--line-2)',
                                    fontSize: 13, alignItems: 'center' }}>
                <span className="t-mono" style={{ color: 'var(--accent)' }}>{it.sku}</span>
                <span style={{ color: 'var(--ink)' }}>{it.name}</span>
                <span>{it.qty}</span>
                <span className="t-mono" style={{ fontVariantNumeric: 'tabular-nums' }}>₹{(it.listed / 1000).toFixed(0)}K</span>
                <span className="t-mono" style={{ fontVariantNumeric: 'tabular-nums', color: 'var(--ink)', fontWeight: 600 }}>₹{(it.final / 1000).toFixed(0)}K</span>
                <span className="t-mono" style={{
                  fontVariantNumeric: 'tabular-nums',
                  color: it.margin < quote.marginFloor ? 'var(--danger)' : 'var(--success)',
                  fontWeight: 600,
                }}>{it.margin} %</span>
              </div>
            ))}
          </Card>
        ),
        <Card key="formula" style={{ background: 'var(--surface-2)' }}>
          <div className="t-eyebrow" style={{ marginBottom: 10 }}>Formula · deterministic</div>
          <div style={{ fontFamily: 'var(--font-mono)', fontSize: 12.5, color: 'var(--ink-2)',
                        background: 'var(--surface)', padding: 14, borderRadius: 8,
                        border: '1px solid var(--line-2)' }}>
            {quote.formula}
          </div>
          <div className="t-meta" style={{ marginTop: 10 }}>
            Architecture §8.4 — agent explains, PRICE engine calculates. This formula is reproducible and audited.
          </div>
        </Card>,
      ].filter(Boolean)}
      side={[
        <Card key="customer">
          <div className="t-eyebrow" style={{ marginBottom: 10 }}>Customer</div>
          <div style={{ display: 'flex', flexDirection: 'column', gap: 8, fontSize: 13 }}>
            <div style={{ display: 'flex', justifyContent: 'space-between' }}>
              <span className="t-meta">Name</span><span style={{ color: 'var(--ink)' }}>{quote.customer}</span>
            </div>
            <div style={{ display: 'flex', justifyContent: 'space-between' }}>
              <span className="t-meta">Segment</span><span style={{ color: 'var(--ink)' }}>{quote.segment}</span>
            </div>
            <div style={{ display: 'flex', justifyContent: 'space-between' }}>
              <span className="t-meta">Valid for</span><span className="t-mono">{quote.validUntil}</span>
            </div>
            {quote.sentAt && (
              <div style={{ display: 'flex', justifyContent: 'space-between' }}>
                <span className="t-meta">Sent</span><span className="t-mono">{quote.sentAt}</span>
              </div>
            )}
          </div>
        </Card>,
        <Card key="status">
          <div className="t-eyebrow" style={{ marginBottom: 10 }}>Status</div>
          <div style={{ display: 'flex', flexDirection: 'column', gap: 8, fontSize: 13 }}>
            <div style={{ display: 'flex', justifyContent: 'space-between' }}>
              <span className="t-meta">Ceiling check</span>
              <span style={{ color: breach ? 'var(--danger)' : 'var(--success)' }}>
                {breach ? 'BREACH' : 'PASS'}
              </span>
            </div>
            <div style={{ display: 'flex', justifyContent: 'space-between' }}>
              <span className="t-meta">Approval needed</span>
              <span style={{ color: 'var(--ink)' }}>{needsCeoSign ? 'CEO · breach override' : 'Pricing · direct'}</span>
            </div>
            <div style={{ display: 'flex', justifyContent: 'space-between' }}>
              <span className="t-meta">External writes</span>
              <span className="t-mono" style={{ color: 'var(--mute)' }}>none · quote document only</span>
            </div>
          </div>
        </Card>,
        <Card key="actions">
          <div className="t-eyebrow" style={{ marginBottom: 10 }}>Quote actions</div>
          <div style={{ display: 'flex', flexDirection: 'column', gap: 6 }}>
            {isDraft && <Btn size="sm" onClick={() => onSimulate?.(quote.id)}>Simulate with new params</Btn>}
            <Btn size="sm" onClick={() => onExport?.(quote.id)}>Export PDF</Btn>
            <Btn size="sm" onClick={() => onOpenFormula?.(quote.id)}>View formula</Btn>
          </div>
        </Card>,
      ]}
    />
  );
};


/* ============================================================
   MARGIN RISK PAGE
   ============================================================ */
const PriceMarginRiskPage = ({ items, onOpenSku, onOpenCmdK, onForwardToVault }) => {
  const breaches = items.filter(r => r.risk === 'breach');
  const atFloor  = items.filter(r => r.risk === 'at');
  const low      = items.filter(r => r.risk === 'low');

  return (
    <ListTable
      pageHead={
        <PageHead
          crumb={['PRICE', 'margin risk']}
          title={`Margin floor · ${items.length} SKU${items.length === 1 ? '' : 's'} on watch`}
          subtitle={`${breaches.length} breaching · ${atFloor.length} exactly at floor · ${low.length} low risk. Forward to VAULT for IM to draft a reprice-up.`}
          actions={<Btn size="sm" onClick={onOpenCmdK} kbd="⌘K">Jump to…</Btn>}
        />
      }
      body={
        <Card>
          <div style={{ display: 'grid', gridTemplateColumns: '1fr 2fr 1fr 1fr 1fr 0.8fr auto',
                        gap: 16, padding: '8px 0', alignItems: 'center' }}
               className="t-eyebrow">
            <span>SKU</span><span>Name</span><span>City</span><span>Margin</span><span>Floor</span><span>Risk · days</span><span></span>
          </div>
          {items.map(r => (
            <div key={r.id} style={{ display: 'grid', gridTemplateColumns: '1fr 2fr 1fr 1fr 1fr 0.8fr auto',
                                     gap: 16, padding: '12px 0', borderTop: '1px solid var(--line-2)',
                                     alignItems: 'center', fontSize: 13 }}>
              <span className="t-mono" style={{ color: 'var(--accent)', cursor: 'pointer' }} onClick={() => onOpenSku?.(r.id)}>{r.id}</span>
              <span style={{ color: 'var(--ink)' }}>{r.name}</span>
              <span>{r.city}</span>
              <span className="t-mono" style={{
                fontVariantNumeric: 'tabular-nums', fontWeight: 600,
                color: r.risk === 'breach' ? 'var(--danger)' :
                       r.risk === 'at'     ? 'var(--warn)' : 'var(--ink)',
              }}>{r.margin} %</span>
              <span className="t-mono" style={{ color: 'var(--mute)' }}>{r.floor} %</span>
              <span>
                <Chip variant={r.risk === 'breach' ? 'danger' : r.risk === 'at' ? 'warn' : 'mute'} dot>
                  {r.risk}
                </Chip>
                <span className="t-meta" style={{ marginLeft: 6 }}>· {r.daysAtRisk} d</span>
              </span>
              <Btn size="sm" variant="ghost" onClick={() => onForwardToVault?.(r.id)}>
                Forward to VAULT
              </Btn>
            </div>
          ))}
        </Card>
      }
    />
  );
};


/* ============================================================
   SKU DETAIL PAGE · lighter · linked from margin risk + quotes
   ============================================================ */
const PriceSkuDetailPage = ({ skuId, onBack }) => {
  // For Wave E we render a lightweight SKU 360 from id only · production would
  // fetch from /api/price/skus/:id with full cost breakdown.
  return (
    <DetailObject
      back={<button className="k-detail-back" onClick={onBack}>← Back</button>}
      pageHead={<PageHead crumb={['PRICE', 'skus', skuId]} title={`SKU pricing · ${skuId}`}
                          subtitle="Cost breakdown, margin computation, and reprice simulator." />}
      statusRow={
        <>
          <VerificationStamp>Verified · PRICE engine</VerificationStamp>
          <Chip variant="mute" dot>READ-ONLY</Chip>
          <span className="t-mono" style={{ fontSize: 11, color: 'var(--mute)' }}>{skuId}</span>
        </>
      }
      main={[
        <Card key="cost">
          <div className="t-eyebrow" style={{ marginBottom: 12 }}>Cost breakdown · current pricing</div>
          <div style={{ display: 'flex', flexDirection: 'column', gap: 10, fontSize: 13 }}>
            {[
              ['Metal cost · 18K WG (4.2 g)',  '₹24,702',  'var(--ink)'],
              ['Stone cost · F·SI 0.7 ct',     '₹2,94,000', 'var(--ink)'],
              ['Making + finishing',           '₹38,000',  'var(--ink)'],
              ['Cost · subtotal',              '₹3,56,702', 'var(--ink)'],
              ['Listed price',                 '₹5,80,000', 'var(--ink)'],
              ['Weighted margin',              '38.5 %',    'var(--success)'],
              ['Margin floor (policy)',        '32 %',      'var(--mute)'],
            ].map(([l, v, c]) => (
              <div key={l} style={{ display: 'flex', justifyContent: 'space-between',
                                    padding: '6px 0', borderTop: '1px solid var(--line-2)' }}>
                <span className="t-meta">{l}</span>
                <span className="t-mono" style={{ color: c, fontWeight: 600, fontVariantNumeric: 'tabular-nums' }}>{v}</span>
              </div>
            ))}
          </div>
        </Card>,
        <Card key="formula" style={{ background: 'var(--surface-2)' }}>
          <div className="t-eyebrow" style={{ marginBottom: 10 }}>Formula</div>
          <div style={{ fontFamily: 'var(--font-mono)', fontSize: 12.5, color: 'var(--ink-2)',
                        background: 'var(--surface)', padding: 14, borderRadius: 8,
                        border: '1px solid var(--line-2)', lineHeight: 1.65 }}>
            metal_cost = weight × rate(material){'\n'}
            stone_cost = Σ(carat × rate(quality)){'\n'}
            cost = metal_cost + stone_cost + making + finishing{'\n'}
            margin = (price − cost) / price{'\n'}
            policy_check = margin {'>'}= floor (32 %)
          </div>
        </Card>,
      ]}
      side={[
        <Card key="reprice">
          <div className="t-eyebrow" style={{ marginBottom: 10 }}>Reprice simulator</div>
          <p className="t-body-sm" style={{ marginTop: 0, color: 'var(--mute)' }}>
            Simulate the effect of a discount on weighted margin. Will not commit anything; route through
            VAULT or a quote draft to apply.
          </p>
          <div style={{ display: 'flex', flexDirection: 'column', gap: 8, marginTop: 12 }}>
            <Btn size="sm" disabled>Simulate − 5 %</Btn>
            <Btn size="sm" disabled>Simulate − 8 %</Btn>
            <Btn size="sm" disabled>Simulate − 12 %</Btn>
            <div className="t-meta" style={{ marginTop: 6 }}>
              · Wave F enhancement · live simulator with margin preview
            </div>
          </div>
        </Card>,
      ]}
    />
  );
};


Object.assign(window.K, {
  PriceOverviewPage, PriceCosignQueuePage, PriceCosignDetailPage,
  PriceRatesPage, PriceQuotesPage, PriceQuoteDetailPage,
  PriceMarginRiskPage, PriceSkuDetailPage,
  RateRow, CosignRow, QuoteRow,
});
