// Per-City Carrier Scorecard — the paid product surface.
//
// One carrier, one metro. The deliverable shippers, brokers, and carriers
// pay for. Renders in two modes:
//
//   1. LA-seeded mode: real scored carrier data from LA_REPORT — full
//      scorecard with metric bars, peer rank, verdict, all the goods.
//   2. Provisional mode (every other metro): live operator-network signal
//      filtered by carrier + city. No fake scores. Honest framing,
//      subscribe-CTA upsell to the full Pulse.

const { useState: useStateSC, useEffect: useEffectSC, useMemo: useMemoSC } = React;

function PerCityScorecard({ carrierSlug, cityId, onNav, onCarrier }) {
  const cities = (window.SI_DATA && window.SI_DATA.ALL_CITIES) || [];
  const cityMeta = cities.find(c => c.id === cityId) || { id: cityId, name: cityId, state: "" };

  // LA scorecard is the only seeded full-data city.
  const isLA = cityId === "los-angeles";
  const LA_REPORT = window.SI_DATA && window.SI_DATA.LA_REPORT;
  const METRICS   = (window.SI_DATA && window.SI_DATA.METRICS) || [];

  // Find the carrier inside LA_REPORT (only valid in LA mode).
  let laCarrier = null, laCatId = null;
  if (isLA && LA_REPORT) {
    for (const cat of Object.keys(LA_REPORT.carriers || {})) {
      const found = LA_REPORT.carriers[cat].find(c => c.id === carrierSlug);
      if (found) { laCarrier = found; laCatId = cat; break; }
    }
  }

  // Carrier display name — fall back gracefully when the carrier isn't in
  // the LA seed (e.g. a smaller TL like Covenant in Chicago).
  const [carrierName, setCarrierName] = useStateSC(
    laCarrier ? laCarrier.name :
    carrierSlug.split("-").map(w => w[0].toUpperCase() + w.slice(1)).join(" ")
  );

  // Live data
  const [signals, setSignals] = useStateSC([]);
  const [loadingSignals, setLoadingSignals] = useStateSC(true);

  useEffectSC(() => {
    let alive = true;
    async function load() {
      if (!window.SI_DB || !window.SI_DB.raw) { setLoadingSignals(false); return; }
      try {
        // Operator-network signals tagged to this carrier in this city.
        const data = await window.SI_DB.raw.select(
          "intel_submissions",
          `select=id,parsed_carrier,parsed_intel_type,severity,raw_text,created_at,source_url,notes`
          + `&parsed_carrier=eq.${encodeURIComponent(carrierSlug)}`
          + `&city_id=eq.${encodeURIComponent(cityId)}`
          + `&status=eq.verified&visibility=eq.public`
          + `&order=created_at.desc&limit=100`
        );
        if (!alive) return;
        setSignals(Array.isArray(data) ? data : []);

        // If we still don't have a friendly carrier name, look it up.
        if (!laCarrier) {
          const ent = await window.SI_DB.raw.select(
            "entities",
            `select=name&type=eq.carrier&slug=eq.${encodeURIComponent(carrierSlug)}&limit=1`
          );
          if (alive && Array.isArray(ent) && ent[0] && ent[0].name) {
            setCarrierName(ent[0].name);
          }
        }
      } catch (e) {
        console.warn("[scorecard] load failed", e);
      } finally {
        if (alive) setLoadingSignals(false);
      }
    }
    load();
    return () => { alive = false; };
  }, [carrierSlug, cityId]);

  const now = Date.now();
  const day = 24 * 3600 * 1000;
  const within30d = signals.filter(r => now - new Date(r.created_at).getTime() < 30 * day);
  const sev = (r) => r.severity || "low";
  const high30d = within30d.filter(r => sev(r) === "high" || sev(r) === "critical").length;

  const byType = {};
  within30d.forEach(r => {
    const t = r.parsed_intel_type || "other";
    byType[t] = (byType[t] || 0) + 1;
  });
  const topTypes = Object.entries(byType).sort((a,b)=>b[1]-a[1]).slice(0, 5);

  function fmtDate(s) {
    const d = new Date(s);
    const days = Math.round((now - d.getTime()) / day);
    if (days === 0) return "today";
    if (days === 1) return "yesterday";
    if (days < 7)   return `${days}d ago`;
    return d.toLocaleDateString("en-US", { month: "short", day: "numeric" });
  }
  function prettyType(t) { return t.replace(/_/g, " "); }

  // Peer rank within the metro (LA mode only — uses seeded scores).
  const peers = (isLA && laCarrier && LA_REPORT)
    ? (LA_REPORT.carriers[laCatId] || []).slice().sort((a,b)=>b.score-a.score)
    : [];
  const rank = peers.findIndex(p => p.id === carrierSlug);

  return (
    <div className="page-scorecard">
      <style>{`
        .sc-hero { background: linear-gradient(180deg, #fff 0%, oklch(0.98 0.005 250) 100%);
          border-bottom: 1px solid var(--rule); padding: 56px 24px 40px; }
        .sc-hero-inner { max-width: 1100px; margin: 0 auto; }
        .sc-paid-band { display:inline-flex; align-items:center; gap:8px; padding:6px 12px;
          background: oklch(0.94 0.04 80); color: oklch(0.40 0.10 80);
          border-radius: 999px; font-family:var(--font-mono); font-size:10px;
          letter-spacing:0.16em; text-transform:uppercase; margin-bottom: 18px; font-weight: 600; }
        .sc-paid-band .dot { width:6px; height:6px; border-radius:50%; background:oklch(0.55 0.18 80); }
        .sc-title { font-family: var(--font-serif); font-size: 48px; line-height: 1.05;
          letter-spacing: -0.025em; margin: 0 0 8px; }
        .sc-title em { font-style: italic; color: var(--red, oklch(0.50 0.16 250)); }
        .sc-subline { color: var(--ink-soft); font-size: 16px; margin: 0 0 24px; }

        .sc-hero-grid { display:grid; grid-template-columns:1.4fr 1fr; gap:48px;
          align-items:start; margin-top:32px; }
        @media (max-width:880px) { .sc-hero-grid { grid-template-columns:1fr; gap:32px; } }
        .sc-verdict { font-family: var(--font-serif); font-size: 22px; line-height: 1.4;
          font-style: italic; color: var(--ink); border-left: 3px solid var(--red, oklch(0.50 0.16 250));
          padding: 4px 0 4px 20px; margin: 0 0 24px; }

        .sc-score-card { background:#fff; border:1px solid var(--rule); border-radius:10px;
          padding:24px; text-align:center; }
        .sc-score-num { font-family:var(--font-serif); font-size:72px; line-height:1;
          letter-spacing:-0.03em; margin: 8px 0 4px; }
        .sc-score-grade { font-family:var(--font-mono); font-size:11px; letter-spacing:0.16em;
          text-transform:uppercase; color:var(--ink-soft); }
        .sc-score-meta { color:var(--ink-soft); font-size:13px; margin-top:14px; }
        .sc-score-prov { font-family:var(--font-serif); font-size:34px; letter-spacing:-0.02em;
          color:var(--ink-soft); }

        .sc-stats { display:grid; grid-template-columns:repeat(4,1fr); gap:14px;
          max-width:1100px; margin:32px auto; padding:0 24px; }
        @media (max-width:760px) { .sc-stats { grid-template-columns:repeat(2,1fr); } }
        .sc-stat { background:#fff; border:1px solid var(--rule); border-radius:8px; padding:18px; }
        .sc-stat-num { font-family:var(--font-serif); font-size:30px; letter-spacing:-0.02em; line-height:1.05; }
        .sc-stat-label { font-family:var(--font-mono); font-size:10px; letter-spacing:0.15em;
          text-transform:uppercase; color:var(--ink-soft); margin-top:6px; }

        .sc-section { max-width:1100px; margin:48px auto; padding:0 24px; }
        .sc-section-h { font-family:var(--font-mono); font-size:12px; letter-spacing:0.18em;
          text-transform:uppercase; color:var(--ink-soft); padding-bottom:14px;
          border-bottom:1px solid var(--rule); margin-bottom:24px; }

        .sc-feed { display:flex; flex-direction:column; gap:12px; }
        .sc-row { background:#fff; border:1px solid var(--rule); border-radius:6px;
          padding:14px 16px; }
        .sc-row-meta { display:flex; gap:10px; font-family:var(--font-mono); font-size:10px;
          letter-spacing:0.14em; text-transform:uppercase; color:var(--ink-soft);
          margin-bottom:6px; align-items:center; }
        .sc-pill { display:inline-block; padding:2px 8px; border-radius:4px; font-weight:600; }
        .sc-pill.critical { background:oklch(0.92 0.1 25);  color:oklch(0.35 0.18 25); }
        .sc-pill.high     { background:oklch(0.93 0.08 50); color:oklch(0.35 0.16 50); }
        .sc-pill.moderate { background:oklch(0.93 0.05 80); color:oklch(0.40 0.10 80); }
        .sc-pill.low      { background:oklch(0.95 0.02 250); color:var(--ink-soft); }
        .sc-row-text { font-size:15px; line-height:1.5; color:var(--ink); margin:0; }

        .sc-list { list-style:none; padding:0; margin:0; }
        .sc-list li { display:flex; justify-content:space-between; padding:12px 0;
          border-bottom:1px solid var(--rule); font-size:15px; }
        .sc-list li:last-child { border-bottom:none; }
        .sc-list .count { font-family:var(--font-mono); color:var(--ink-soft); font-size:13px; }

        .sc-locked { background:linear-gradient(180deg, oklch(0.97 0.005 250) 0%, oklch(0.94 0.01 250) 100%);
          border:1px solid var(--rule); border-radius:10px; padding:32px; text-align:center;
          margin: 32px 0; position:relative; overflow:hidden; }
        .sc-locked::before { content:""; position:absolute; top:0; left:0; right:0; height:3px;
          background:linear-gradient(90deg, oklch(0.55 0.18 250), oklch(0.55 0.18 145)); }
        .sc-locked-h { font-family:var(--font-mono); font-size:11px; letter-spacing:0.18em;
          text-transform:uppercase; color:var(--ink-soft); margin-bottom:8px; }
        .sc-locked-title { font-family:var(--font-serif); font-size:24px; letter-spacing:-0.02em;
          margin:0 0 12px; }
        .sc-locked-body { color:var(--ink-soft); font-size:15px; line-height:1.55; max-width:560px;
          margin:0 auto 20px; }

        .sc-cta-row { display:flex; gap:12px; justify-content:center; flex-wrap:wrap; }
      `}</style>

      <section className="sc-hero">
        <div className="sc-hero-inner">
          <div className="report-breadcrumb" style={{ marginBottom: 12 }}>
            <a href="#" onClick={(e) => { e.preventDefault(); onNav("home"); }}>Home</a>
            <span>/</span>
            <a href="#" onClick={(e) => { e.preventDefault(); onCarrier(carrierSlug); }}>{carrierName}</a>
            <span>/</span>
            <span className="current">{cityMeta.name}, {cityMeta.state}</span>
          </div>

          <div className="sc-paid-band">
            <span className="dot" />
            {isLA && laCarrier ? "Q1 2026 Carrier Scorecard" : "Provisional Pulse · Operator-network signal"}
          </div>

          <h1 className="sc-title">
            <em>{carrierName}</em> in {cityMeta.name}.
          </h1>
          {isLA && laCarrier ? (
            <p className="sc-subline">
              {laCarrier.shipments} shipments analyzed · {laCarrier.complaints} complaints filed · Q1 2026 reporting period
            </p>
          ) : (
            <p className="sc-subline">
              {within30d.length} operator signals · last 30 days · published intel only
            </p>
          )}

          <div className="sc-hero-grid">
            <div>
              {isLA && laCarrier ? (
                <p className="sc-verdict">"{laCarrier.verdict}"</p>
              ) : (
                <p className="sc-verdict">
                  Provisional read for {carrierName} in {cityMeta.name}. The full carrier
                  scorecard publishes once we have enough field-validated lanes here.
                  In the meantime, this page surfaces every published operator signal
                  tagged to {carrierName} in this metro.
                </p>
              )}
              {rank >= 0 && peers.length > 1 && (
                <p style={{ color: "var(--ink-soft)", fontSize: 14, margin: "12px 0 0" }}>
                  Ranks <strong>#{rank + 1}</strong> of {peers.length} in {cityMeta.name} ·
                  {" "}{laCatId === "small" ? "Small Package" : laCatId === "ltl" ? "LTL Freight"
                    : laCatId === "ftl" ? "Truckload (FTL)" : laCatId === "courier" ? "Courier" : "International"}
                </p>
              )}
            </div>
            <div className="sc-score-card">
              {isLA && laCarrier ? (
                <>
                  <div className="sc-score-grade">Score · 0–100</div>
                  <div className="sc-score-num">{laCarrier.score}</div>
                  <div className="sc-score-grade">{window.SI_DATA && window.SI_DATA.scoreToLetter ? window.SI_DATA.scoreToLetter(laCarrier.score) : ""}</div>
                  <div className="sc-score-meta">
                    Trend {laCarrier.trend > 0 ? "↑" : laCarrier.trend < 0 ? "↓" : "→"} QoQ
                  </div>
                </>
              ) : (
                <>
                  <div className="sc-score-grade">Score</div>
                  <div className="sc-score-prov">Provisional</div>
                  <div className="sc-score-meta">Pulse-tier signal only</div>
                </>
              )}
            </div>
          </div>
        </div>
      </section>

      {/* Stats strip */}
      <div className="sc-stats">
        <div className="sc-stat">
          <div className="sc-stat-num">{loadingSignals ? "…" : within30d.length}</div>
          <div className="sc-stat-label">Signals · 30d</div>
        </div>
        <div className="sc-stat">
          <div className="sc-stat-num" style={{ color: high30d > 0 ? "oklch(0.55 0.18 25)" : "var(--ink)" }}>
            {loadingSignals ? "…" : high30d}
          </div>
          <div className="sc-stat-label">High + critical</div>
        </div>
        <div className="sc-stat">
          <div className="sc-stat-num">{loadingSignals ? "…" : Object.keys(byType).length}</div>
          <div className="sc-stat-label">Distinct issue types</div>
        </div>
        <div className="sc-stat">
          <div className="sc-stat-num">{isLA && laCarrier ? laCarrier.complaints : "—"}</div>
          <div className="sc-stat-label">Complaints filed</div>
        </div>
      </div>

      {/* Metric breakdown — LA mode only (real seeded data) */}
      {isLA && laCarrier && (
        <section className="sc-section">
          <div className="sc-section-h">Metric breakdown · {cityMeta.name}</div>
          <div className="carrier-metrics-grid">
            {METRICS.map((m, i) => (
              <window.MetricBar key={m.id} label={m.label} score={laCarrier.scores[m.id]} delay={i * 60} />
            ))}
          </div>
        </section>
      )}

      {/* Live signal feed */}
      <section className="sc-section">
        <div className="sc-section-h">
          {carrierName} · {cityMeta.name} · operator-network signal
        </div>
        {loadingSignals ? (
          <p style={{ textAlign: "center", color: "var(--ink-soft)", padding: "40px 0" }}>Loading…</p>
        ) : within30d.length === 0 ? (
          <div style={{ textAlign: "center", color: "var(--ink-soft)", padding: "40px 0" }}>
            No public operator signals tagged to {carrierName} in {cityMeta.name} in the last 30 days.
            <br />
            That's not the same as nothing happening — submit a tip if you've seen something.
          </div>
        ) : (
          <>
            <div style={{ display: "grid", gridTemplateColumns: "1fr 1fr", gap: 24, marginBottom: 32 }} className="sc-grid-2">
              <div>
                <h3 style={{ fontFamily: "var(--font-serif)", fontSize: 17, marginBottom: 12 }}>Top issue types</h3>
                {topTypes.length ? (
                  <ul className="sc-list">
                    {topTypes.map(([t, n]) => (
                      <li key={t}><span>{prettyType(t)}</span><span className="count">{n}</span></li>
                    ))}
                  </ul>
                ) : <p style={{ color: "var(--ink-soft)" }}>—</p>}
              </div>
              <div>
                <h3 style={{ fontFamily: "var(--font-serif)", fontSize: 17, marginBottom: 12 }}>Severity mix · 30d</h3>
                <ul className="sc-list">
                  {["critical","high","moderate","low"].map(s => {
                    const n = within30d.filter(r => sev(r) === s).length;
                    if (n === 0) return null;
                    return <li key={s}><span style={{ textTransform: "capitalize" }}>{s}</span><span className="count">{n}</span></li>;
                  })}
                </ul>
              </div>
            </div>

            <div className="sc-feed">
              {within30d.slice(0, 10).map(r => (
                <div className="sc-row" key={r.id}>
                  <div className="sc-row-meta">
                    <span className={`sc-pill ${sev(r)}`}>{sev(r)}</span>
                    <span>{prettyType(r.parsed_intel_type || "other")}</span>
                    <span>· {fmtDate(r.created_at)}</span>
                  </div>
                  <p className="sc-row-text">{r.raw_text}</p>
                </div>
              ))}
            </div>
          </>
        )}
      </section>

      {/* Paywall affordance — premium-tier upsell */}
      <section className="sc-section">
        <div className="sc-locked">
          <div className="sc-locked-h">Subscriber-tier deliverable</div>
          <h3 className="sc-locked-title">The full {carrierName} · {cityMeta.name} report</h3>
          <p className="sc-locked-body">
            Lane-level scoring, dock-level operator-rated detention, claims and damage-rate
            trend over six quarters, real-name shipper testimony (where consented), regulatory
            and FMCSA-tied violations, and the editorial pattern read. Updated every Pulse cycle.
          </p>
          <div className="sc-cta-row">
            <button className="btn-primary-lg" onClick={() => onNav("members")}>
              See subscriber pricing →
            </button>
            <button className="btn-ghost-lg" onClick={() => onNav("methodology")}>
              Read the methodology
            </button>
          </div>
        </div>
      </section>
    </div>
  );
}

window.PerCityScorecard = PerCityScorecard;
