// admin/pages/system.jsx — audit, health, segments, fulfilment, automation stubs

function AuditPage() {
  const [q, setQ] = React.useState('');
  const rows = OwnerAudit.list({ q });
  return (
    <div>
      <div className="mode-banner">Owner audit log (local). Server ERP audit service: missing.</div>
      <div className="spread" style={{ marginBottom: 12 }}>
        <h2 className="serif" style={{ fontSize: '1.4rem' }}>Audit Log</h2>
        <input className="inp" style={{ maxWidth: 260 }} placeholder="Search…" value={q} onChange={(e) => setQ(e.target.value)} />
      </div>
      {rows.length === 0 ? (
        <Empty icon="eye" title="No audit entries yet" note="Stock adjusts, order status changes, product edits, and import approvals appear here." />
      ) : (
        <div className="card table-scroll">
          <table className="tbl">
            <thead><tr><th>When</th><th>Actor</th><th>Action</th><th>Entity</th><th>Result</th><th>Detail</th></tr></thead>
            <tbody>
              {rows.slice(0, 200).map((r) => (
                <tr key={r.id}>
                  <td style={{ whiteSpace: 'nowrap' }}>{new Date(r.at).toLocaleString('en-IN')}</td>
                  <td>{r.actor}</td>
                  <td><code>{r.action}</code></td>
                  <td>{r.entityType} {r.entityId}</td>
                  <td>{r.result}</td>
                  <td className="muted">{r.detail}</td>
                </tr>
              ))}
            </tbody>
          </table>
        </div>
      )}
    </div>
  );
}

function HealthPage() {
  const remote = !!(window.APG_CONFIG && window.APG_CONFIG.useRemote);
  const ready = !!(window.APG && window.APG.isReady && window.APG.isReady());
  let storageOk = true;
  try {
    localStorage.setItem('apg.health.ping', '1');
    localStorage.removeItem('apg.health.ping');
  } catch {
    storageOk = false;
  }
  const caps = window.OwnerCaps;
  const teamCap = caps && caps.getCap ? caps.getCap('team') : null;
  const mtCap = caps && caps.getCap ? caps.getCap('multiTenant') : null;
  const erpOk = !!(window.ErpCore && window.ErpCore.ROLE_PERMISSIONS);
  const tenantOk = !!(window.RinadsTenant && window.RinadsTenant.bootstrap);
  const rbacReady = erpOk && tenantOk;
  const teamStatus = (teamCap && teamCap.status) || (rbacReady ? 'partial' : 'blocked');
  const mtStatus = (mtCap && mtCap.status) || (erpOk ? 'live' : 'blocked');
  const teamDetail =
    (teamCap && teamCap.via) ||
    (rbacReady
      ? 'memberships + ROLE_PERMISSIONS local; invite email provider blocked'
      : 'RBAC host not loaded');
  const mtDetail =
    (mtCap && mtCap.via) ||
    '@rinads/erp-core + local tenant registry / memberships';

  function statusLabel(status, ok) {
    if (status === 'partial') return 'Partial';
    if (status === 'blocked' || !ok) return 'Missing';
    return 'OK / noted';
  }
  function statusClass(status, ok) {
    if (status === 'partial') return 'b-low';
    if (status === 'blocked' || !ok) return 'b-out';
    return 'b-in';
  }

  const rows = [
    { name: 'Admin data layer (APG)', ok: !!window.APG, detail: ready ? 'ready' : 'initializing' },
    { name: 'Remote Supabase mode', ok: true, detail: remote ? 'enabled' : 'localStorage mode (default)' },
    { name: 'Browser storage', ok: storageOk, detail: storageOk ? 'writable' : 'blocked' },
    { name: 'RINADS Runtime', ok: !!(window.OwnerRuntime && window.OwnerRuntime.get()), detail: 'localStorage job/event queue' },
    { name: 'RINADS Intelligence', ok: !!(window.OwnerIntelligence && window.OwnerIntelligence.get()), detail: '@rinads/intelligence memory + analytics' },
    {
      name: 'Multi-tenant ERP services',
      ok: mtStatus !== 'blocked',
      status: mtStatus,
      detail: mtDetail,
    },
    {
      name: 'RBAC / team invites',
      ok: teamStatus !== 'blocked',
      status: teamStatus,
      detail: teamDetail,
    },
    { name: 'Canonical media/import packages', ok: true, detail: 'Node package under canonical/ (not browser runtime)' }
  ];
  return (
    <div>
      <div className="mode-banner">System health shows measurable client signals only — no fake uptime.</div>
      <h2 className="serif" style={{ fontSize: '1.4rem', marginBottom: 12 }}>System Health</h2>
      <div className="card">
        <table className="tbl">
          <thead><tr><th>Signal</th><th>Status</th><th>Detail</th></tr></thead>
          <tbody>
            {rows.map((r) => (
              <tr key={r.name}>
                <td>{r.name}</td>
                <td><span className={'badge ' + statusClass(r.status, r.ok)}>{statusLabel(r.status, r.ok)}</span></td>
                <td className="muted">{r.detail}</td>
              </tr>
            ))}
          </tbody>
        </table>
      </div>
    </div>
  );
}

function SegmentsPage() {
  const seg = (window.OwnerIntelligence && window.OwnerIntelligence.customerSegments)
    ? window.OwnerIntelligence.customerSegments()
    : OwnerMetrics.customerSegments();
  const blocks = [
    ['New Customers', seg.newCustomers],
    ['Repeat Customers', seg.repeatCustomers],
    ['High Value (≥ ₹2000)', seg.highValue],
    ['Inactive (60d+)', seg.inactive],
    ['Recent Buyers (14d)', seg.recentBuyers]
  ];
  return (
    <div>
      <div className="mode-banner">Rule-based segments from orders. Creating a segment does <b>not</b> send marketing.</div>
      <h2 className="serif" style={{ fontSize: '1.4rem', marginBottom: 12 }}>CRM Segments</h2>
      <p className="muted" style={{ marginBottom: 16 }}>{seg.source}</p>
      <div className="kpi-grid">
        {blocks.map(([title, rows]) => (
          <div className="card card-pad" key={title}>
            <div className="section-title">{title}</div>
            <div className="kpi__value" style={{ fontSize: '1.8rem' }}>{rows.length}</div>
            <ul className="muted" style={{ fontSize: '.78rem', marginTop: 8, paddingLeft: 16 }}>
              {rows.slice(0, 5).map((r) => (
                <li key={r.key}>{(r.name || '').trim() || r.key} · {money(r.spent)}</li>
              ))}
            </ul>
          </div>
        ))}
      </div>
    </div>
  );
}

function FulfilmentPage({ go }) {
  const admin = useAdmin();
  const orders = admin.getOrders().filter((o) => ['new', 'packed', 'shipped', 'out_for_delivery', 'returned'].includes(o.status));
  return (
    <div>
      <div className="mode-banner">Fulfilment uses order status + optional shipment helper. Full returns/refunds domain: partial/blocked.</div>
      <div className="spread" style={{ marginBottom: 12 }}>
        <h2 className="serif" style={{ fontSize: '1.4rem' }}>Fulfilment</h2>
        <button className="btn btn-soft btn-sm" onClick={() => go('orders')}>All orders</button>
      </div>
      <div className="card table-scroll">
        <table className="tbl">
          <thead><tr><th>Order</th><th>Customer</th><th>Status</th><th>Courier</th><th>AWB</th><th className="num">Total</th></tr></thead>
          <tbody>
            {orders.map((o) => (
              <tr key={o.id} style={{ cursor: 'pointer' }} onClick={() => go('orders', { orderId: o.id })}>
                <td><b>{o.id}</b></td>
                <td>{(o.details.firstName || '') + ' ' + (o.details.lastName || '')}</td>
                <td><StatusBadge status={o.status} /></td>
                <td>{o.courier || '—'}</td>
                <td>{o.awb || '—'}</td>
                <td className="num">{money(o.total)}</td>
              </tr>
            ))}
          </tbody>
        </table>
        {!orders.length && <Empty icon="truck" title="No open fulfilment" note="New and in-transit orders appear here." />}
      </div>
      <div className="card card-pad" style={{ marginTop: 16 }}>
        <div className="section-title">Returns / Refunds</div>
        <p className="muted">Returns: filterable via order status <code>returned</code> only. Refunds: <b>blocked</b> until financial domain services exist. OwnerOps.refundBlocked().</p>
      </div>
    </div>
  );
}

function RuleBuilderFoundation({ onSaved }) {
  const [name, setName] = React.useState('');
  const [when, setWhen] = React.useState('order.created.v1');
  const [thenType, setThenType] = React.useState('create_task');
  const [msg, setMsg] = React.useState('');
  const [err, setErr] = React.useState('');
  const save = (e) => {
    e.preventDefault();
    setErr('');
    setMsg('');
    try {
      if (!OwnerOps.saveDraftRule) throw new Error('Draft builder unavailable');
      const rule = OwnerOps.saveDraftRule({ name: name || undefined, when, thenType });
      setMsg('Saved draft ' + (rule && rule.id) + ' (disabled until Activate on Rules tab)');
      if (onSaved) onSaved();
    } catch (ex) {
      setErr(ex.message || String(ex));
    }
  };
  return (
    <div className="card card-pad">
      <div className="section-title">WHEN / IF / THEN foundation</div>
      <p className="muted">Structured draft only — no arbitrary code. Full visual no-code builder remains blocked until Runtime 2.0 is stable in production.</p>
      <form onSubmit={save} style={{ display: 'grid', gap: 10, maxWidth: 480, marginTop: 12 }}>
        <label>Name<input className="inp" value={name} onChange={(e) => setName(e.target.value)} placeholder="Optional draft name" /></label>
        <label>WHEN (event)
          <select className="sel" value={when} onChange={(e) => setWhen(e.target.value)}>
            <option value="order.created.v1">order.created.v1</option>
            <option value="order.delivered.v1">order.delivered.v1</option>
            <option value="inventory.low.v1">inventory.low.v1</option>
            <option value="payment.failed.v1">payment.failed.v1</option>
            <option value="import.needs_review.v1">import.needs_review.v1</option>
          </select>
        </label>
        <label>IF<p className="muted" style={{ margin: 0 }}>always (structured DSL — advanced IF editor deferred)</p></label>
        <label>THEN (allowlisted action)
          <select className="sel" value={thenType} onChange={(e) => setThenType(e.target.value)}>
            <option value="create_task">create_task</option>
            <option value="create_restock_task">create_restock_task</option>
            <option value="notify_owner">notify_owner</option>
            <option value="create_notification">create_notification</option>
            <option value="log_only">log_only</option>
            <option value="analytics.record">analytics.record</option>
          </select>
        </label>
        <button className="btn btn-primary" type="submit">Save draft</button>
      </form>
      {msg && <p className="muted" style={{ marginTop: 10 }}>{msg}</p>}
      {err && <p style={{ color: 'var(--a-red)', marginTop: 10 }}>{err}</p>}
    </div>
  );
}

function AutomationPage() {
  const cap = OwnerCaps.getCap('automation');
  const [tab, setTab] = React.useState('dashboard');
  const [traceQ, setTraceQ] = React.useState('');
  const [traceOut, setTraceOut] = React.useState([]);
  const [simRule, setSimRule] = React.useState(null);
  const [simResult, setSimResult] = React.useState(null);
  const [, tick] = React.useReducer((x) => x + 1, 0);

  const rules = OwnerOps.listAutomationRules ? OwnerOps.listAutomationRules() : [];
  const jobs = OwnerOps.listRuntimeJobs ? OwnerOps.listRuntimeJobs() : [];
  const tasks = OwnerOps.listOpsTasks ? OwnerOps.listOpsTasks('open') : [];
  const metrics = OwnerOps.runtimeMetrics ? OwnerOps.runtimeMetrics() : { total: 0, failed: 0, deadLetter: 0 };

  const jobCounts = jobs.reduce(function (acc, j) {
    acc[j.status] = (acc[j.status] || 0) + 1;
    return acc;
  }, {});

  function runTrace(e) {
    e && e.preventDefault();
    setTraceOut(OwnerOps.traceRuntime(traceQ));
  }

  function doSimulate(ruleId) {
    setSimRule(ruleId);
    setSimResult(OwnerOps.simulateRule(ruleId));
  }

  return (
    <div>
      <div className="mode-banner">Automation: <b>{cap.status}</b> — {cap.via || cap.reason}. Jobs drain on mutation + admin session (no persistent worker on static deploy).</div>
      <div className="spread" style={{ marginBottom: 12 }}>
        <h2 className="serif" style={{ fontSize: '1.4rem' }}>Automation Center</h2>
        <button className="btn btn-soft btn-sm" type="button" onClick={() => { OwnerRuntime.bootstrapTick(); tick(); }}>Refresh / drain queue</button>
      </div>

      <div className="tabs" style={{ marginBottom: 12 }}>
        {['dashboard', 'jobs', 'rules', 'builder', 'workflows', 'tasks', 'events', 'approvals', 'trace'].map((t) => (
          <button key={t} type="button" className={'btn btn-sm ' + (tab === t ? 'btn-primary' : 'btn-soft')} onClick={() => setTab(t)}>{t}</button>
        ))}
      </div>

      {tab === 'dashboard' && (
        <div className="grid-2">
          <div className="card card-pad">
            <div className="section-title">Job health</div>
            <p>Queued: {jobCounts.queued || 0} · Running: {jobCounts.running || 0} · Failed: {jobCounts.failed || 0} · Dead letter: {jobCounts.dead_letter || 0}</p>
            <p className="muted">Success rate: {Math.round((metrics.successRate || 0) * 100)}% ({metrics.completed || 0}/{metrics.total || 0})</p>
          </div>
          <div className="card card-pad">
            <div className="section-title">Open tasks</div>
            <p>{tasks.length} automation-generated tasks awaiting action.</p>
          </div>
        </div>
      )}

      {tab === 'jobs' && (
        <div className="card table-scroll">
          <table className="tbl">
            <thead><tr><th>ID</th><th>Type</th><th>Status</th><th>Attempts</th><th>Error</th><th></th></tr></thead>
            <tbody>
              {jobs.slice(0, 100).map((j) => (
                <tr key={j.id}>
                  <td><code>{j.id.slice(0, 16)}</code></td>
                  <td>{j.jobType}</td>
                  <td>{j.status}</td>
                  <td>{j.attempts}/{j.maxAttempts}</td>
                  <td className="muted">{j.lastError || '—'}</td>
                  <td>{(j.status === 'failed' || j.status === 'dead_letter') && (
                    <button className="btn btn-soft btn-sm" type="button" onClick={() => { OwnerOps.replayJob(j.id); tick(); }}>Replay</button>
                  )}</td>
                </tr>
              ))}
            </tbody>
          </table>
          {!jobs.length && <Empty icon="gear" title="No jobs yet" note="Events from orders, inventory, and imports enqueue jobs here." />}
        </div>
      )}

      {tab === 'rules' && (
        <div>
          {rules.map((r) => {
            const ver = (r.versions || []).find((v) => v.version === r.currentVersion) || r.versions[0];
            return (
              <div key={r.id} className="card card-pad" style={{ marginBottom: 10 }}>
                <div className="spread">
                  <b>{r.name}</b>
                  <span className="muted">{r.status} · v{r.currentVersion}</span>
                </div>
                <p className="muted" style={{ margin: '8px 0' }}>
                  WHEN <code>{ver && ver.when}</code> THEN {(ver && ver.thenActions || []).map((a) => a.type).join(', ')}
                </p>
                <div className="spread">
                  <button className="btn btn-soft btn-sm" type="button" onClick={() => { OwnerOps.toggleRule(r.id, !r.enabled); tick(); }}>
                    {r.enabled ? 'Pause' : 'Activate'}
                  </button>
                  <button className="btn btn-soft btn-sm" type="button" onClick={() => doSimulate(r.id)}>Simulate (dry-run)</button>
                </div>
              </div>
            );
          })}
          {simResult && <div className="card card-pad"><b>Simulation {simRule}</b><p>Matched: {simResult.matched}, skipped: {simResult.skipped}, actions: {simResult.actions.join(', ') || 'none'}</p></div>}
          {!rules.length && <Empty icon="gear" title="No rules" note="MVP rules seed on first runtime load." />}
        </div>
      )}

      {tab === 'builder' && (
        <RuleBuilderFoundation onSaved={() => tick()} />
      )}

      {tab === 'workflows' && (
        <div>
          {(OwnerOps.listWorkflows ? OwnerOps.listWorkflows() : []).map(function (w) {
            return (
              <div key={w.id} className="card card-pad" style={{ marginBottom: 10 }}>
                <div className="spread"><b>{w.name}</b><span className="muted">{w.status} · v{w.currentVersion}</span></div>
                <p className="muted">{(w.versions && w.versions[0] && w.versions[0].steps || []).length} steps · trigger {(w.versions && w.versions[0] && w.versions[0].trigger) || '—'}</p>
              </div>
            );
          })}
          {(OwnerOps.listWorkflowExecutions ? OwnerOps.listWorkflowExecutions() : []).slice(0, 20).map(function (ex) {
            return (
              <div key={ex.id} className="card card-pad" style={{ marginBottom: 8 }}>
                <code>{ex.id.slice(0, 18)}</code> · {ex.status} · {ex.workflowId}
              </div>
            );
          })}
        </div>
      )}

      {tab === 'events' && (
        <div className="card table-scroll">
          <table className="tbl">
            <thead><tr><th>Type</th><th>Aggregate</th><th>Correlation</th><th>When</th></tr></thead>
            <tbody>
              {(OwnerOps.listRuntimeEvents ? OwnerOps.listRuntimeEvents({ limit: 100 }) : []).map(function (ev) {
                return (
                  <tr key={ev.id}>
                    <td><code>{ev.eventType}</code></td>
                    <td>{ev.aggregateType}:{ev.aggregateId}</td>
                    <td className="muted"><code>{(ev.correlationId || '').slice(0, 20)}</code></td>
                    <td className="muted">{ev.createdAt && ev.createdAt.slice(0, 19)}</td>
                  </tr>
                );
              })}
            </tbody>
          </table>
        </div>
      )}

      {tab === 'approvals' && (
        <div className="card table-scroll">
          <table className="tbl">
            <thead><tr><th>Action</th><th>Status</th><th>Requester</th><th></th></tr></thead>
            <tbody>
              {(OwnerOps.listApprovals ? OwnerOps.listApprovals('pending') : []).map(function (a) {
                return (
                  <tr key={a.id}>
                    <td>{a.actionType}</td>
                    <td>{a.status}</td>
                    <td className="muted">{a.requesterId}</td>
                    <td>
                      <button className="btn btn-soft btn-sm" type="button" onClick={() => { OwnerOps.resolveApproval(a.id, true); tick(); }}>Approve</button>
                      {' '}
                      <button className="btn btn-soft btn-sm" type="button" onClick={() => { OwnerOps.resolveApproval(a.id, false); tick(); }}>Reject</button>
                    </td>
                  </tr>
                );
              })}
            </tbody>
          </table>
        </div>
      )}

      {tab === 'tasks' && (
        <div className="card table-scroll">
          <table className="tbl">
            <thead><tr><th>Title</th><th>Priority</th><th>Source</th><th>Status</th><th></th></tr></thead>
            <tbody>
              {(OwnerOps.listOpsTasks() || []).slice(0, 100).map((t) => (
                <tr key={t.id}>
                  <td>{t.title}</td>
                  <td>{t.priority}</td>
                  <td>{t.source}</td>
                  <td>{t.status}</td>
                  <td>{t.status === 'open' && <button className="btn btn-soft btn-sm" type="button" onClick={() => { OwnerOps.updateOpsTaskStatus(t.id, 'completed'); tick(); }}>Complete</button>}</td>
                </tr>
              ))}
            </tbody>
          </table>
        </div>
      )}

      {tab === 'trace' && (
        <div>
          <form className="card card-pad" onSubmit={runTrace} style={{ marginBottom: 12 }}>
            <input className="inp" placeholder="Order ID, job ID, correlation ID…" value={traceQ} onChange={(e) => setTraceQ(e.target.value)} />
            <button className="btn btn-primary btn-sm" type="submit" style={{ marginTop: 8 }}>Trace</button>
          </form>
          {traceOut.map((t) => (
            <div key={t.correlationId} className="card card-pad" style={{ marginBottom: 8 }}>
              <code>{t.correlationId}</code>
              <ul>{(t.nodes || []).map((n, i) => (
                <li key={i}>{n.at} · {n.kind} · {n.label} {n.status ? '(' + n.status + ')' : ''} {n.error ? '— ' + n.error : ''}</li>
              ))}</ul>
            </div>
          ))}
        </div>
      )}
    </div>
  );
}

function IntegrityPage({ go }) {
  const intel = window.OwnerIntelligence;
  const report = intel && intel.dataIntegrity ? intel.dataIntegrity() : { issues: [], summary: { critical: 0, warning: 0, info: 0 } };
  const dups = intel && intel.duplicates ? intel.duplicates() : [];
  const grouped = {
    critical: report.issues.filter((i) => i.severity === 'critical'),
    warning: report.issues.filter((i) => i.severity === 'warning'),
    info: report.issues.filter((i) => i.severity === 'info'),
  };

  return (
    <div>
      <div className="mode-banner">Data Integrity Center — deterministic reconciliation. Duplicate candidates require manual review; no auto-merge.</div>
      <div className="spread" style={{ marginBottom: 12 }}>
        <h2 className="serif" style={{ fontSize: '1.4rem' }}>Data Integrity</h2>
        <button className="btn btn-soft btn-sm" onClick={() => go('products')}>Catalog</button>
      </div>
      <div className="kpi-grid" style={{ marginBottom: 16 }}>
        <div className="kpi"><div className="kpi__label">Critical</div><div className="kpi__value">{report.summary.critical}</div></div>
        <div className="kpi"><div className="kpi__label">Warnings</div><div className="kpi__value">{report.summary.warning}</div></div>
        <div className="kpi"><div className="kpi__label">Info</div><div className="kpi__value">{report.summary.info}</div></div>
        <div className="kpi"><div className="kpi__label">Duplicate pairs</div><div className="kpi__value">{dups.length}</div></div>
      </div>
      {['critical', 'warning', 'info'].map((sev) => (
        grouped[sev].length > 0 && (
          <div className="card card-pad" key={sev} style={{ marginBottom: 12 }}>
            <div className="section-title">{sev.charAt(0).toUpperCase() + sev.slice(1)}</div>
            <ul className="action-list">
              {grouped[sev].slice(0, 30).map((issue, i) => (
                <li key={i}>
                  <code>{issue.kind}</code> — {issue.message}
                  {issue.entityId && <span className="muted"> ({issue.entityType} {issue.entityId})</span>}
                </li>
              ))}
            </ul>
          </div>
        )
      ))}
      {dups.length > 0 && (
        <div className="card card-pad">
          <div className="section-title">Duplicate candidates</div>
          <ul className="action-list">
            {dups.map((d, i) => (
              <li key={i}>{d.sourceRecordA} ↔ {d.sourceRecordB} — {Math.round(d.confidence * 100)}% ({d.signals.join(', ')})</li>
            ))}
          </ul>
        </div>
      )}
      {!report.issues.length && !dups.length && (
        <Empty icon="alert" title="No integrity issues detected" note="Reconciliation checks customer totals, duplicate names, and catalog completeness from current data." />
      )}
    </div>
  );
}

function loadReviewsStore() {
  try {
    const raw = localStorage.getItem('hap.reviews.v1');
    return raw ? JSON.parse(raw) : [];
  } catch (_) {
    return [];
  }
}

function saveReviewsStore(rows) {
  try {
    localStorage.setItem('hap.reviews.v1', JSON.stringify(rows.slice(0, 500)));
  } catch (_) {}
}

function ReviewsModerationPage() {
  const [, tick] = React.useReducer((x) => x + 1, 0);
  const all = loadReviewsStore();
  const pending = all.filter((r) => r.status === 'pending');
  const recent = all.filter((r) => r.status !== 'pending').slice(0, 40);

  function setStatus(id, status) {
    const rows = loadReviewsStore().map((r) => (r.id === id ? { ...r, status, moderatedAt: Date.now() } : r));
    saveReviewsStore(rows);
    tick();
  }

  return (
    <div>
      <div className="mode-banner">Reviews moderation — localStorage <code>hap.reviews.v1</code>. Only delivered purchases may submit; pending rows need approve/reject.</div>
      <h2 className="serif" style={{ fontSize: '1.4rem', marginBottom: 12 }}>Reviews moderation</h2>
      <div className="card table-scroll" style={{ marginBottom: 16 }}>
        <table className="tbl">
          <thead><tr><th>When</th><th>Product</th><th>Customer</th><th>Rating</th><th>Review</th><th></th></tr></thead>
          <tbody>
            {pending.map((r) => (
              <tr key={r.id}>
                <td style={{ whiteSpace: 'nowrap' }}>{r.createdAt ? new Date(r.createdAt).toLocaleString('en-IN') : '—'}</td>
                <td><code>{r.productId}</code></td>
                <td>{r.name || r.email}<br /><span className="muted" style={{ fontSize: '.72rem' }}>{r.email}</span></td>
                <td>{r.rating}/5</td>
                <td>
                  {r.title && <b>{r.title}</b>}
                  <div className="muted" style={{ fontSize: '.82rem' }}>{r.content}</div>
                </td>
                <td>
                  <div className="row" style={{ gap: 6, justifyContent: 'flex-end' }}>
                    <button className="btn btn-primary btn-sm" type="button" onClick={() => setStatus(r.id, 'published')}>Approve</button>
                    <button className="btn btn-soft btn-sm" type="button" onClick={() => setStatus(r.id, 'rejected')}>Reject</button>
                  </div>
                </td>
              </tr>
            ))}
          </tbody>
        </table>
        {!pending.length && <Empty icon="star" title="No pending reviews" note="Customer submissions with status pending appear here." />}
      </div>
      {recent.length > 0 && (
        <div className="card card-pad">
          <div className="section-title">Recently moderated</div>
          <ul className="action-list">
            {recent.map((r) => (
              <li key={r.id}><code>{r.status}</code> · {r.productId} · {r.rating}/5 — {(r.title || r.content || '').slice(0, 80)}</li>
            ))}
          </ul>
        </div>
      )}
    </div>
  );
}

function SupportInboxPage() {
  const [, tick] = React.useReducer((x) => x + 1, 0);
  const commerce = window.AmbadyCommerce;
  const tickets = commerce && typeof commerce.listTickets === 'function'
    ? commerce.listTickets()
    : (commerce && commerce.get && commerce.get() && commerce.get().listTickets
      ? commerce.get().listTickets()
      : []);

  function applyStatus(id, status) {
    if (commerce && typeof commerce.setTicketStatus === 'function') {
      return commerce.setTicketStatus(id, status);
    }
    if (commerce && commerce.get) {
      const c = commerce.get();
      if (c && c.setTicketStatus) return c.setTicketStatus(id, status);
    }
    return null;
  }

  function setStatus(id, status, current) {
    try {
      // open → resolved is not a legal direct transition; step through in_progress.
      if (status === 'resolved' && current === 'open') {
        applyStatus(id, 'in_progress');
      }
      applyStatus(id, status);
      tick();
    } catch (err) {
      alert((err && err.message) || 'Could not update ticket status');
    }
  }

  return (
    <div>
      <div className="mode-banner">Support inbox — AmbadyCommerce tickets (localStorage). Status transitions enforced by commerce core.</div>
      <h2 className="serif" style={{ fontSize: '1.4rem', marginBottom: 12 }}>Support inbox</h2>
      {!commerce && (
        <Empty icon="chat" title="Commerce core unavailable" note="Load js/commerce.iife.js + commerce-bridge to manage tickets." />
      )}
      {commerce && (
        <div className="card table-scroll">
          <table className="tbl">
            <thead><tr><th>Ticket</th><th>Customer</th><th>Subject</th><th>Priority</th><th>Status</th><th></th></tr></thead>
            <tbody>
              {(tickets || []).map((t) => (
                <tr key={t.id}>
                  <td><code>{t.id}</code><br /><span className="muted" style={{ fontSize: '.72rem' }}>{t.category}</span></td>
                  <td>{t.customerName}<br /><span className="muted" style={{ fontSize: '.72rem' }}>{t.customerEmail || t.customerKey}</span></td>
                  <td>
                    <b>{t.subject}</b>
                    <div className="muted" style={{ fontSize: '.78rem' }}>
                      {((t.messages || [])[t.messages.length - 1] || {}).body || ''}
                    </div>
                  </td>
                  <td>{t.priority}</td>
                  <td>{t.status}</td>
                  <td>
                    <div className="row" style={{ gap: 6, justifyContent: 'flex-end' }}>
                      {t.status !== 'in_progress' && t.status !== 'resolved' && t.status !== 'closed' && (
                        <button className="btn btn-soft btn-sm" type="button" onClick={() => setStatus(t.id, 'in_progress', t.status)}>In progress</button>
                      )}
                      {t.status !== 'resolved' && t.status !== 'closed' && (
                        <button className="btn btn-primary btn-sm" type="button" onClick={() => setStatus(t.id, 'resolved', t.status)}>Resolve</button>
                      )}
                    </div>
                  </td>
                </tr>
              ))}
            </tbody>
          </table>
          {!(tickets || []).length && <Empty icon="chat" title="No support tickets" note="Customer openTicket submissions appear here." />}
        </div>
      )}
    </div>
  );
}

window.AuditPage = AuditPage;
window.HealthPage = HealthPage;
window.IntegrityPage = IntegrityPage;
window.SegmentsPage = SegmentsPage;
window.FulfilmentPage = FulfilmentPage;
window.AutomationPage = AutomationPage;
window.ReviewsModerationPage = ReviewsModerationPage;
window.SupportInboxPage = SupportInboxPage;

function MemoryExplorerPage() {
  const intel = window.OwnerIntelligence;
  const memories = intel && intel.listMemories ? intel.listMemories() : [];
  const grouped = {};
  memories.forEach(function (m) {
    var cat = m.category || m.scope || 'other';
    if (!grouped[cat]) grouped[cat] = [];
    grouped[cat].push(m);
  });
  return (
    <div>
      <div className="mode-banner">What RINPO remembers — source, confidence, and trust level shown. Inferred memories are never presented as verified facts.</div>
      <h2 className="serif" style={{ fontSize: '1.4rem', marginBottom: 12 }}>Memory Explorer</h2>
      {!memories.length && <Empty icon="star" title="No memories yet" note="Explicit preferences and runtime observations appear here." />}
      {Object.keys(grouped).map(function (cat) {
        return (
          <div className="card card-pad" key={cat} style={{ marginBottom: 12 }}>
            <div className="section-title">{cat}</div>
            <ul className="action-list">
              {grouped[cat].map(function (m) {
                return (
                  <li key={m.id}>
                    <span className="badge b-new">{m.trustLevel || m.inferenceMode}</span> {m.content}
                    <span className="muted" style={{ fontSize: '.75rem' }}> · {m.source} · {Math.round((m.confidence || 0) * 100)}%</span>
                  </li>
                );
              })}
            </ul>
          </div>
        );
      })}
    </div>
  );
}

function GraphExplorerPage() {
  const intel = window.OwnerIntelligence;
  const [productId, setProductId] = React.useState('');
  const [graph, setGraph] = React.useState(null);
  const products = (window.HAP && window.HAP.PRODUCTS) || [];
  const run = function () {
    if (!intel || !intel.traverseGraph || !productId) return;
    setGraph(intel.traverseGraph('product', productId));
  };
  return (
    <div>
      <div className="mode-banner">Relationship graph from order history — search, expand, inspect source trace.</div>
      <h2 className="serif" style={{ fontSize: '1.4rem', marginBottom: 12 }}>Memory Graph</h2>
      <div className="card card-pad" style={{ marginBottom: 12 }}>
        <label className="field"><span>Product</span>
          <select className="inp" value={productId} onChange={(e) => setProductId(e.target.value)}>
            <option value="">Select product</option>
            {products.slice(0, 100).map((p) => <option key={p.id} value={p.id}>{p.name}</option>)}
          </select>
        </label>
        <button className="btn btn-primary btn-sm" type="button" onClick={run} style={{ marginTop: 8 }}>Traverse</button>
      </div>
      {graph && (
        <div className="card card-pad">
          <div className="section-title">Path from {graph.root.type}:{graph.root.id}</div>
          <ul className="action-list">
            {graph.path.map(function (p, i) { return <li key={i}>{p}</li>; })}
          </ul>
          <div className="muted" style={{ fontSize: '.8rem', marginTop: 8 }}>{graph.edges.length} relationship(s)</div>
        </div>
      )}
    </div>
  );
}

function DataQualityPage() {
  const intel = window.OwnerIntelligence;
  const scores = intel && intel.qualityScores ? intel.qualityScores() : null;
  if (!scores) return <Empty icon="layers" title="Intelligence unavailable" note="Load intelligence bundle." />;
  return (
    <div>
      <div className="mode-banner">Data quality scores — critical issues require review before Runtime action.</div>
      <h2 className="serif" style={{ fontSize: '1.4rem', marginBottom: 12 }}>Data Quality Center</h2>
      <div className="kpi-grid" style={{ marginBottom: 16 }}>
        {[['Catalog', scores.catalog], ['Customer', scores.customer], ['Inventory', scores.inventory], ['Operational', scores.operational], ['Overall', scores.overall]].map(function (row) {
          return (
            <div className="card card-pad" key={row[0]}>
              <div className="section-title">{row[0]}</div>
              <div className="kpi__value">{row[1]}</div>
            </div>
          );
        })}
      </div>
      <div className="card card-pad">
        <div className="section-title">Issues</div>
        {!scores.issues.length && <p className="muted">No critical or warning issues detected.</p>}
        <ul className="action-list">
          {scores.issues.slice(0, 30).map(function (issue, i) {
            return <li key={i}><span className={'badge ' + (issue.severity === 'critical' ? 'b-danger' : 'b-warn')}>{issue.severity}</span> [{issue.domain}] {issue.message}</li>;
          })}
        </ul>
      </div>
    </div>
  );
}

window.MemoryExplorerPage = MemoryExplorerPage;
window.GraphExplorerPage = GraphExplorerPage;
window.DataQualityPage = DataQualityPage;
