/* global React, window */
// Shared CategoryLP component used by all 6 categories.
// Pages pass dept id + per-category motif SVG renderer.

const { CATEGORIES_EXT, AUTHORS, ARTICLES, TAGS_EXT } = window.cynixDataExt;
const { TAGS_V2 } = window.cynixDataExtV2;
const { SharedMasthead, Breadcrumb, Colophon, findAuthor, findCategory } = window.cynixShared;

const ALL_TAGS = (() => {
  const seen = new Set();
  return [...TAGS_EXT, ...TAGS_V2].filter((t) => {
    if (seen.has(t.slug)) return false;
    seen.add(t.slug);
    return true;
  });
})();

// ─────── Per-category hero photos (gpt-image-1 documentary photo) ───────
const HERO_PHOTOS = {
  server: "hero-server.png",
  domain: "hero-domain-ssl.png",
  saas: "hero-saas.png",
  ec: "hero-ec.png",
  ai: "hero-ai-tools.png",
  rsv: "hero-reservation.png",
};

// ─────── Per-category SVG motifs ───────
const Motifs = {
  server: () => (
    <svg viewBox="0 0 600 480" preserveAspectRatio="xMidYMid slice" className="cat-hero-motif">
      <path d="M 60 460 Q 180 460 240 320 L 320 100 Q 335 75 350 100 L 430 320 Q 490 460 580 460 Z" fill="#F4EFE3" opacity="0.18" />
      <path d="M -10 320 Q 180 280 360 310 T 610 290" stroke="#00D4FF" strokeOpacity="0.7" strokeWidth="1.5" fill="none" />
      <path d="M -10 360 Q 200 340 400 355 T 610 350" stroke="#FFF200" strokeOpacity="0.5" strokeWidth="1" fill="none" strokeDasharray="2 6" />
      <circle cx="460" cy="140" r="48" fill="#E63535" opacity="0.95" />
      <line x1="0" y1="380" x2="600" y2="380" stroke="#00D4FF" strokeOpacity="0.4" strokeWidth="1" strokeDasharray="4 8" />
    </svg>
  ),
  domain: () => (
    <svg viewBox="0 0 600 480" preserveAspectRatio="xMidYMid slice" className="cat-hero-motif">
      {/* globe */}
      <circle cx="300" cy="250" r="160" fill="none" stroke="#FFB800" strokeOpacity="0.5" strokeWidth="1.4" />
      <ellipse cx="300" cy="250" rx="160" ry="60" fill="none" stroke="#FFB800" strokeOpacity="0.4" strokeWidth="1" />
      <ellipse cx="300" cy="250" rx="60" ry="160" fill="none" stroke="#FFB800" strokeOpacity="0.4" strokeWidth="1" />
      <line x1="140" y1="250" x2="460" y2="250" stroke="#FFB800" strokeOpacity="0.4" strokeWidth="1" />
      <line x1="300" y1="90" x2="300" y2="410" stroke="#FFB800" strokeOpacity="0.4" strokeWidth="1" />
      {/* key/lock badge */}
      <circle cx="448" cy="140" r="46" fill="#E63535" opacity="0.95" />
      <rect x="438" y="128" width="20" height="16" rx="2" fill="#F4EFE3" />
      <path d="M 442 128 V 122 a 6 6 0 0 1 12 0 V 128" fill="none" stroke="#F4EFE3" strokeWidth="2" />
      {/* certified stamp */}
      <g transform="translate(80 380) rotate(-12)">
        <rect width="120" height="56" fill="none" stroke="#FFB800" strokeWidth="1.5" />
        <text x="60" y="22" fontFamily='"JetBrains Mono", monospace' fontSize="10" letterSpacing="2" fill="#FFB800" textAnchor="middle">CERTIFIED</text>
        <text x="60" y="44" fontFamily='"Noto Sans JP", serif' fontStyle="italic" fontSize="14" fontWeight="900" fill="#FFB800" textAnchor="middle">.jp</text>
      </g>
    </svg>
  ),
  saas: () => (
    <svg viewBox="0 0 600 480" preserveAspectRatio="xMidYMid slice" className="cat-hero-motif">
      {/* dashboard grid */}
      <g opacity="0.85">
        <rect x="60" y="80" width="220" height="120" fill="none" stroke="#4FCBA9" strokeOpacity="0.5" strokeWidth="1" />
        <rect x="300" y="80" width="240" height="120" fill="none" stroke="#4FCBA9" strokeOpacity="0.5" strokeWidth="1" />
        <rect x="60" y="220" width="160" height="180" fill="none" stroke="#4FCBA9" strokeOpacity="0.5" strokeWidth="1" />
        <rect x="240" y="220" width="180" height="180" fill="none" stroke="#4FCBA9" strokeOpacity="0.5" strokeWidth="1" />
        <rect x="440" y="220" width="100" height="180" fill="none" stroke="#4FCBA9" strokeOpacity="0.5" strokeWidth="1" />
      </g>
      {/* bars */}
      <g>
        <rect x="76" y="160" width="14" height="40" fill="#4FCBA9" opacity="0.7" />
        <rect x="100" y="140" width="14" height="60" fill="#4FCBA9" opacity="0.7" />
        <rect x="124" y="120" width="14" height="80" fill="#4FCBA9" opacity="0.7" />
        <rect x="148" y="150" width="14" height="50" fill="#4FCBA9" opacity="0.7" />
        <rect x="172" y="100" width="14" height="100" fill="#FFF200" opacity="0.85" />
      </g>
      {/* KPI pulse circle */}
      <circle cx="490" cy="140" r="42" fill="#E63535" opacity="0.95" />
      <text x="490" y="146" fontFamily='"Noto Sans JP", serif' fontStyle="italic" fontWeight="900" fontSize="22" fill="#F4EFE3" textAnchor="middle">+18%</text>
      {/* trend line */}
      <path d="M 60 380 Q 200 300 340 340 T 540 280" stroke="#4FCBA9" strokeOpacity="0.7" strokeWidth="1.5" fill="none" />
    </svg>
  ),
  ec: () => (
    <svg viewBox="0 0 600 480" preserveAspectRatio="xMidYMid slice" className="cat-hero-motif">
      {/* shopping bag silhouette */}
      <g transform="translate(180 90)">
        <path d="M 30 60 H 210 L 200 320 H 40 Z" fill="#FFB800" opacity="0.85" />
        <path d="M 80 60 V 30 a 40 30 0 0 1 80 0 V 60" fill="none" stroke="#0A0A0A" strokeWidth="3" />
        <text x="120" y="200" fontFamily='"Noto Sans JP", serif' fontStyle="italic" fontWeight="900" fontSize="56" fill="#0A0A0A" textAnchor="middle">¥</text>
      </g>
      {/* sales line */}
      <path d="M 60 410 L 130 380 L 200 350 L 270 320 L 340 290 L 410 240 L 480 200 L 540 160" stroke="#FF7A8E" strokeOpacity="0.85" strokeWidth="2.5" fill="none" />
      {/* milestone dots */}
      <circle cx="200" cy="350" r="6" fill="#FFF200" />
      <circle cx="340" cy="290" r="6" fill="#FFF200" />
      <circle cx="480" cy="200" r="6" fill="#FFF200" />
      {/* badge */}
      <circle cx="84" cy="120" r="36" fill="#E63535" opacity="0.95" />
      <text x="84" y="116" fontFamily='"JetBrains Mono", monospace' fontSize="9" letterSpacing="1.5" fill="#F4EFE3" textAnchor="middle">M/M</text>
      <text x="84" y="132" fontFamily='"Noto Sans JP", serif' fontStyle="italic" fontWeight="900" fontSize="16" fill="#F4EFE3" textAnchor="middle">100M</text>
    </svg>
  ),
  ai: () => (
    <svg viewBox="0 0 600 480" preserveAspectRatio="xMidYMid slice" className="cat-hero-motif">
      {/* neural network */}
      <g opacity="0.85">
        {/* edges layer 1 */}
        {[120, 240, 360].map((y) => (
          [180, 300, 420].map((y2) => (
            <line key={`e1-${y}-${y2}`} x1="140" y1={y} x2="320" y2={y2} stroke="#00D4FF" strokeOpacity="0.4" strokeWidth="0.8" />
          ))
        ))}
        {[180, 300, 420].map((y) => (
          [240].map((y2) => (
            <line key={`e2-${y}-${y2}`} x1="320" y1={y} x2="500" y2={y2} stroke="#00D4FF" strokeOpacity="0.5" strokeWidth="0.8" />
          ))
        ))}
      </g>
      {/* nodes layer 1 */}
      {[120, 240, 360].map((y) => (
        <circle key={`n1-${y}`} cx="140" cy={y} r="14" fill="#8A4FFF" opacity="0.9" />
      ))}
      {/* nodes layer 2 */}
      {[180, 300, 420].map((y) => (
        <circle key={`n2-${y}`} cx="320" cy={y} r="14" fill="#8A4FFF" opacity="0.9" />
      ))}
      {/* output node */}
      <circle cx="500" cy="240" r="22" fill="#E63535" opacity="0.95" />
      <text x="500" y="246" fontFamily='"JetBrains Mono", monospace' fontSize="13" fontWeight="700" fill="#F4EFE3" textAnchor="middle">AI</text>
      {/* signal pulse */}
      <path d="M 60 460 Q 280 450 540 320" stroke="#FFF200" strokeOpacity="0.5" strokeWidth="1" strokeDasharray="2 6" fill="none" />
    </svg>
  ),
  rsv: () => (
    <svg viewBox="0 0 600 480" preserveAspectRatio="xMidYMid slice" className="cat-hero-motif">
      {/* calendar */}
      <g transform="translate(140 100)">
        <rect width="320" height="280" fill="#F4EFE3" opacity="0.92" />
        <rect width="320" height="48" fill="#FFA361" />
        <text x="160" y="32" fontFamily='"JetBrains Mono", monospace' fontSize="13" letterSpacing="3" fill="#0A0A0A" textAnchor="middle">APRIL 2026</text>
        {/* grid */}
        {[0, 1, 2, 3, 4].map((row) => (
          [0, 1, 2, 3, 4, 5, 6].map((col) => {
            const day = row * 7 + col + 1;
            if (day > 30) return null;
            const cx = col * 45 + 22;
            const cy = row * 44 + 80;
            const isMarked = [8, 15, 22, 29].includes(day);
            return (
              <g key={`d-${day}`}>
                <text x={cx} y={cy} fontFamily='"JetBrains Mono", monospace' fontSize="11" fontWeight="700" fill="#0A0A0A" textAnchor="middle" opacity={isMarked ? 1 : 0.45}>{day}</text>
                {isMarked && <circle cx={cx} cy={cy - 3} r="14" fill="none" stroke="#E63535" strokeWidth="1.5" />}
              </g>
            );
          })
        ))}
      </g>
      {/* check badge */}
      <circle cx="500" cy="120" r="40" fill="#E63535" opacity="0.95" />
      <path d="M 484 120 L 496 132 L 516 110" stroke="#F4EFE3" strokeWidth="4" fill="none" strokeLinecap="round" strokeLinejoin="round" />
    </svg>
  ),
};

const DEPT_INDEX = (id) => CATEGORIES_EXT.findIndex((c) => c.id === id);

const CategoryPage = ({ deptId, deco, quote, articles, pillarOverrides }) => {
  const CAT = CATEGORIES_EXT.find((c) => c.id === deptId) || CATEGORIES_EXT[0];
  const idx = DEPT_INDEX(deptId);
  const ed = (CAT.chars.length === 2)
    ? { label: "NAOTO × HARUKA", primary: "naoto-miyake" }
    : (CAT.chars[0] === "navi"
      ? { label: "NAOTO", primary: "naoto-miyake" }
      : { label: "HARUKA", primary: "haruka-hayashi" });
  const author = findAuthor(ed.primary);
  const Motif = Motifs[deptId] || Motifs.server;

  // 動的 tested: そのカテゴリの記事タイトル「N社比較 / N選」を合算
  const TESTED_COUNT = articles.reduce((sum, a) => {
    const t = (a.title || "") + " " + (a.deck || "");
    const m = t.match(/(\d+)\s*(?:社|選|本|つ|個)/);
    return sum + (m ? parseInt(m[1], 10) : 5);
  }, 0);

  // Pillar — fall back to first 3 articles。 cover image (a.cover) を hero に渡して実機 documentary 写真表示
  const pillar = pillarOverrides || articles.slice(0, 3).map((a, i) => ({
    slug: a.slug, lead: i === 0,
    title: a.title, deck: a.deck,
    cat: i === 0 ? "FEATURE" : a.type === "tutorial" ? "TUTORIAL" : a.type === "review" ? "REVIEW" : "GUIDE",
    page: `p.${a.pageNum || "020"}`, read: `${a.readTime || 10} min`,
    author: a.author, n: String(i + 1).padStart(2, "0"),
    img: a.cover,
    grad: i === 0 ? [CAT.color, CAT.accent, "#0A0A0A"] : i === 1 ? [CAT.accent, CAT.color] : ["#FFB800", "#FF6B2B"],
  }));

  return (
    <div className="mag mag-category" data-dept={deptId}>
      <SharedMasthead section={`DEPARTMENT · ${CAT.en.toUpperCase()}`} />
      <Breadcrumb items={[
        { label: "HOME", href: "cynix-jp.html" },
        { label: CAT.en.toUpperCase() },
      ]} />

      {/* Cover */}
      <section className="cat-cover">
        <div className="cat-cover-text">
          <span className="cat-mark">DEPARTMENT №{String(idx + 1).padStart(2, "0")} · pp.012—055 · {CAT.count} ARTICLES INDEXED</span>
          <h1 className="cat-h">
            {CAT.title.split("・")[0]}、<br />
            <em>その{deptId === "ai" ? "本物" : deptId === "ec" ? "成長曲線" : deptId === "saas" ? "ROI" : deptId === "rsv" ? "現場" : deptId === "domain" ? "信頼" : "実測値"}。</em>
            <span className="en">{CAT.en} · DEPT.{String(idx + 1).padStart(2, "0")}</span>
          </h1>
          <p className="cat-deck">{CAT.deck}</p>
          <div className="cat-bar">
            <div><span className="lab">indexed</span><span className="val">{CAT.count}</span></div>
            <div><span className="lab">target</span><span className="val">{CAT.target}</span></div>
            <div><span className="lab">subcat</span><span className="val">{CAT.subcategories.length}</span></div>
            <div><span className="lab">tested</span><span className="val">{TESTED_COUNT}</span></div>
            <div><span className="lab">editor</span><span className="val" style={{ fontStyle: "italic", fontSize: 14 }}>{ed.label}</span></div>
          </div>
        </div>
        <div className="cat-cover-vis">
          {HERO_PHOTOS[deptId] && (
            <img src={HERO_PHOTOS[deptId]} alt="" loading="lazy" style={{ position: "absolute", inset: 0, width: "100%", height: "100%", objectFit: "cover", zIndex: 0 }} />
          )}
          <div className="cat-cover-vis-glow" style={{ mixBlendMode: "multiply", opacity: 0.55 }}></div>
          <div className="cat-cover-deco" style={{ top: -40, right: -60, zIndex: 3 }}>{deco}</div>
          <div className="cat-cover-stamp" style={{ zIndex: 3 }}>
            DEPT №<br /><span className="big">{String(idx + 1).padStart(2, "0")}</span>{CAT.en}<br />edition
          </div>
          <Motif />
          <div className="cat-cover-pull" style={{ zIndex: 3 }}>
            <q>{quote}</q>
            <div className="cat-cover-pull-attr">— {author.role_jp.toUpperCase()} {author.name_en.toUpperCase()}</div>
          </div>
        </div>
      </section>

      {/* Subcategory grid */}
      <div className="subcat-strip">
        {CAT.subcategories.map((s, i) => (
          <a key={s.id} className="subcat-cell" href={`subcategory-template.html?dept=${CAT.id}&sub=${s.id}`}>
            <span className="subcat-num">№ {String(i + 1).padStart(2, "0")} / {String(CAT.subcategories.length).padStart(2, "0")}</span>
            <h4>{s.title}</h4>
            <p>{s.deck}</p>
            <span className="ct">{s.count || 5} ARTICLES →</span>
          </a>
        ))}
      </div>

      {/* Cross-dept nav */}
      <nav className="deptnav">
        {CATEGORIES_EXT.map((c) => (
          <a key={c.id}
             href={`/category-${c.id === "domain" ? "domain-ssl" : c.id === "ai" ? "ai-tools" : c.id === "rsv" ? "reservation" : c.id}.html`}
             className={c.id === deptId ? "on" : ""}>
            <span className="deptnav-num">DEPT.{String(CATEGORIES_EXT.indexOf(c) + 1).padStart(2, "0")}</span>
            <span className="deptnav-en">{c.en}</span>
            <span className="deptnav-jp">{c.title.split("・")[0]}</span>
          </a>
        ))}
      </nav>

      {/* Pillar */}
      <section className="pillar">
        <div className="pillar-head">
          <h2 className="pillar-h">編集部の<br /><em>本命</em>3本。</h2>
          <div className="pillar-mark">FEATURED · pp.012—030<br />UPDATED 2026/04/25<br />{ed.label}</div>
        </div>
        <div className="pillar-grid">
          {pillar.map((p) => {
            const auth = findAuthor(p.author);
            const fullArticle = articles.find((a) => a.slug === p.slug);
            const href = p.href || (fullArticle
              ? "/" + fullArticle.category + (fullArticle.subcategory ? "/" + fullArticle.subcategory : "") + "/" + fullArticle.slug + "/"
              : "#");
            return (
              <a key={p.slug} className={`pillar-card${p.lead ? " lead" : ""}`} href={href}>
                <div className="pillar-img-svg" style={{ position: "relative", overflow: "hidden", background: `linear-gradient(135deg, ${(p.grad || [CAT.color, CAT.accent]).join(", ")})` }}>
                  {p.img && (
                    <img
                      src={p.img}
                      alt={p.title || ""}
                      loading="lazy"
                      style={{ position: "absolute", inset: 0, width: "100%", height: "100%", objectFit: "cover", zIndex: 0 }}
                    />
                  )}
                  <svg viewBox="0 0 400 250" preserveAspectRatio="xMidYMid slice" style={{ width: "100%", height: "100%", position: "relative", zIndex: 1, mixBlendMode: "multiply", opacity: 0.55 }}>
                    <ellipse cx="200" cy="240" rx="280" ry="100" fill="white" opacity="0.15" />
                    <path d="M -10 130 Q 100 100 200 135 T 410 120" stroke="white" strokeOpacity="0.5" strokeWidth="1.2" fill="none" />
                    <path d="M -10 170 Q 80 190 200 165 T 410 180" stroke={CAT.accent} strokeOpacity="0.7" strokeWidth="1" fill="none" strokeDasharray="2 4" />
                    <text x="360" y={p.lead ? 80 : 70} fontFamily='"Noto Sans JP", serif' fontStyle="italic" fontWeight="900" fontSize={p.lead ? 110 : 80} fill="white" opacity="0.22" textAnchor="end">{p.n}</text>
                  </svg>
                </div>
                <div className="pillar-meta">
                  <span className="cat-tag">{p.cat}</span>
                  <span className="pg">{p.page}</span>
                </div>
                <h3 className="pillar-title">{p.title}</h3>
                <p className="pillar-deck">{p.deck}</p>
                <div className="pillar-foot">
                  <span>By {auth.name_jp}</span>
                  <span>{p.read}</span>
                </div>
              </a>
            );
          })}
        </div>
      </section>

      {/* Article list */}
      <section className="cat-list">
        <div className="cat-list-head">
          <h3>すべての<em>記事</em>。</h3>
          <div className="cat-list-filters">
            <a href="#" className="on">最新</a>
            <a href="#">人気</a>
            <a href="#">編集部選定</a>
            <a href="#">A→Z</a>
          </div>
        </div>
        <div className="cat-list-rows">
          {articles.map((a, i) => {
            const auth = findAuthor(a.author);
            const href = "/" + a.category + (a.subcategory ? "/" + a.subcategory : "") + "/" + a.slug + "/";
            return (
              <a key={a.slug + i} className="cat-list-row" href={href}>
                <span className="row-page">{String(i + 1).padStart(3, "0")}</span>
                <span className="row-cat">{(a.type || "guide").toUpperCase()}</span>
                <span className="row-title">{a.title}</span>
                <span className="row-meta">
                  <span>By {auth.name_jp} · {a.readTime || 10} MIN</span>
                  <span>{a.published}</span>
                </span>
                <span className="row-arrow">→</span>
              </a>
            );
          })}
        </div>
      </section>

      {/* Tag cloud */}
      <section className="tagcloud">
        <h3>関連<em>タグ</em>。</h3>
        <div className="tagcloud-list">
          {ALL_TAGS.filter((t) => !t.parent || t.parent === deptId || (deptId === "server" && ["実機ベンチ", "セルフバック"].includes(t.label))).slice(0, 14).map((t) => (
            <a key={t.slug} href={`tag-page.html?tag=${t.slug}`}>#{t.label} <span className="ct">{t.count}</span></a>
          ))}
        </div>
      </section>

      {/* Newsletter */}
      <section className="cat-news">
        <div>
          <h3>毎週金曜、<br /><em>{CAT.title.split("・")[0]}</em>の本音を。</h3>
          <p style={{ marginTop: 16 }}>編集部 {author.name_jp} が、その週に検証したプロダクトの実測値とサポート応答時間を、生のまま配信。</p>
        </div>
        <form className="cat-news-form" onSubmit={(e) => { e.preventDefault(); const email = (new FormData(e.target).get('email') || '').toString().trim(); if (!email || !email.includes('@')) { alert('メールアドレスを入力してください。'); return; } const s = encodeURIComponent('[cynix.jp] Newsletter Subscribe'); const b = encodeURIComponent('cynix.jp ニュースレター購読のお申し込み Email: ' + email); window.location.href = 'mailto:cynix@jpsm.ne.jp?subject=' + s + '&body=' + b; }}>
          <input type="email" name="email" placeholder="your@email.com" />
          <button type="submit">SUBSCRIBE</button>
        </form>
      </section>

      <Colophon />
    </div>
  );
};

window.cynixCategoryPage = CategoryPage;
