/* ミニCMS：記事テンプレート（技術ブログ品質）
   POSTS（posts.js）からデータを受け取り、目次・著者カード・図・数値・コード・FAQを描画する。
   記事を増やす = posts.js にデータを足す + 薄いラッパーHTMLを1枚置く だけ。 */

function inlineNodes(text) {
  // **太字** と `コード` の簡易インライン記法をReactノードに
  if (text == null) return [];
  text = String(text);
  const out = [];
  const re = /(\*\*[^*]+\*\*|`[^`]+`|\[[^\]]+\]\([^)]+\))/g;
  let last = 0, m, i = 0;
  while ((m = re.exec(text)) !== null) {
    if (m.index > last) out.push(text.slice(last, m.index));
    const tok = m[0];
    if (tok.startsWith("**")) out.push(<strong key={i++} style={{ fontWeight: 500, color: "#1A1530" }}>{tok.slice(2, -2)}</strong>);
    else if (tok.startsWith("`")) out.push(<code key={i++} style={{ fontFamily: "var(--font-mono-label), monospace", fontSize: "0.92em", background: "var(--purple-light)", color: "#3C2A8A", padding: "2px 7px", borderRadius: 6 }}>{tok.slice(1, -1)}</code>);
    else { const lm = tok.match(/\[([^\]]+)\]\(([^)]+)\)/); out.push(<a key={i++} href={lm[2]} style={{ color: "var(--purple)", textDecoration: "underline", textUnderlineOffset: 3 }}>{lm[1]}</a>); }
    last = m.index + tok.length;
  }
  if (last < text.length) out.push(text.slice(last));
  return out;
}

function ProseH2({ id, children }) {
  return (
    <h2 id={id} style={{
      fontFamily: "var(--font-serif)", fontSize: 28, fontWeight: 500, color: "#1A1530",
      letterSpacing: "-0.01em", lineHeight: 1.4, margin: "64px 0 20px",
      paddingLeft: 16, borderLeft: "4px solid var(--purple)", scrollMarginTop: 90,
    }}>{children}</h2>
  );
}
function ProseP({ lead, children }) {
  return <p style={{ fontFamily: "var(--font-sans)", fontSize: lead ? 19 : 17, color: lead ? "#1A1A1A" : "#2A2733", lineHeight: lead ? 1.9 : 1.95, margin: "0 0 22px" }}>{children}</p>;
}

function TLDR({ items }) {
  return (
    <div style={{ background: "var(--purple-light)", borderRadius: 16, padding: "26px 30px", margin: "8px 0 8px" }}>
      <div style={{ fontFamily: "var(--font-mono-label)", fontSize: 12, letterSpacing: "0.18em", color: "#3C2A8A", fontWeight: 500, marginBottom: 14 }}>— この記事でわかること —</div>
      <ul style={{ margin: 0, paddingLeft: 20, display: "flex", flexDirection: "column", gap: 9 }}>
        {items.map((t, i) => <li key={i} style={{ fontFamily: "var(--font-sans)", fontSize: 15.5, color: "#2A2733", lineHeight: 1.7 }}>{inlineNodes(t)}</li>)}
      </ul>
    </div>
  );
}
function TOC({ items }) {
  if (!items.length) return null;
  return (
    <nav style={{ border: "1px solid #E5E5E5", borderRadius: 16, padding: "22px 26px", margin: "32px 0", background: "#fff" }}>
      <div style={{ fontFamily: "var(--font-mono-label)", fontSize: 12, letterSpacing: "0.18em", color: "var(--purple)", fontWeight: 500, marginBottom: 14 }}>— 目次 —</div>
      <ol style={{ margin: 0, paddingLeft: 20, display: "flex", flexDirection: "column", gap: 10 }}>
        {items.map((h, i) => <li key={i} style={{ fontFamily: "var(--font-sans)", fontSize: 14.5, lineHeight: 1.6 }}>
          <a href={"#" + h.id} style={{ color: "#2A2733", textDecoration: "none" }}
            onMouseEnter={(e) => e.currentTarget.style.color = "var(--purple)"}
            onMouseLeave={(e) => e.currentTarget.style.color = "#2A2733"}>{h.t}</a>
        </li>)}
      </ol>
    </nav>
  );
}
function StatCards({ items }) {
  return (
    <div style={{ display: "grid", gridTemplateColumns: `repeat(${Math.min(items.length, 3)}, 1fr)`, gap: 16, margin: "28px 0 34px" }}>
      {items.map((s, i) => (
        <div key={i} style={{ border: "1px solid #E5E5E5", borderRadius: 16, padding: "26px 22px", background: "#fff", textAlign: "center" }}>
          <div style={{ fontFamily: "var(--font-serif)", fontSize: 40, fontWeight: 500, color: "#1A1530", lineHeight: 1 }}>
            {s.num}<span style={{ fontSize: 17, color: "var(--purple)", marginLeft: 3 }}>{s.unit}</span>
          </div>
          <div style={{ width: 36, height: 3, background: "var(--purple)", borderRadius: 2, margin: "14px auto" }} />
          <div style={{ fontFamily: "var(--font-sans)", fontSize: 13, color: "#6B6B6B", lineHeight: 1.6 }}>{s.label}</div>
        </div>
      ))}
    </div>
  );
}
function CompareTable({ head, rows }) {
  return (
    <div style={{ overflowX: "auto", margin: "28px 0 34px" }}>
      <table style={{ width: "100%", borderCollapse: "collapse", fontFamily: "var(--font-sans)", fontSize: 14.5 }}>
        <thead>
          <tr>
            <th style={{ textAlign: "left", padding: "14px 16px", borderBottom: "2px solid #E5E5E5", color: "#6B6B6B", fontWeight: 500, fontSize: 13 }}></th>
            <th style={{ textAlign: "left", padding: "14px 16px", borderBottom: "2px solid #E5E5E5", color: "#6B6B6B", fontWeight: 500 }}>{head[0]}</th>
            <th style={{ textAlign: "left", padding: "14px 16px", borderBottom: "2px solid var(--purple)", color: "#3C2A8A", fontWeight: 500 }}>{head[1]}</th>
          </tr>
        </thead>
        <tbody>
          {rows.map((r, i) => (
            <tr key={i}>
              <td style={{ padding: "14px 16px", borderBottom: "1px solid #EFEDE8", fontWeight: 500, color: "#1A1530" }}>{r[0]}</td>
              <td style={{ padding: "14px 16px", borderBottom: "1px solid #EFEDE8", color: "#6B6B6B" }}>{r[1]}</td>
              <td style={{ padding: "14px 16px", borderBottom: "1px solid #EFEDE8", color: "#2A2733", background: "rgba(124,92,255,0.04)" }}>{inlineNodes(r[2])}</td>
            </tr>
          ))}
        </tbody>
      </table>
    </div>
  );
}
function Callout({ children }) {
  return (
    <div style={{ borderLeft: "3px solid var(--purple)", background: "#fff", borderRadius: "0 12px 12px 0", padding: "20px 24px", margin: "28px 0", fontFamily: "var(--font-serif)", fontSize: 20, lineHeight: 1.7, color: "#1A1530" }}>
      {inlineNodes(children)}
    </div>
  );
}
function Figure({ img, caption }) {
  return (
    <figure style={{ margin: "32px 0 34px" }}>
      <img src={img} alt={caption || ""} loading="lazy" style={{ width: "100%", borderRadius: 16, display: "block", border: "1px solid #E5E5E5" }} />
      {caption && <figcaption style={{ fontFamily: "var(--font-sans)", fontSize: 13, color: "#6B6B6B", marginTop: 10, textAlign: "center" }}>{caption}</figcaption>}
    </figure>
  );
}
function CodeBlock({ lang, code }) {
  return (
    <pre style={{ margin: "26px 0 32px", borderRadius: 12, overflow: "auto", border: "1px solid #2A2540" }}>
      <code className={"language-" + (lang || "text")} style={{ fontFamily: "var(--font-mono-label), monospace", fontSize: 13.5, lineHeight: 1.7 }}>{code}</code>
    </pre>
  );
}
function FAQ({ items }) {
  return (
    <div style={{ margin: "16px 0 8px", display: "flex", flexDirection: "column", gap: 14 }}>
      {items.map((f, i) => (
        <div key={i} style={{ border: "1px solid #E5E5E5", borderRadius: 14, padding: "22px 26px", background: "#fff" }}>
          <div style={{ fontFamily: "var(--font-sans)", fontSize: 16, fontWeight: 500, color: "#1A1530", marginBottom: 10 }}>Q. {f.q}</div>
          <div style={{ fontFamily: "var(--font-sans)", fontSize: 15, color: "#2A2733", lineHeight: 1.9 }}>{inlineNodes(f.a)}</div>
        </div>
      ))}
    </div>
  );
}

function AuthorCard({ author }) {
  return (
    <div style={{ display: "flex", gap: 20, alignItems: "center", border: "1px solid #E5E5E5", borderRadius: 18, padding: "26px 30px", background: "#fff", margin: "48px 0 8px" }}>
      <img src={author.avatar} alt={author.name} style={{ width: 64, height: 64, borderRadius: "50%", objectFit: "cover", objectPosition: "center 28%", flexShrink: 0, background: "var(--bg-base)", border: "1px solid #E5E5E5" }} />
      <div style={{ flex: 1 }}>
        <div style={{ fontFamily: "var(--font-serif)", fontSize: 18, fontWeight: 500, color: "#1A1530" }}>{author.name}</div>
        <div style={{ fontFamily: "var(--font-sans)", fontSize: 13, color: "#6B6B6B", marginTop: 3, lineHeight: 1.6 }}>{author.role}</div>
        <div style={{ display: "flex", gap: 16, marginTop: 10, fontFamily: "var(--font-sans)", fontSize: 13 }}>
          {author.x && <a href={author.x} target="_blank" rel="noopener noreferrer" style={{ color: "var(--purple)", textDecoration: "none" }}>X / Twitter</a>}
          {author.note && <a href={author.note} target="_blank" rel="noopener noreferrer" style={{ color: "var(--purple)", textDecoration: "none" }}>note</a>}
        </div>
      </div>
    </div>
  );
}

function readingMinutes(post) {
  let n = 0;
  (post.content || []).forEach((b) => {
    if (b.t) n += b.t.length;
    if (b.items) b.items.forEach((x) => n += (typeof x === "string" ? x.length : (x.label || "").length + (x.a || "").length + (x.q || "").length));
    if (b.rows) b.rows.forEach((r) => r.forEach((c) => n += String(c).length));
    if (b.code) n += b.code.length / 3;
  });
  return Math.max(2, Math.round(n / 480));
}

function ArticleBody({ post }) {
  const blocks = post.content.map((b, i) => {
    switch (b.k) {
      case "tldr": return <TLDR key={i} items={b.items} />;
      case "h2": return <ProseH2 key={i} id={b.id}>{b.t}</ProseH2>;
      case "lead": return <ProseP key={i} lead>{inlineNodes(b.t)}</ProseP>;
      case "p": return <ProseP key={i}>{inlineNodes(b.t)}</ProseP>;
      case "stats": return <StatCards key={i} items={b.items} />;
      case "compare": return <CompareTable key={i} head={b.head} rows={b.rows} />;
      case "callout": return <Callout key={i}>{b.t}</Callout>;
      case "figure": return <Figure key={i} img={b.img} caption={b.caption} />;
      case "code": return <CodeBlock key={i} lang={b.lang} code={b.code} />;
      case "faq": return <FAQ key={i} items={b.items} />;
      default: return null;
    }
  });
  return <div>{blocks}</div>;
}

function ArticleApp({ slug }) {
  const post = (typeof POSTS !== "undefined") && POSTS.find((p) => p.slug === slug);
  React.useEffect(() => {
    if (window.hljs) window.hljs.highlightAll();
  }, []);
  if (!post) return <div style={{ padding: 80, textAlign: "center" }}>記事が見つかりません。</div>;
  const toc = post.content.filter((b) => b.k === "h2").map((b) => ({ id: b.id, t: b.t }));
  return (
    <div>
      <Nav />
      <main>
        <PageHero
          labelEn="INSIGHTS · 発信"
          watermark="INSIGHTS"
          breadcrumb={[{ label: "TOP", href: "index.html" }, { label: "発信", href: "insights.html" }, { label: post.label || "記事" }]}
          titleParts={post.titleParts}
          intro={post.heroIntro} />
        <section style={{ padding: "44px 24px 100px", background: "var(--bg-base)" }}>
          <div style={{ maxWidth: 760, margin: "0 auto" }}>
            <div style={{ display: "flex", flexWrap: "wrap", gap: 14, alignItems: "center", fontFamily: "var(--font-mono-label)", fontSize: 12, letterSpacing: "0.06em", color: "#6B6B6B", marginBottom: 28 }}>
              <span style={{ color: "var(--purple)", fontWeight: 500 }}>{post.label}</span>
              <span>{post.date}</span>
              <span>約{readingMinutes(post)}分で読めます</span>
              {(post.tags || []).map((t) => <span key={t} style={{ background: "var(--purple-light)", color: "#3C2A8A", padding: "4px 11px", borderRadius: 999 }}>#{t}</span>)}
            </div>
            <ArticleBody post={post} />
            <AuthorCard author={post.author} />
          </div>
        </section>
        <BigCTA
          labelEn="JOIN US"
          title="AIで会社を動かす現場を、一緒に。"
          sub="AIエージェントと人が協働する現場を、つくってくれるエンジニアを探しています。"
          primary={{ href: "recruit/entry.html", label: "カジュアル面談" }}
          secondary={{ href: "recruit/index.html", label: "採用情報を見る" }} />
      </main>
      <Footer />
      {TWEAK_DEFAULTS.showSideRail && <SideRail />}
      <TweaksPanel defaults={TWEAK_DEFAULTS} />
    </div>
  );
}
