/* SubMedium — shared UI components */
const { useState, useEffect, useRef } = React;

/* ---------- source avatar + stack ---------- */
function SourceAvatar({ k, size = 22 }) {
  const s = SRC[k] || { name: k };
  return (
    <span
      title={s.name}
      style={{
        width: size, height: size, flex: "0 0 auto",
        display: "inline-flex", alignItems: "center", justifyContent: "center",
        fontFamily: "var(--mono)", fontWeight: 600,
        fontSize: size * 0.4, letterSpacing: "0.01em",
        color: "var(--ink)", background: "var(--paper-2)",
        border: "1px solid var(--line)",
        borderRadius: size > 28 ? 4 : 3,
      }}
    >
      {initials(s.name)}
    </span>
  );
}

function AvatarStack({ sources = [], count, onOpen, compact }) {
  const shown = sources.slice(0, compact ? 3 : 4);
  const extra = (count || sources.length) - shown.length;
  return (
    <button
      onClick={onOpen}
      style={{
        display: "inline-flex", alignItems: "center", gap: 9,
        background: "none", border: 0, padding: 0, color: "inherit",
      }}
      className="avatarstack"
    >
      <span style={{ display: "inline-flex" }}>
        {shown.map((s, i) => (
          <span key={i} style={{ marginLeft: i ? -6 : 0, position: "relative", zIndex: shown.length - i }}>
            <SourceAvatar k={s.k} />
          </span>
        ))}
      </span>
      <span className="meta" style={{ color: "var(--ink-2)", fontWeight: 500 }}>
        {count || sources.length} sources
        {extra > 0 && <span style={{ color: "var(--ink-3)" }}> · all coverage →</span>}
      </span>
    </button>
  );
}

/* ---------- AI Brief ---------- */
function BriefMark() {
  return (
    <svg width="13" height="13" viewBox="0 0 12 12" aria-hidden="true" style={{ flex: "0 0 auto" }}>
      <path d="M6 0 L7.4 4.6 L12 6 L7.4 7.4 L6 12 L4.6 7.4 L0 6 L4.6 4.6 Z"
        fill="var(--accent)" />
    </svg>
  );
}

function AIBrief({ text, tight }) {
  return (
    <div style={{
      borderTop: "1px solid var(--line)", borderBottom: "1px solid var(--line)",
      padding: tight ? "12px 0" : "15px 0", margin: tight ? "0" : "2px 0",
    }}>
      <div style={{ display: "flex", alignItems: "center", gap: 7, marginBottom: 7 }}>
        <BriefMark />
        <span className="kicker" style={{ color: "var(--ink-2)" }}>The Brief</span>
        <span className="meta" style={{ fontSize: 10, color: "var(--ink-3)" }}>· AI synthesis</span>
      </div>
      <p style={{
        margin: 0, fontFamily: "var(--serif)", fontStyle: "italic",
        fontSize: tight ? 14.5 : 16, lineHeight: 1.5, color: "var(--ink-2)",
        fontWeight: 400,
      }}>{text}</p>
    </div>
  );
}

/* ---------- market ticker ---------- */
function Quote({ q }) {
  const up = q.pct >= 0;
  return (
    <span style={{ display: "inline-flex", alignItems: "baseline", gap: 8, marginRight: 26 }}>
      <span style={{ fontFamily: "var(--mono)", fontSize: 12, color: "var(--ink-2)", letterSpacing: "0.02em" }}>{q.sym}</span>
      <span style={{ fontFamily: "var(--mono)", fontSize: 12, color: "var(--ink)" }}>{q.val}</span>
      <span style={{ fontFamily: "var(--mono)", fontSize: 12, color: up ? "var(--up)" : "var(--down)" }}>
        {up ? "▲" : "▼"} {Math.abs(q.pct).toFixed(2)}%
      </span>
    </span>
  );
}
function Ticker() {
  const row = [...MARKETS, ...MARKETS];
  return (
    <div style={{ background: "var(--paper-3)", borderBottom: "1px solid var(--line)", overflow: "hidden" }}>
      <div className="shell" style={{ display: "flex", alignItems: "center", gap: 0, height: 34 }}>
        <span className="kicker" style={{ flex: "0 0 auto", marginRight: 18, color: "var(--accent-2)" }}>Live</span>
        <div style={{ overflow: "hidden", flex: 1, position: "relative", maskImage: "linear-gradient(90deg,transparent,#000 3%,#000 97%,transparent)" }}>
          <div className="ticker-track" style={{ display: "inline-flex", whiteSpace: "nowrap" }}>
            {row.map((q, i) => <Quote key={i} q={q} />)}
          </div>
        </div>
      </div>
    </div>
  );
}

/* ---------- masthead ---------- */
function Wordmark({ onClick }) {
  return (
    <button onClick={onClick} style={{ background: "none", border: 0, padding: 0, display: "flex", alignItems: "baseline", gap: 0, cursor: "pointer" }}>
      <span style={{ fontFamily: "var(--serif)", fontWeight: 620, fontSize: 30, letterSpacing: "-0.02em", color: "var(--ink)" }}>Sub</span>
      <span style={{ fontFamily: "var(--serif)", fontWeight: 620, fontSize: 30, letterSpacing: "-0.02em", color: "var(--accent)" }}>Medium</span>
      <span style={{ width: 6, height: 6, borderRadius: 6, background: "var(--accent)", marginLeft: 3, alignSelf: "flex-end", marginBottom: 6 }} />
    </button>
  );
}

function dateLabel() {
  return new Date("2026-06-15T09:00:00").toLocaleDateString("en-US", { weekday: "long", year: "numeric", month: "long", day: "numeric" });
}

function Masthead({ section, setSection, onHome, query, setQuery, forYou, setForYou }) {
  return (
    <header style={{ background: "var(--paper)", position: "sticky", top: 0, zIndex: 50, boxShadow: "0 1px 0 var(--line-2)" }}>
      {/* top row */}
      <div className="shell" style={{ display: "grid", gridTemplateColumns: "1fr auto 1fr", alignItems: "center", padding: "14px 28px 12px" }}>
        <div className="meta" style={{ fontSize: 11.5 }}>{dateLabel()}</div>
        <Wordmark onClick={onHome} />
        <div style={{ display: "flex", alignItems: "center", justifyContent: "flex-end", gap: 14 }}>
          <div style={{ position: "relative", display: "flex", alignItems: "center" }}>
            <svg width="15" height="15" viewBox="0 0 16 16" style={{ position: "absolute", left: 9, opacity: 0.5 }}><circle cx="7" cy="7" r="5" fill="none" stroke="currentColor" strokeWidth="1.5"/><path d="M11 11l3.5 3.5" stroke="currentColor" strokeWidth="1.5"/></svg>
            <input
              value={query} onChange={(e) => setQuery(e.target.value)}
              placeholder="Search every source…"
              style={{
                font: "inherit", fontSize: 13, fontFamily: "var(--mono)",
                padding: "7px 12px 7px 30px", width: 188, color: "var(--ink)",
                background: "var(--paper-2)", border: "1px solid var(--line)", borderRadius: 3, outline: "none",
              }} />
          </div>
          <button style={{ background: "none", border: 0, fontFamily: "var(--sans)", fontSize: 13.5, fontWeight: 500, color: "var(--ink-2)" }}>Sign in</button>
        </div>
      </div>
      <hr className="rule-ink" />
      {/* nav row */}
      <div className="shell" style={{ display: "flex", alignItems: "center", justifyContent: "space-between", height: 46 }}>
        <nav style={{ display: "flex", gap: 2, marginLeft: -10 }}>
          {SECTIONS.map((s) => {
            const active = s === section;
            return (
              <button key={s} onClick={() => setSection(s)}
                style={{
                  background: "none", border: 0, padding: "6px 11px", position: "relative",
                  fontFamily: "var(--sans)", fontSize: 14, fontWeight: active ? 600 : 450,
                  color: active ? "var(--ink)" : "var(--ink-2)",
                }}>
                {s}
                {active && <span style={{ position: "absolute", left: 11, right: 11, bottom: -1, height: 2, background: "var(--accent)" }} />}
              </button>
            );
          })}
        </nav>
        <button onClick={() => setForYou(!forYou)}
          style={{
            display: "inline-flex", alignItems: "center", gap: 7,
            background: forYou ? "var(--ink)" : "transparent",
            color: forYou ? "var(--paper)" : "var(--ink-2)",
            border: "1px solid " + (forYou ? "var(--ink)" : "var(--line)"),
            borderRadius: 3, padding: "6px 13px", fontSize: 13, fontWeight: 500,
          }}>
          <svg width="13" height="13" viewBox="0 0 14 14"><path d="M7 1.5l1.6 3.3 3.6.5-2.6 2.5.6 3.6L7 10.2 3.8 11.9l.6-3.6L1.8 5.8l3.6-.5z" fill={forYou ? "var(--accent-2)" : "none"} stroke="currentColor" strokeWidth="1.1"/></svg>
          For You
        </button>
      </div>
      <hr className="rule" />
    </header>
  );
}

/* ---------- story cards ---------- */
function SectionTag({ children }) {
  return <span className="kicker" style={{ marginRight: 10 }}>{children}</span>;
}

function ImagePH({ credit, h, slot }) {
  if (slot) {
    return <image-slot id={slot} placeholder="Drop a photo" style={{ width: "100%", height: h }} shape="rect"></image-slot>;
  }
  return (
    <div className="imgph" style={{ width: "100%", height: h }}>
      <span className="credit">{credit || "Wire photo"}</span>
    </div>
  );
}

function LeadStory({ s, onOpen, showBrief = true }) {
  return (
    <article className="rise" style={{ display: "grid", gridTemplateColumns: "1.18fr 1fr", gap: 30, alignItems: "start" }}>
      <div style={{ cursor: "pointer" }} onClick={onOpen}>
        <ImagePH h={372} slot="lead-hero" />
      </div>
      <div>
        <div style={{ display: "flex", alignItems: "center", gap: 8, marginBottom: 11 }}>
          <SectionTag>{s.kicker}</SectionTag>
          {s.live && <LiveDot />}
        </div>
        <h1 className="hl" style={{ fontSize: 41, margin: "0 0 14px", cursor: "pointer" }} onClick={onOpen}>{s.headline}</h1>
        <p className="dek" style={{ fontSize: 19, margin: "0 0 16px" }}>{s.dek}</p>
        {showBrief && <AIBrief text={s.brief} />}
        <div style={{ marginTop: 14, display: "flex", alignItems: "center", justifyContent: "space-between" }}>
          <AvatarStack sources={s.sources} count={s.sourceCount} onOpen={onOpen} />
          <span className="meta">{s.time} ago</span>
        </div>
      </div>
    </article>
  );
}

function LiveDot() {
  return (
    <span style={{ display: "inline-flex", alignItems: "center", gap: 6 }}>
      <span style={{ width: 7, height: 7, borderRadius: 7, background: "var(--down)", boxShadow: "0 0 0 0 var(--down)", animation: "pulse 1.8s infinite" }} />
      <span className="meta" style={{ color: "var(--down)", fontWeight: 600, fontSize: 11 }}>LIVE</span>
    </span>
  );
}

function StoryCard({ s, onOpen, thumb, brief }) {
  return (
    <article style={{ display: "flex", flexDirection: "column", gap: 10, cursor: "pointer" }} onClick={onOpen}>
      {thumb && <ImagePH h={150} />}
      <div>
        <SectionTag>{s.kicker}</SectionTag>
        {s.live && <LiveDot />}
      </div>
      <h2 className="hl clamp-3" style={{ fontSize: thumb ? 22 : 23, margin: 0 }}>{s.headline}</h2>
      {brief
        ? <AIBrief text={s.brief} tight />
        : <p className="dek clamp-2" style={{ fontSize: 15.5, margin: 0 }}>{s.dek}</p>}
      <div style={{ display: "flex", alignItems: "center", justifyContent: "space-between", marginTop: "auto", paddingTop: 4 }}>
        <AvatarStack sources={s.sources} count={s.sourceCount} onOpen={(e) => { e.stopPropagation(); onOpen(); }} compact />
        <span className="meta">{s.time}</span>
      </div>
    </article>
  );
}

function CompactRow({ s, onOpen, idx }) {
  return (
    <article onClick={onOpen} style={{ display: "grid", gridTemplateColumns: "auto 1fr", gap: 13, cursor: "pointer", padding: "13px 0" }}>
      {idx != null && <span style={{ fontFamily: "var(--serif)", fontSize: 19, fontWeight: 600, color: "var(--accent)", lineHeight: 1 }}>{String(idx).padStart(2, "0")}</span>}
      <div>
        <h3 className="hl clamp-2" style={{ fontSize: 16.5, margin: "0 0 6px", fontWeight: 540 }}>{s.headline}</h3>
        <div style={{ display: "flex", alignItems: "center", gap: 9 }}>
          <span className="meta" style={{ color: "var(--ink-2)" }}>{s.sourceCount} sources</span>
          <span className="meta">· {s.time}</span>
        </div>
      </div>
    </article>
  );
}

Object.assign(window, { SourceAvatar, AvatarStack, AIBrief, BriefMark, Ticker, Masthead, LeadStory, StoryCard, CompactRow, ImagePH, SectionTag, LiveDot });
