// ————————————————————————————————————————————————————————————————
// SingleReportView — renders actual report content (markdown + portfolio cards)
// ————————————————————————————————————————————————————————————————

const { useMemo: SRUM, useState: SRUS } = React;

// The topic dossier whose canonical report is this slug (null if the report isn't
// a topic canonical). Drives the on-demand Revision history drawer.
function findTopicForReport(slug) {
  return (window.TOPICS || []).find((t) => t.report_slug === slug) || null;
}

// Revision history — collapsed by default ("only when we'd like to check we go
// through that part"). Each row links to that prior version if it's still a
// reachable report; otherwise it's shown as an archived line.
function RevisionHistory({ topic }) {
  const [open, setOpen] = SRUS(false);
  if (!topic || !(topic.revisions || []).length) return null;
  const reachable = new Set((window.ALL_REPORTS || []).map((r) => r.slug));
  return (
    <section style={{ marginTop: 40, borderTop: "1px solid var(--line)", paddingTop: 20 }}>
      <button
        className="btn ghost"
        onClick={() => setOpen((o) => !o)}
        style={{ fontFamily: "var(--mono)", fontSize: 12 }}
      >
        {open ? "▾" : "▸"} Revision history ({topic.revisions.length})
      </button>
      {open && (
        <ol style={{ marginTop: 12, listStyle: "none", padding: 0 }}>
          {topic.revisions.map((rev) => {
            const label = rev.change_summary || rev.report_slug;
            const viewable = reachable.has(rev.report_slug);
            return (
              <li
                key={rev.version}
                style={{ display: "flex", gap: 10, padding: "6px 0", fontSize: 13, lineHeight: 1.5 }}
              >
                <span style={{ fontFamily: "var(--mono)", color: "var(--fg-3)", whiteSpace: "nowrap" }}>
                  v{rev.version} · {rev.as_of}
                </span>
                {viewable ? (
                  <a href={"?view=single-report&slug=" + rev.report_slug} style={{ color: "var(--accent)" }}>
                    {label}
                  </a>
                ) : (
                  <span style={{ color: "var(--fg-1)" }}>{label}</span>
                )}
              </li>
            );
          })}
        </ol>
      )}
    </section>
  );
}

// Simple markdown → JSX renderer (no external deps)
function renderMarkdown(md) {
  if (!md) return null;
  const lines = md.split("\n");
  const elements = [];
  let i = 0;
  let inTable = false;
  let tableRows = [];

  function flushTable() {
    if (!tableRows.length) return;
    const headerRow = tableRows[0];
    const dataRows = tableRows.slice(2); // skip separator row
    elements.push(
      React.createElement("div", { key: "tbl-" + elements.length, className: "rep-md-table-wrap" },
        React.createElement("table", { className: "rep-md-table" },
          React.createElement("thead", null,
            React.createElement("tr", null,
              headerRow.map((cell, ci) =>
                React.createElement("th", { key: ci, dangerouslySetInnerHTML: { __html: inlineFormat(cell.trim()) } })
              )
            )
          ),
          React.createElement("tbody", null,
            dataRows.map((row, ri) =>
              React.createElement("tr", { key: ri },
                row.map((cell, ci) =>
                  React.createElement("td", { key: ci, dangerouslySetInnerHTML: { __html: inlineFormat(cell.trim()) } })
                )
              )
            )
          )
        )
      )
    );
    tableRows = [];
    inTable = false;
  }

  function inlineFormat(text) {
    if (!text) return "";
    return text
      .replace(/\*\*(.+?)\*\*/g, "<strong>$1</strong>")
      .replace(/\*(.+?)\*/g, "<em>$1</em>")
      .replace(/`(.+?)`/g, "<code>$1</code>")
      .replace(/\[([^\]]+)\]\(([^)]+)\)/g, '<a href="$2" target="_blank" rel="noopener">$1</a>');
  }

  while (i < lines.length) {
    const line = lines[i];

    // Table detection
    if (line.startsWith("|")) {
      inTable = true;
      const cells = line.split("|").slice(1, -1);
      tableRows.push(cells);
      i++;
      continue;
    } else if (inTable) {
      flushTable();
    }

    // Skip first h1 (already shown in header)
    if (i === 0 && line.startsWith("# ")) { i++; continue; }

    // Headings
    if (line.startsWith("## ")) {
      elements.push(React.createElement("h2", { key: i, className: "rep-md-h2" }, line.slice(3)));
    } else if (line.startsWith("### ")) {
      elements.push(React.createElement("h3", { key: i, className: "rep-md-h3" }, line.slice(4)));
    } else if (line.startsWith("#### ")) {
      elements.push(React.createElement("h4", { key: i, className: "rep-md-h4" }, line.slice(5)));
    }
    // Horizontal rule
    else if (line.startsWith("---")) {
      elements.push(React.createElement("hr", { key: i, className: "rep-md-hr" }));
    }
    // Bold metadata lines like **Time:** 01:07
    else if (line.startsWith("**") && line.includes(":**")) {
      elements.push(React.createElement("div", {
        key: i, className: "rep-md-meta",
        dangerouslySetInnerHTML: { __html: inlineFormat(line) }
      }));
    }
    // List items
    else if (line.match(/^\d+\.\s/)) {
      elements.push(React.createElement("div", {
        key: i, className: "rep-md-li",
        dangerouslySetInnerHTML: { __html: inlineFormat(line) }
      }));
    }
    else if (line.startsWith("- ")) {
      elements.push(React.createElement("div", {
        key: i, className: "rep-md-li bullet",
        dangerouslySetInnerHTML: { __html: "  " + inlineFormat(line.slice(2)) }
      }));
    }
    // Empty line
    else if (!line.trim()) {
      // skip
    }
    // Paragraph
    else {
      elements.push(React.createElement("p", {
        key: i, className: "rep-md-p",
        dangerouslySetInnerHTML: { __html: inlineFormat(line) }
      }));
    }
    i++;
  }
  if (inTable) flushTable();
  return elements;
}

// Company card for portfolio-backed reports
function ReportCompanyCard({ company, lang }) {
  const c = company;
  const dimScores = c.dimension_scores;
  return (
    <div className="rep-company-card" style={{ padding: "20px 24px", background: "var(--bg-1)", borderRadius: 10, border: "1px solid var(--line)", marginBottom: 12 }}>
      <div style={{ display: "flex", alignItems: "center", gap: 12, marginBottom: 12 }}>
        <span style={{ fontFamily: "var(--mono)", fontWeight: 600, fontSize: 15 }}>{(c.ticker || "").replace(".T", "")}</span>
        <span style={{ fontWeight: 500, fontSize: 14 }}>{c.name}</span>
        <span className={"conviction-badge " + (c.conviction || "LOW").toLowerCase()} style={{
          padding: "2px 8px", borderRadius: 4, fontSize: 11, fontWeight: 600,
          background: c.conviction === "HIGH" ? "oklch(68% 0.18 25 / 0.15)" : c.conviction === "MEDIUM" ? "oklch(76% 0.14 70 / 0.15)" : "var(--bg-2)",
          color: c.conviction === "HIGH" ? "oklch(68% 0.18 25)" : c.conviction === "MEDIUM" ? "oklch(76% 0.14 70)" : "var(--fg-2)",
        }}>{c.conviction}</span>
        <span style={{ fontSize: 12, color: "var(--fg-3)" }}>{c.layer} · {((c.weight || 0) * 100).toFixed(0)}%</span>
      </div>

      {c.thesis && <p style={{ fontSize: 13, lineHeight: 1.6, color: "var(--fg-1)", margin: "0 0 12px" }}>{c.thesis}</p>}

      <div style={{ display: "grid", gridTemplateColumns: "repeat(auto-fit, minmax(100px, 1fr))", gap: 8, marginBottom: 12 }}>
        {[
          ["P/E", c.pe], ["Fwd P/E", c.forward_pe], ["P/B", c.pb],
          ["ROE", c.roe], ["Op Mgn", c.op_margin], ["Div Y", c.div_yield], ["FCF", c.fcf]
        ].map(([label, val]) => (
          <div key={label} style={{ fontSize: 12, padding: "6px 8px", background: "var(--bg-2)", borderRadius: 6 }}>
            <div style={{ color: "var(--fg-3)", fontSize: 10, marginBottom: 2 }}>{label}</div>
            <div style={{ fontFamily: "var(--mono)", fontWeight: 500 }}>{val != null && val !== "" && val !== "N/A" ? String(val) : "—"}</div>
          </div>
        ))}
      </div>

      {dimScores && (
        <div style={{ display: "flex", gap: 6, flexWrap: "wrap", marginBottom: 10 }}>
          {Object.entries(dimScores).map(([k, v]) => (
            <div key={k} style={{
              fontSize: 11, padding: "3px 8px", borderRadius: 4,
              background: v >= 8 ? "oklch(78% 0.16 155 / 0.12)" : v >= 5 ? "oklch(76% 0.14 70 / 0.12)" : "oklch(68% 0.18 25 / 0.12)",
              color: v >= 8 ? "oklch(78% 0.16 155)" : v >= 5 ? "oklch(76% 0.14 70)" : "oklch(68% 0.18 25)",
              fontWeight: 500,
            }}>{k} {v}/10</div>
          ))}
        </div>
      )}

      {c.risk && <div style={{ fontSize: 12, color: "var(--fg-2)", lineHeight: 1.5 }}><strong style={{ color: "oklch(68% 0.18 25)" }}>Risk:</strong> {c.risk.slice(0, 200)}</div>}
    </div>
  );
}


function SingleReportView({ slug, lang, onBack, onOpenStock }) {
  const report = SRUM(() => {
    return (window.ALL_REPORTS || []).find(r => r.slug === slug);
  }, [slug, window._reportsReady]);  // recompute when the deferred report blob lands

  if (!report) {
    return (
      <div className="reports-view" style={{ padding: 40 }}>
        <button className="btn ghost" onClick={onBack}>← Back</button>
        <div style={{ marginTop: 20, color: "var(--fg-2)" }}>Report not found: {slug}</div>
      </div>
    );
  }

  const hasCompanies = report.companies && report.companies.length > 0;

  return (
    <div className="rep-scroll" style={{ overflow: "auto", height: "calc(100vh - 60px)" }}>
      <div className="rep-inner" style={{ maxWidth: 1000, margin: "0 auto", padding: "40px 48px 80px" }}>
        {/* Back button */}
        <button className="btn ghost" onClick={onBack} style={{ marginBottom: 16 }}>
          ← {lang === "jp" ? "レポート一覧" : "Back to reports"}
        </button>

        {/* Header */}
        <header style={{ marginBottom: 32 }}>
          <div style={{ fontSize: 12, color: "var(--fg-3)", marginBottom: 8, fontFamily: "var(--mono)" }}>
            {report.date} {report.time && `· ${report.time}`} · {report.theme}
          </div>
          <h1 style={{ fontSize: 26, fontWeight: 600, letterSpacing: "-0.02em", color: "var(--fg-0)", margin: "0 0 8px" }}>
            {report.title}
          </h1>
          {report.portfolioSubtitle && (
            <div style={{ fontSize: 15, color: "var(--fg-1)" }}>{report.portfolioSubtitle}</div>
          )}
        </header>

        {/* Portfolio companies (if JSON-backed) */}
        {hasCompanies && (
          <section style={{ marginBottom: 32 }}>
            <h2 className="rep-md-h2">{lang === "jp" ? "ポートフォリオ" : "Portfolio"} ({report.companies.length} stocks)</h2>
            {report.macroContext && (
              <p style={{ fontSize: 14, lineHeight: 1.6, color: "var(--fg-1)", marginBottom: 16 }}>{report.macroContext}</p>
            )}
            {report.companies.map(c => (
              <ReportCompanyCard key={c.ticker} company={c} lang={lang} />
            ))}
          </section>
        )}

        {/* Markdown content */}
        <section className="rep-md-content">
          {renderMarkdown(report.content)}
        </section>

        {/* Revision history (only if this report is a topic canonical) */}
        <RevisionHistory topic={findTopicForReport(report.slug)} />
      </div>
    </div>
  );
}

window.SingleReportView = SingleReportView;
window.RevisionHistory = RevisionHistory;
window.findTopicForReport = findTopicForReport;
