/* Login + Dashboard + Generate screens */

/* ------------------------------ LOGIN ------------------------------ */
function LoginScreen({ onLogin }) {
  const [email, setEmail] = useState("");
  const [pwd, setPwd] = useState("");
  const [loading, setLoading] = useState(false);
  const [error, setError] = useState("");

  const submit = async (e) => {
    e.preventDefault();
    setLoading(true);
    setError("");
    try {
      const data = await api.login(email, pwd);
      onLogin(data.token);
    } catch (err) {
      setError(err.message || "Login failed");
      setLoading(false);
    }
  };

  return (
    <div style={{
      minHeight: "100vh", background: "var(--bg)",
      display: "grid", gridTemplateColumns: "1fr 1fr"
    }}>
      {/* Left — form */}
      <div style={{ display: "flex", flexDirection: "column", padding: "32px 48px" }}>
        <div className="row gap-2">
          <Logo size={24} />
          <div className="fw-600" style={{ fontSize: 15 }}>Pulse</div>
        </div>
        <div style={{ flex: 1, display: "flex", flexDirection: "column", justifyContent: "center", maxWidth: 360, width: "100%", margin: "0 auto" }}>
          <h1 style={{ fontSize: 28, fontWeight: 600, letterSpacing: "-0.02em", marginBottom: 6 }}>Sign in</h1>
          <p className="text-2" style={{ marginBottom: 32 }}>Welcome back — continue to your project reports.</p>

          <form onSubmit={submit} className="col gap-4">
            <div className="field">
              <label>Work email</label>
              <input className="input" type="email" value={email} onChange={e => setEmail(e.target.value)} placeholder="you@company.com" />
            </div>
            <div className="field">
              <div className="row">
                <label style={{ flex: 1 }}>Password</label>
                <a className="text-xs text-2" href="#" style={{ textDecoration: "underline", textUnderlineOffset: 3 }}>Forgot?</a>
              </div>
              <input className="input" type="password" value={pwd} onChange={e => setPwd(e.target.value)} />
            </div>
            {error && (
              <div style={{ color: "var(--red)", fontSize: 13, padding: "8px 12px", background: "var(--red-bg)", borderRadius: 6 }}>
                {error}
              </div>
            )}
            <button type="submit" className="btn btn-primary btn-lg" style={{ justifyContent: "center", width: "100%" }}>
              {loading ? "Signing in…" : (<>Continue <I.ArrowRight style={{ width: 14, height: 14 }} /></>)}
            </button>

            <div className="row gap-3" style={{ margin: "4px 0" }}>
              <div style={{ flex: 1, height: 1, background: "var(--border)" }}></div>
              <span className="text-xs text-3">or</span>
              <div style={{ flex: 1, height: 1, background: "var(--border)" }}></div>
            </div>

            <button type="button" className="btn btn-secondary btn-lg" style={{ justifyContent: "center", width: "100%" }} onClick={onLogin}>
              <svg width="14" height="14" viewBox="0 0 24 24"><path fill="#4285f4" d="M22.56 12.25c0-.78-.07-1.53-.2-2.25H12v4.26h5.92c-.26 1.37-1.04 2.53-2.21 3.31v2.77h3.57c2.08-1.92 3.28-4.74 3.28-8.09z"/><path fill="#34a853" d="M12 23c2.97 0 5.46-.98 7.28-2.66l-3.57-2.77c-.98.66-2.23 1.06-3.71 1.06-2.86 0-5.29-1.93-6.16-4.53H2.18v2.84C3.99 20.53 7.7 23 12 23z"/><path fill="#fbbc05" d="M5.84 14.09c-.22-.66-.35-1.36-.35-2.09s.13-1.43.35-2.09V7.07H2.18C1.43 8.55 1 10.22 1 12s.43 3.45 1.18 4.93l2.85-2.22.81-.62z"/><path fill="#ea4335" d="M12 5.38c1.62 0 3.06.56 4.21 1.64l3.15-3.15C17.45 2.09 14.97 1 12 1 7.7 1 3.99 3.47 2.18 7.07l3.66 2.84c.87-2.6 3.3-4.53 6.16-4.53z"/></svg>
              Continue with Google
            </button>
            <button type="button" className="btn btn-secondary btn-lg" style={{ justifyContent: "center", width: "100%" }} onClick={onLogin}>
              <svg width="14" height="14" viewBox="0 0 24 24" fill="#2684ff"><path d="M11.533 6.33A5.62 5.62 0 0 0 13.97 11.4l5.24 5.24a.69.69 0 0 0 .97 0l3.65-3.65a.69.69 0 0 0 0-.97L16.21 4.4a.69.69 0 0 0-.97 0l-3.7 3.7a.69.69 0 0 0 0 .98l-.01-2.74z" opacity=".5"/><path d="M.2 11.39a.69.69 0 0 0 0 .97l7.6 7.63a.69.69 0 0 0 .98 0l3.65-3.66a5.62 5.62 0 0 1-2.44-5.06L4.83 5.94a.69.69 0 0 0-.97 0L.2 11.39z"/></svg>
              Continue with Atlassian SSO
            </button>

            <div className="text-sm text-2 mt-4" style={{ textAlign: "center" }}>
              Don't have an account? <a href="#" style={{ color: "var(--text)", textDecoration: "underline", textUnderlineOffset: 3 }}>Request access</a>
            </div>
          </form>
        </div>
        <div className="text-xs text-3" style={{ textAlign: "center" }}>
          Pulse · secure session · SOC2 Type II
        </div>
      </div>

      {/* Right — hero panel */}
      <div style={{
        background: "var(--surface)", borderLeft: "1px solid var(--border)",
        display: "flex", flexDirection: "column", padding: "48px",
        position: "relative", overflow: "hidden"
      }}>
        <div style={{ position: "absolute", inset: 0, background: "radial-gradient(circle at 80% 10%, color-mix(in oklab, var(--text) 4%, transparent), transparent 50%)", pointerEvents: "none" }}></div>
        <div style={{ position: "relative", zIndex: 1, flex: 1, display: "flex", flexDirection: "column", justifyContent: "center", maxWidth: 520 }}>
          <div className="pill" style={{ alignSelf: "flex-start", marginBottom: 20 }}>
            <span className="dot dot-green"></span>
            Weekly report — ready in 55 seconds
          </div>
          <div className="serif" style={{ fontSize: 40, fontWeight: 400, letterSpacing: "-0.03em", lineHeight: 1.1, marginBottom: 16 }}>
            Stakeholder-ready project reports,<br/>without the spreadsheet gymnastics.
          </div>
          <div className="text-2" style={{ fontSize: 15, lineHeight: 1.6, marginBottom: 32 }}>
            Pulse reads your Jira, computes RAG, detects velocity anomalies, scores your RAID log,
            and matches current sprint fingerprints against history — all in one run.
          </div>

          {/* Mini preview card */}
          <div className="card" style={{ boxShadow: "var(--sh-md)" }}>
            <div className="card-head" style={{ padding: "10px 14px" }}>
              <div className="row gap-2">
                <RagDot status="red" />
                <span className="fw-500">BuildLog — Week of Apr 18</span>
              </div>
              <span className="text-xs text-3 mono">report_2026-04-18.html</span>
            </div>
            <div style={{ padding: "14px", display: "grid", gridTemplateColumns: "1fr 1fr 1fr", gap: 12 }}>
              {[
                { label: "Velocity", v: "23%", rag: "red" },
                { label: "Overdue", v: "21", rag: "red" },
                { label: "Blockers", v: "3", rag: "amber" },
              ].map(m => (
                <div key={m.label}>
                  <div className="label-xs mb-2">{m.label}</div>
                  <div className="row gap-2">
                    <div style={{ fontSize: 20, fontWeight: 600 }} className="mono">{m.v}</div>
                    <div className={`dot dot-${m.rag}`}></div>
                  </div>
                </div>
              ))}
            </div>
            <div style={{ padding: "0 14px 14px", borderTop: "1px solid var(--border)", paddingTop: 12 }}>
              <div className="label-xs mb-3">Workstreams</div>
              {[
                { n: "Backend", v: 22, rag: "red" },
                { n: "Frontend", v: 31, rag: "red" },
                { n: "QA", v: 22, rag: "red" },
              ].map(w => (
                <div key={w.n} className="row gap-3" style={{ marginBottom: 8 }}>
                  <span className="text-sm" style={{ width: 60 }}>{w.n}</span>
                  <div className="bar-track" style={{ flex: 1 }}>
                    <div className={`bar-fill ${w.rag}`} style={{ width: `${w.v}%` }}></div>
                  </div>
                  <span className="mono text-xs text-2" style={{ width: 30, textAlign: "right" }}>{w.v}%</span>
                </div>
              ))}
            </div>
          </div>
        </div>
      </div>
    </div>
  );
}

/* ------------------------------ DASHBOARD helpers ------------------------------ */
function getIsoWeek(d = new Date()) {
  const date = new Date(Date.UTC(d.getFullYear(), d.getMonth(), d.getDate()));
  const dayNum = date.getUTCDay() || 7;
  date.setUTCDate(date.getUTCDate() + 4 - dayNum);
  const yearStart = new Date(Date.UTC(date.getUTCFullYear(), 0, 1));
  return Math.ceil((((date - yearStart) / 86400000) + 1) / 7);
}

function timeAgo(isoStr) {
  if (!isoStr) return null;
  const diffMs = Date.now() - new Date(isoStr).getTime();
  const mins = Math.round(diffMs / 60000);
  if (mins < 1) return "just now";
  if (mins < 60) return `${mins}m ago`;
  const hrs = Math.round(mins / 60);
  if (hrs < 24) return `${hrs}h ago`;
  return `${Math.round(hrs / 24)}d ago`;
}

/* ------------------------------ DASHBOARD ------------------------------ */
function Dashboard({ onNav }) {
  const [dashData, setDashData] = useState(null);

  useEffect(() => {
    api.get("/api/dashboard").then(setDashData).catch(() => {});
  }, []);

  // Fall back to demo if API has no data yet
  const latest = dashData?.latest?.length
    ? dashData.latest
    : DEMO_REPORTS.filter(r => r.date === "2026-04-18");
  const velSpark = dashData?.velocity_spark?.length
    ? dashData.velocity_spark
    : [58, 42, 38, 31, 42, 23];

  const ragReport = latest.find(r => r.type === "rag") || latest[0];
  const overallRag = ragReport?.overall_rag || ragReport?.overall || "red";
  const weekNum = getIsoWeek();
  const lastRunAgo = timeAgo(ragReport?.generated_at);
  const pageSub = lastRunAgo
    ? `Here's where BuildLog stands going into week ${weekNum}. Last report: ${lastRunAgo}.`
    : `Here's where BuildLog stands going into week ${weekNum}.`;
  const metrics = ragReport?.metrics || {};
  const velPct = metrics.velocityPct ?? 23;
  const overdueVal = metrics.overdue ?? 21;
  const completionPct = metrics.done != null && metrics.totalIssues
    ? Math.round((metrics.done / metrics.totalIssues) * 100)
    : metrics.velocityPct ?? 29;

  const overdueTrend = [5, 9, 12, 18, 17, overdueVal];
  const completionTrend = [72, 64, 48, 40, 32, completionPct];

  const kpis = [
    { label: "Overall RAG", v: <RagPill status={overallRag} />, spark: null, delta: "last report" },
    { label: "Velocity", v: `${velPct}%`, rag: velPct < 60 ? "red" : velPct < 80 ? "amber" : "green", delta: "vs estimate", spark: velSpark, sparkColor: "var(--red)" },
    { label: "Overdue items", v: String(overdueVal), rag: overdueVal > 5 ? "red" : overdueVal > 2 ? "amber" : "green", delta: "open issues", spark: overdueTrend, sparkColor: "var(--red)" },
    { label: "Completion", v: `${completionPct}%`, rag: completionPct < 50 ? "red" : completionPct < 75 ? "amber" : "green", delta: "done / total", spark: completionTrend, sparkColor: "var(--red)" },
  ];

  return (
    <div className="page">
      <div className="page-head">
        <div>
          <div className="pill mb-3">
            <I.Folder style={{ width: 12, height: 12 }} />
            BuildLog <span className="text-3 mono" style={{ marginLeft: 4 }}>BL</span>
          </div>
          <div className="page-title">Good morning, Maks.</div>
          <div className="page-sub">{pageSub}</div>
        </div>
        <div className="row gap-2">
          <button className="btn btn-secondary" onClick={() => onNav("archive")}>
            <I.Archive /> Browse archive
          </button>
          <button className="btn btn-primary" onClick={() => onNav("generate")}>
            <I.Zap style={{ width: 14, height: 14 }} /> Generate reports
          </button>
        </div>
      </div>

      {/* KPI strip */}
      <div style={{ display: "grid", gridTemplateColumns: "repeat(4, 1fr)", gap: 12, marginBottom: 32 }}>
        {kpis.map((k, i) => (
          <div key={i} className="card" style={{ padding: "16px 18px" }}>
            <div className="label-xs mb-3">{k.label}</div>
            <div className="row" style={{ alignItems: "flex-end", justifyContent: "space-between", marginBottom: 8 }}>
              <div style={{ display: "flex", alignItems: "center", gap: 8 }}>
                {typeof k.v === "string" ? (
                  <>
                    <div style={{ fontSize: 28, fontWeight: 600, letterSpacing: "-0.02em" }} className="mono">{k.v}</div>
                    {k.rag && <div className={`dot dot-${k.rag}`}></div>}
                  </>
                ) : k.v}
              </div>
              {k.spark && <Sparkline values={k.spark} color={k.sparkColor} width={90} height={28} />}
            </div>
            <div className="text-xs text-3">{k.delta}</div>
          </div>
        ))}
      </div>

      {/* Two columns: Latest reports + Pattern alert */}
      <div style={{ display: "grid", gridTemplateColumns: "2fr 1fr", gap: 24, marginBottom: 32 }}>
        <div className="card">
          <div className="card-head">
            <div className="card-title">Latest run · {(ragReport?.date || latest[0]?.date || "—")}</div>
            <button className="btn btn-ghost btn-sm" onClick={() => onNav("archive")}>All runs <I.ChevRight style={{ width: 12, height: 12 }} /></button>
          </div>
          <div>
            {latest.map((r, idx) => {
              const t = reportTypeMeta(r.type);
              const Icon = t ? t.icon : I.File;
              const rag = r.overall_rag || r.overall || "amber";
              return (
                <div key={r.id} style={{
                  padding: "14px 20px",
                  borderBottom: idx < latest.length - 1 ? "1px solid var(--border)" : "none",
                  display: "grid", gridTemplateColumns: "auto 1fr auto auto", alignItems: "center", gap: 16,
                  cursor: "pointer"
                }}
                  onClick={() => onNav("report", { reportId: r.id })}
                  onMouseEnter={e => e.currentTarget.style.background = "var(--surface-2)"}
                  onMouseLeave={e => e.currentTarget.style.background = "transparent"}
                >
                  <div style={{ width: 32, height: 32, borderRadius: 8, background: "var(--surface-2)", display: "flex", alignItems: "center", justifyContent: "center", color: t ? t.color : "var(--text-2)" }}>
                    <Icon />
                  </div>
                  <div>
                    <div className="fw-500">{t ? t.name : r.type}</div>
                    <div className="text-sm text-3">{t ? t.tagline : r.date}</div>
                  </div>
                  {rag && <RagPill status={rag} />}
                  <I.ArrowUpRight style={{ color: "var(--text-3)" }} />
                </div>
              );
            })}
          </div>
        </div>

        {/* Pattern alert card */}
        <div className="card" style={{ borderColor: "color-mix(in oklab, var(--red) 30%, var(--border))" }}>
          <div className="card-head" style={{ borderBottomColor: "color-mix(in oklab, var(--red) 20%, var(--border))" }}>
            <div className="row gap-2">
              <I.Alert style={{ color: "var(--red)" }} />
              <div className="card-title">Pattern alert</div>
            </div>
            <span className="pill pill-red">99.8%</span>
          </div>
          <div className="card-body">
            <div className="fw-500 mb-2">Matches BL Sprint 3</div>
            <div className="text-sm text-2 mb-4" style={{ lineHeight: 1.6 }}>
              Current sprint fingerprint is 99.8% similar to a historically failed sprint — 22% completion, 35% overdue ratio. Blocker ratio is already <span className="fw-500 text-red">higher</span> than baseline.
            </div>
            <button className="btn btn-secondary btn-sm" onClick={() => onNav("report", { reportId: "p-2026-04-18" })}>
              Open pattern report <I.ChevRight style={{ width: 12, height: 12 }} />
            </button>
          </div>
        </div>
      </div>

      {/* Workstream strip */}
      <div className="card mb-6">
        <div className="card-head">
          <div className="card-title">Workstreams</div>
          <span className="text-xs text-3">18 Apr 2026</span>
        </div>
        <div style={{ display: "grid", gridTemplateColumns: "repeat(3, 1fr)" }}>
          {[
            { n: "Backend",  rag: "red", v: 22, done: "6/21",  overdue: 7, blockers: 1, bugs: 3, owner: "alex.petrov" },
            { n: "Frontend", rag: "red", v: 31, done: "6/20",  overdue: 7, blockers: 0, bugs: 4, owner: "natasha.web" },
            { n: "QA",       rag: "red", v: 22, done: "4/14",  overdue: 4, blockers: 2, bugs: 1, owner: "dmitri.fox" },
          ].map((w, i, arr) => (
            <div key={w.n} style={{
              padding: "20px 24px",
              borderRight: i < arr.length - 1 ? "1px solid var(--border)" : "none",
            }}>
              <div className="row mb-3">
                <span className="fw-600">{w.n}</span>
                <div className="spacer"></div>
                <RagPill status={w.rag} />
              </div>
              <div className="bar-track mb-3">
                <div className={`bar-fill ${w.rag}`} style={{ width: `${w.v}%` }}></div>
              </div>
              <div className="row mb-4" style={{ fontSize: 11 }}>
                <span className="mono">{w.v}% velocity</span>
                <div className="spacer"></div>
                <span className="text-3 mono">{w.done} done</span>
              </div>
              <div style={{ display: "grid", gridTemplateColumns: "repeat(3, 1fr)", gap: 8 }}>
                {[
                  { l: "Overdue", v: w.overdue, color: w.overdue > 0 ? "var(--red)" : "var(--text-2)" },
                  { l: "Blockers", v: w.blockers, color: w.blockers > 0 ? "var(--amber)" : "var(--text-2)" },
                  { l: "Open bugs", v: w.bugs, color: "var(--text-2)" },
                ].map(m => (
                  <div key={m.l}>
                    <div className="label-xs">{m.l}</div>
                    <div className="mono fw-500" style={{ color: m.color, fontSize: 16, marginTop: 2 }}>{m.v}</div>
                  </div>
                ))}
              </div>
              <div className="text-xs text-3 mt-4 mono">lead · {w.owner}</div>
            </div>
          ))}
        </div>
      </div>

      {/* Recent activity */}
      <div className="card">
        <div className="card-head">
          <div className="card-title">Recent activity</div>
          <button className="btn btn-ghost btn-sm">View all</button>
        </div>
        <div>
          {[
            { t: "3h ago", icon: I.Zap, text: <>Maks generated <span className="fw-500">all 4 reports</span> for week ending 18 Apr</>, meta: "RED overall · 56s" },
            { t: "3h ago", icon: I.Alert, text: <>Pattern report flagged <span className="fw-500 text-red">99.8% match</span> with BL Sprint 3</>, meta: "failed sprint historical" },
            { t: "1d ago", icon: I.Shield, text: <>BL-41 escalated to Critical blocker in RAID log</>, meta: "alex.petrov" },
            { t: "1w ago", icon: I.Zap, text: <>Scheduled weekly run completed · AMBER → RED transition</>, meta: "4 of 4 reports" },
            { t: "2w ago", icon: I.Settings, text: <>Schedule updated — Fridays 17:00 Europe/Kyiv</>, meta: "" },
          ].map((a, i) => (
            <div key={i} className="row gap-3" style={{ padding: "12px 20px", borderBottom: i < 4 ? "1px solid var(--border)" : "none" }}>
              <div style={{ width: 26, height: 26, borderRadius: 6, background: "var(--surface-2)", display: "flex", alignItems: "center", justifyContent: "center", color: "var(--text-2)" }}>
                <a.icon style={{ width: 13, height: 13 }} />
              </div>
              <div className="text-sm" style={{ flex: 1 }}>{a.text}</div>
              <div className="text-xs text-3 mono">{a.meta}</div>
              <div className="text-xs text-3" style={{ width: 60, textAlign: "right" }}>{a.t}</div>
            </div>
          ))}
        </div>
      </div>
    </div>
  );
}

/* ------------------------------ GENERATE (wizard with streaming) ------------------------------ */
function GenerateScreen({ onNav, initialSelection = [] }) {
  // step: "configure" | "running" | "done"
  const [step, setStep] = useState("configure");
  const [selected, setSelected] = useState(
    initialSelection.length > 0 ? initialSelection : REPORT_TYPES.map(r => r.id)
  );
  const [period, setPeriod] = useState("week");
  const [projectKey, setProjectKey] = useState("BL");
  const [notify, setNotify] = useState(true);
  const [dryRun, setDryRun] = useState(false);

  // run state
  const [progress, setProgress] = useState({}); // { id: 0..100 }
  const [logs, setLogs] = useState([]);
  const [currentIdx, setCurrentIdx] = useState(-1);
  const logsRef = useRef(null);

  const selectedTypes = REPORT_TYPES.filter(t => selected.includes(t.id));

  const toggle = (id) => {
    setSelected(sel => sel.includes(id) ? sel.filter(x => x !== id) : [...sel, id]);
  };

  const [runId, setRunId] = useState(null);
  const [runError, setRunError] = useState("");

  const startRun = async () => {
    setStep("running");
    setRunError("");
    setProgress(Object.fromEntries(selectedTypes.map(t => [t.id, 0])));
    setLogs([{ t: "00:00:00", msg: "Starting agents…" }]);
    setCurrentIdx(0);
    try {
      const agents = selected.length === REPORT_TYPES.length ? ["all"] : selected;
      const { run_id } = await api.post("/api/generate", { agents, dry_run: dryRun });
      setRunId(run_id);
    } catch (err) {
      setRunError(err.message);
      setStep("configure");
    }
  };

  // SSE streaming
  useEffect(() => {
    if (!runId || step !== "running") return;
    let agentIdx = 0;
    const es = api.streamRun(runId, (data) => {
      if (data.done) {
        setProgress(p => Object.fromEntries(Object.keys(p).map(k => [k, 100])));
        setTimeout(() => setStep("done"), 500);
        return;
      }
      const msg = data.msg || "";
      setLogs(l => [...l, { t: data.t || "", msg, done: msg.includes("✓") }]);

      // Advance per-agent progress heuristically based on log content
      const type = selectedTypes[agentIdx];
      if (type) {
        if (msg.includes("Fetching")) setProgress(p => ({ ...p, [type.id]: 20 }));
        else if (msg.includes("Computing") || msg.includes("Processing")) setProgress(p => ({ ...p, [type.id]: 50 }));
        else if (msg.includes("Claude") || msg.includes("narrative")) setProgress(p => ({ ...p, [type.id]: 75 }));
        else if (msg.includes("saved") || msg.includes("HTML")) {
          setProgress(p => ({ ...p, [type.id]: 100 }));
          agentIdx = Math.min(agentIdx + 1, selectedTypes.length - 1);
        }
      }
    });
    return () => es.close();
  }, [runId]);

  useEffect(() => {
    if (logsRef.current) logsRef.current.scrollTop = logsRef.current.scrollHeight;
  }, [logs]);

  if (step === "configure") {
    return (
      <div className="page" style={{ maxWidth: 960 }}>
        <div className="page-head">
          <div>
            <div className="label-xs mb-2">Step 1 of 2 · Configure run</div>
            <div className="page-title">Generate reports</div>
            <div className="page-sub">Pick what to run. Claude reads fresh Jira data and produces stakeholder-ready HTML.</div>
          </div>
          <button className="btn btn-ghost" onClick={() => onNav("dashboard")}><I.X style={{ width: 14, height: 14 }} /> Cancel</button>
        </div>

        {/* Report cards */}
        <div className="label-xs mb-3">Reports to generate</div>
        <div style={{ display: "grid", gridTemplateColumns: "1fr 1fr", gap: 12, marginBottom: 24 }}>
          {REPORT_TYPES.map(t => {
            const active = selected.includes(t.id);
            const Icon = t.icon;
            return (
              <div key={t.id} onClick={() => toggle(t.id)} className="card" style={{
                padding: 18, cursor: "pointer",
                borderColor: active ? "var(--text)" : "var(--border)",
                boxShadow: active ? "0 0 0 3px var(--surface-3)" : "none",
                transition: "all 0.15s",
              }}>
                <div className="row gap-3 mb-3">
                  <div style={{ width: 34, height: 34, borderRadius: 8, background: "var(--surface-2)", display: "flex", alignItems: "center", justifyContent: "center", color: t.color }}>
                    <Icon />
                  </div>
                  <div style={{ flex: 1 }}>
                    <div className="fw-600">{t.name}</div>
                    <div className="text-xs text-3 mono">{t.runtime}</div>
                  </div>
                  <div style={{
                    width: 18, height: 18, borderRadius: 5, border: `1.5px solid ${active ? "var(--text)" : "var(--border-2)"}`,
                    background: active ? "var(--text)" : "transparent",
                    display: "flex", alignItems: "center", justifyContent: "center",
                  }}>
                    {active && <I.Check style={{ width: 12, height: 12, color: "var(--accent-fg)", strokeWidth: 3 }} />}
                  </div>
                </div>
                <div className="text-sm text-2" style={{ lineHeight: 1.55 }}>{t.desc}</div>
              </div>
            );
          })}
        </div>

        {/* Options */}
        <div className="card mb-6">
          <div className="card-head"><div className="card-title">Options</div></div>
          <div style={{ padding: 20, display: "grid", gridTemplateColumns: "1fr 1fr", gap: 20 }}>
            <div className="field">
              <label>Project</label>
              <div className="row gap-2">
                <input className="input" value={projectKey} onChange={e => setProjectKey(e.target.value)} />
                <button className="btn btn-secondary">Change</button>
              </div>
              <div className="text-xs text-3 mt-2 mono">buildlog001.atlassian.net</div>
            </div>
            <div className="field">
              <label>Report period</label>
              <div className="row gap-1" style={{ background: "var(--surface-2)", padding: 3, borderRadius: 6 }}>
                {[{ id: "week", l: "This week" }, { id: "sprint", l: "Current sprint" }, { id: "month", l: "Last 30d" }].map(p => (
                  <button key={p.id} onClick={() => setPeriod(p.id)} style={{
                    flex: 1, padding: "7px 10px", border: "none", borderRadius: 4,
                    background: period === p.id ? "var(--surface)" : "transparent",
                    color: period === p.id ? "var(--text)" : "var(--text-2)",
                    fontWeight: period === p.id ? 500 : 400, fontSize: 12, cursor: "pointer",
                    boxShadow: period === p.id ? "var(--sh-sm)" : "none",
                  }}>{p.l}</button>
                ))}
              </div>
            </div>
            <div style={{ gridColumn: "span 2", display: "flex", flexDirection: "column", gap: 10 }}>
              {[
                { id: "notify", v: notify, set: setNotify, l: "Post to #buildlog-reports Slack channel when done" },
                { id: "dry", v: dryRun, set: setDryRun, l: "Dry-run (generate without saving to archive)" },
              ].map(o => (
                <label key={o.id} className="row gap-3" style={{ cursor: "pointer" }}>
                  <div onClick={() => o.set(!o.v)} style={{
                    width: 32, height: 18, borderRadius: 100, padding: 2,
                    background: o.v ? "var(--text)" : "var(--border-2)",
                    transition: "background 0.15s", cursor: "pointer", flexShrink: 0,
                  }}>
                    <div style={{
                      width: 14, height: 14, borderRadius: 100, background: "var(--surface)",
                      transform: o.v ? "translateX(14px)" : "translateX(0)",
                      transition: "transform 0.15s",
                    }}></div>
                  </div>
                  <span className="text-sm">{o.l}</span>
                </label>
              ))}
            </div>
          </div>
        </div>

        {/* Footer action bar */}
        <div className="row" style={{
          position: "sticky", bottom: 20, background: "var(--surface)", border: "1px solid var(--border)",
          borderRadius: "var(--r-lg)", padding: "12px 16px", boxShadow: "var(--sh-md)",
        }}>
          <div className="text-sm text-2">
            {runError
              ? <span style={{ color: "var(--red)" }}>{runError}</span>
              : <><span className="fw-500">{selected.length}</span> of {REPORT_TYPES.length} reports ·{" "}
                <span className="mono">~{selectedTypes.reduce((s, t) => s + parseInt(t.runtime.replace(/\D/g, "")), 0)}s</span> estimated</>
            }
          </div>
          <div className="spacer"></div>
          <button className="btn btn-secondary" onClick={() => onNav("dashboard")}>Cancel</button>
          <button className="btn btn-primary" disabled={selected.length === 0} onClick={startRun}
            style={{ opacity: selected.length === 0 ? 0.5 : 1 }}>
            <I.Zap style={{ width: 14, height: 14 }} /> Run {selected.length} report{selected.length !== 1 ? "s" : ""}
          </button>
        </div>
      </div>
    );
  }

  // RUNNING or DONE
  const allDone = step === "done";
  return (
    <div className="page" style={{ maxWidth: 960 }}>
      <div className="page-head">
        <div>
          <div className="label-xs mb-2">Step 2 of 2 · {allDone ? "Completed" : "Running"}</div>
          <div className="page-title">{allDone ? "Your reports are ready." : "Generating reports…"}</div>
          <div className="page-sub">
            {allDone
              ? `${selectedTypes.length} reports generated in ${((logs.length) * 0.6).toFixed(1)}s · saved to archive`
              : `Reading Jira, scoring, and invoking Claude. Don't close this tab.`}
          </div>
        </div>
        {allDone && (
          <button className="btn btn-primary" onClick={() => onNav("archive")}>
            View in archive <I.ArrowRight style={{ width: 14, height: 14 }} />
          </button>
        )}
      </div>

      {/* Progress list */}
      <div className="card mb-4">
        {selectedTypes.map((t, i, arr) => {
          const pct = progress[t.id] || 0;
          const isActive = currentIdx === i && !allDone;
          const isDone = pct >= 100;
          const Icon = t.icon;
          return (
            <div key={t.id} style={{
              padding: "16px 20px",
              borderBottom: i < arr.length - 1 ? "1px solid var(--border)" : "none",
              display: "grid", gridTemplateColumns: "auto 1fr auto auto", alignItems: "center", gap: 16,
            }}>
              <div style={{
                width: 32, height: 32, borderRadius: 8, background: "var(--surface-2)",
                display: "flex", alignItems: "center", justifyContent: "center",
                color: isDone ? "var(--green)" : isActive ? "var(--text)" : "var(--text-3)",
              }}>
                {isDone ? <I.Check /> : <Icon />}
              </div>
              <div>
                <div className="fw-500">{t.name}</div>
                <div className="text-xs text-3">{t.tagline}</div>
              </div>
              <div style={{ width: 200 }}>
                <div className="bar-track">
                  <div className="bar-fill" style={{
                    width: `${pct}%`,
                    background: isDone ? "var(--green)" : "var(--text)"
                  }}></div>
                </div>
              </div>
              <div className="mono text-xs" style={{ width: 48, textAlign: "right", color: isDone ? "var(--green)" : isActive ? "var(--text)" : "var(--text-3)" }}>
                {isDone ? "done" : isActive ? `${pct}%` : "queued"}
              </div>
            </div>
          );
        })}
      </div>

      {/* Live log */}
      <div className="card">
        <div className="card-head">
          <div className="row gap-2">
            <div className={`dot ${allDone ? "dot-green" : "dot-amber"}`} style={{ animation: allDone ? "none" : "pulse 1.4s infinite" }}></div>
            <div className="card-title">Live log</div>
          </div>
          <span className="text-xs text-3 mono">agents_runner.py · pid 48291</span>
        </div>
        <div ref={logsRef} style={{
          padding: 16, background: "var(--surface-2)", maxHeight: 260, overflowY: "auto",
          fontFamily: "var(--font-mono)", fontSize: 12, lineHeight: 1.8,
          borderRadius: "0 0 var(--r-lg) var(--r-lg)"
        }}>
          {logs.map((l, i) => (
            <div key={i} style={{ color: l.done ? "var(--green)" : "var(--text-2)" }}>
              <span style={{ color: "var(--text-3)", marginRight: 12 }}>{l.t}</span>
              {l.msg}
            </div>
          ))}
          {!allDone && (
            <div style={{ color: "var(--text-3)", display: "flex", alignItems: "center", gap: 8 }}>
              <span className="mono">▋</span>
            </div>
          )}
        </div>
      </div>

      {/* Done — report links */}
      {allDone && (
        <div className="card mt-4">
          <div className="card-head"><div className="card-title">Generated reports</div></div>
          <div>
            {selectedTypes.map((t, i, arr) => {
              const Icon = t.icon;
              return (
                <div key={t.id} onClick={() => onNav("report", { reportId: `${t.id[0]}-${new Date().toISOString().slice(0,10)}` })} style={{
                  padding: "14px 20px",
                  borderBottom: i < arr.length - 1 ? "1px solid var(--border)" : "none",
                  display: "grid", gridTemplateColumns: "auto 1fr auto auto", alignItems: "center", gap: 16, cursor: "pointer"
                }}
                  onMouseEnter={e => e.currentTarget.style.background = "var(--surface-2)"}
                  onMouseLeave={e => e.currentTarget.style.background = "transparent"}
                >
                  <div style={{ color: t.color }}><Icon /></div>
                  <div>
                    <div className="fw-500">{t.name}</div>
                    <div className="text-xs text-3 mono">{t.id}_{new Date().toISOString().slice(0,10)}.html</div>
                  </div>
                  <RagPill status="red" />
                  <I.ArrowUpRight style={{ color: "var(--text-3)" }} />
                </div>
              );
            })}
          </div>
        </div>
      )}

      <style>{`@keyframes pulse { 0%, 100% { opacity: 1; } 50% { opacity: 0.4; } }`}</style>
    </div>
  );
}

Object.assign(window, { LoginScreen, Dashboard, GenerateScreen });
