// Suptech Hub — modern fintech dashboard.
// Three sections only: Markets → Brief → Dispatches. Click a card to drill in.
const { useState, useMemo } = React;

// ─────────────────────────────── Helpers ───────────────────────────────
function fmtNum(n) {
  if (n == null || isNaN(n)) return "—";
  if (Math.abs(n) >= 1000) return n.toLocaleString("en-US", { maximumFractionDigits: 1 });
  if (Math.abs(n) >= 100)  return n.toFixed(1);
  return n.toFixed(2);
}
function fmtChg(n, suffix = "%") {
  if (n == null || isNaN(n)) return "—";
  return (n >= 0 ? "+" : "") + n.toFixed(2) + suffix;
}
function chgClass(n) {
  if (n == null || isNaN(n)) return "is-flat";
  return n > 0 ? "is-up" : n < 0 ? "is-down" : "is-flat";
}
function chgArrow(n) {
  if (n == null || isNaN(n) || n === 0) return "";
  return n > 0 ? "▲" : "▼";
}
function asOfText(iso) {
  if (!iso) return "";
  const d = new Date(iso);
  return d.toLocaleString("en-GB", {
    day: "2-digit", month: "short", hour: "2-digit", minute: "2-digit", timeZone: "UTC",
  }) + " UTC";
}
function dispatchTime(iso) {
  return new Date(iso).toLocaleString("en-GB", {
    day: "2-digit", month: "short", hour: "2-digit", minute: "2-digit",
  });
}

// ─────────────────────────────── Brand mark ────────────────────────────
// Simplified flat version of the SuptechHub logo: rising bars + connector.
function BrandMark({ className = "brand-mark" }) {
  return (
    <svg className={className} viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg" aria-hidden="true">
      <rect x="3"  y="11" width="3" height="8"  rx="0.5" fill="currentColor" />
      <rect x="8"  y="7"  width="3" height="12" rx="0.5" fill="currentColor" />
      <rect x="13" y="3"  width="3" height="16" rx="0.5" fill="currentColor" />
      <path
        d="M2.5 21.5 Q 7 18.5, 11.5 21.5 T 20.5 21.5"
        fill="none"
        stroke="currentColor"
        strokeWidth="1.6"
        strokeLinecap="round"
      />
      <circle cx="17" cy="21.5" r="1.4" fill="currentColor" />
    </svg>
  );
}

// ─────────────────────────────── Topbar ───────────────────────────────
function Topbar({ asOf }) {
  return (
    <header className="topbar">
      <div className="container topbar-inner">
        <div className="brand">
          <BrandMark />
          <div className="brand-name">Suptech<span> Hub</span></div>
        </div>
        <div className="last-updated" title={asOf ? new Date(asOf).toUTCString() : ""}>
          <span className="live-dot" />
          {asOf ? `Updated ${asOfText(asOf)}` : "Awaiting refresh"}
        </div>
      </div>
    </header>
  );
}

// ─────────────────────────────── Markets ───────────────────────────────
function Sparkline({ chg }) {
  // Deterministic mini-shape based on direction. Real history would be nicer; the
  // backend currently only emits `last` + `chg`, so this is a visual cue, not a chart.
  const up = (chg ?? 0) >= 0;
  const pts = up
    ? "0,9 5,8 10,6 15,7 20,5 25,4 30,3 35,2 40,1"
    : "0,1 5,2 10,3 15,2 20,4 25,5 30,7 35,8 40,9";
  return (
    <svg width="56" height="14" viewBox="0 0 40 12" className="tile-spark" aria-hidden="true">
      <polyline fill="none" stroke="currentColor" strokeWidth="1.4" points={pts} />
    </svg>
  );
}

const MARKET_PICKS = [
  // Curated, high-signal subset. Pulled from MARKETS by symbol name.
  { bucket: "indices",     sym: "S&P 500",        label: "S&P 500" },
  { bucket: "indices",     sym: "Nasdaq 100",     label: "Nasdaq 100" },
  { bucket: "indices",     sym: "Hang Seng",      label: "Hang Seng" },
  { bucket: "indices",     sym: "Nikkei 225",     label: "Nikkei 225" },
  { bucket: "rates",       sym: "US 10Y",         label: "US 10Y" },
  { bucket: "fx",          sym: "USD Index (DXY)",label: "DXY" },
  { bucket: "commodities", sym: "Gold",           label: "Gold" },
  { bucket: "crypto",      sym: "BTC",            label: "BTC" },
];

function pickMarket(markets, bucket, sym) {
  return (markets[bucket] || []).find(x => x.sym === sym);
}

function MarketsSection({ markets }) {
  const tiles = MARKET_PICKS
    .map(p => ({ ...p, q: pickMarket(markets, p.bucket, p.sym) }))
    .filter(p => p.q);

  return (
    <section className="section" id="markets">
      <div className="section-head">
        <div className="section-head__title">
          <span className="eyebrow">Markets</span>
          <h2 className="section-title">At the open</h2>
        </div>
        <span className="section-meta">{markets.asOf ? asOfText(markets.asOf) : ""}</span>
      </div>
      <div className="markets-grid">
        {tiles.map(({ q, label }) => {
          const cls = chgClass(q.chg);
          return (
            <div key={label} className="tile">
              <div className="tile-label">{label}</div>
              <div className="tile-value">{fmtNum(q.last)}</div>
              <div className="tile-foot">
                <span className={"tile-chg " + cls}>{chgArrow(q.chg)} {fmtChg(q.chg)}</span>
                <span className={cls}><Sparkline chg={q.chg} /></span>
              </div>
            </div>
          );
        })}
      </div>
    </section>
  );
}

// ─────────────────────────────── Brief ───────────────────────────────
function BriefSection({ brief, regulators, onOpen, feedById }) {
  if (!brief || !brief.length) return null;
  return (
    <section className="section" id="brief">
      <div className="section-head">
        <div className="section-head__title">
          <span className="eyebrow">Today's brief</span>
          <h2 className="section-title">Three things to know</h2>
        </div>
      </div>
      <div className="brief">
        <ol className="brief-list">
          {brief.map((b) => {
            const r = regulators[b.reg] || { name: b.reg, full: b.reg, region: "—" };
            const item = feedById[b.id];
            return (
              <li key={b.id} className="brief-item">
                <span className="brief-num" aria-hidden="true" />
                <div>
                  <div className="brief-tag">
                    {r.name}
                    <span className="brief-tag-region">· {r.region}</span>
                  </div>
                  <div className="brief-text">
                    {item ? (
                      <button
                        type="button"
                        className="brief-text-link"
                        onClick={() => onOpen(item)}
                      >
                        {b.title}
                      </button>
                    ) : b.title}
                  </div>
                </div>
              </li>
            );
          })}
        </ol>
      </div>
    </section>
  );
}

// ─────────────────────────────── Dispatches ───────────────────────────────
const TYPE_LABEL = {
  consultation: "Consultation",
  rule:         "Final rule",
  guidance:     "Guidance",
  speech:       "Speech",
  enforcement:  "Enforcement",
  report:       "Report",
  data:         "Data",
  news:         "News",
};

function DispatchCard({ item, onOpen, regulators }) {
  const r = regulators[item.reg] || { name: item.reg, full: item.reg, region: "—" };
  const typeLabel = TYPE_LABEL[item.type] || "News";
  return (
    <button type="button" className="card" onClick={() => onOpen(item)}>
      <div className="card-meta">
        <span className="pill pill-region">{r.region}</span>
        <span className="pill pill-type">{typeLabel}</span>
        {item.impact === "high" && <span className="pill pill-impact-high">High impact</span>}
      </div>
      <h3 className="card-title">{item.title}</h3>
      <p className="card-summary">{item.summary}</p>
      <div className="card-foot">
        <span className="card-source">{r.name}</span>
        <span>{dispatchTime(item.timeISO)}</span>
      </div>
    </button>
  );
}

function DispatchesSection({ feed, regulators, onOpen, limit = 18 }) {
  const sorted = useMemo(() => {
    return feed.slice().sort((a, b) => b.timeISO.localeCompare(a.timeISO));
  }, [feed]);
  const visible = sorted.slice(0, limit);

  return (
    <section className="section" id="dispatches">
      <div className="section-head">
        <div className="section-head__title">
          <span className="eyebrow">Regulators</span>
          <h2 className="section-title">Latest dispatches</h2>
        </div>
        <span className="section-meta">{feed.length} in feed</span>
      </div>
      {visible.length === 0 ? (
        <div className="empty">No dispatches in the feed yet.</div>
      ) : (
        <div className="dispatch-grid">
          {visible.map(item => (
            <DispatchCard
              key={item.id}
              item={item}
              regulators={regulators}
              onOpen={onOpen}
            />
          ))}
        </div>
      )}
    </section>
  );
}

// ─────────────────────────────── Drawer ───────────────────────────────
function Drawer({ item, onClose, regulators }) {
  if (!item) return null;
  const r = regulators[item.reg] || { name: item.reg, full: item.reg, region: "—" };
  const typeLabel = TYPE_LABEL[item.type] || "News";
  return (
    <div className="drawer-scrim" onClick={onClose}>
      <aside className="drawer" onClick={(e) => e.stopPropagation()}>
        <button className="drawer-close" onClick={onClose}>← Close</button>
        <div className="drawer-meta">
          <span className="pill pill-region">{r.region}</span>
          <span className="pill pill-type">{typeLabel}</span>
          {item.impact === "high" && <span className="pill pill-impact-high">High impact</span>}
        </div>
        <h2 className="drawer-title">{item.title}</h2>
        <p className="drawer-summary">{item.summary}</p>

        <ul className="drawer-kv">
          <li><span>Regulator</span><span>{r.full}</span></li>
          <li><span>Published</span><span>{dispatchTime(item.timeISO)}</span></li>
          {item.deadline && (
            <li><span>Deadline</span><span>{new Date(item.deadline).toLocaleDateString("en-GB", { day: "2-digit", month: "short", year: "numeric" })}</span></li>
          )}
          <li><span>Region</span><span>{r.region}</span></li>
          {item.topic && item.topic.length > 0 && (
            <li><span>Topics</span><span>{item.topic.join(", ")}</span></li>
          )}
        </ul>

        {item.link
          ? <a className="drawer-link" href={item.link} target="_blank" rel="noopener noreferrer">Open source ↗</a>
          : <span className="drawer-link" aria-disabled="true">No source link</span>
        }
      </aside>
    </div>
  );
}

// ─────────────────────────────── Footer ───────────────────────────────
function Footer({ asOf }) {
  return (
    <footer className="footer">
      <div className="container footer-inner">
        <div className="footer-brand">
          <BrandMark className="brand-mark" />
          <span><b>Suptech Hub</b> · Finance · Supervision · Technology</span>
          <span className="footer-tag">Public beta</span>
        </div>
        <div>
          {asOf ? `Last refresh ${asOfText(asOf)}` : "—"} · © {new Date().getFullYear()}
        </div>
      </div>
    </footer>
  );
}

// ─────────────────────────────── Export to window ───────────────────────────────
Object.assign(window, {
  Topbar,
  MarketsSection,
  BriefSection,
  DispatchesSection,
  Drawer,
  Footer,
});
