// tomugi-series.jsx — series detail page focused on organizing volumes

// One color PER SERIES for the generic volume books. Prefer the AniList cover's
// dominant color so the book matches the real cover; fall back to a stable
// generated mid-tone when AniList didn't provide one.
function seriesBookTint(series) {
  let base;
  if (series && series.coverColor) {
    base = series.coverColor;
  } else {
    const s = String((series && (series.id || series.title)) || "");
    let h = 0;
    for (let i = 0; i < s.length; i++) h = (h * 31 + s.charCodeAt(i)) % 360;
    base = `hsl(${h} 42% 40%)`;
  }
  // Mute toward the dark theme so the little books don't grab all the attention.
  return `color-mix(in srgb, ${base} 55%, #1c1f27)`;
}

function SeriesPage({ series, onBack, onOpen, onGenre, showTexture = true }) {
  const { useState } = React;
  const { buildVolumes, recommendSeries } = window.TomugiUtils;
  const volumes = buildVolumes(series);
  const recommendations = onOpen ? recommendSeries(series, window.TOMUGI_SERIES, 6) : [];
  const [openVolumes, setOpenVolumes] = useState(() => new Set());
  const [organized, setOrganized] = useState(() => new Set(volumes.filter((v) => v.organized).map((v) => v.n)));
  const [modalTarget, setModalTarget] = useState(null);
  const [noticeOpen, setNoticeOpen] = useState(false);
  const [descOpen, setDescOpen] = useState(false);

  // Group volumes into drawers of GROUP_SIZE. The last drawer absorbs a small
  // remainder instead of leaving a tiny trailing group (e.g. 32 -> 10, 10, 12).
  const GROUP_SIZE = 10;
  const groups = [];
  for (let i = 0; i < volumes.length; i += GROUP_SIZE) groups.push(volumes.slice(i, i + GROUP_SIZE));
  if (groups.length > 1 && groups[groups.length - 1].length < GROUP_SIZE / 2) {
    const tail = groups.pop();
    groups[groups.length - 1] = groups[groups.length - 1].concat(tail);
  }
  const grouped = groups.length > 1;
  const [openGroups, setOpenGroups] = useState(() => grouped ? new Set([0]) : new Set());
  function toggleGroup(i) {
    setOpenGroups((prev) => {
      const next = new Set(prev);
      if (next.has(i)) next.delete(i); else next.add(i);
      return next;
    });
  }

  function toggleVolume(n) {
    setOpenVolumes((prev) => {
      const next = new Set(prev);
      if (next.has(n)) next.delete(n); else next.add(n);
      return next;
    });
  }

  function openOrganizer(target) {
    // Device/browser gate temporarily disabled for testing the organizer.
    setModalTarget(target);
  }

  function markOrganized(target) {
    setModalTarget(null);
    setOrganized((prev) => {
      if (target.kind === "all") return new Set(volumes.map((v) => v.n));
      const next = new Set(prev);
      next.add(target.volume.n);
      return next;
    });
  }

  const organizedCount = organized.size;
  const pendingCount = Math.max(0, volumes.length - organizedCount);
  const modalTitle = modalTarget?.kind === "volume"
    ? `${series.title} · Vol. ${String(modalTarget.volume.n).padStart(2, "0")}`
    : series.title;
  const modalChaps = modalTarget?.kind === "volume" ? modalTarget.volume.count : series.chaps;
  const modalPerVolume = modalTarget?.kind === "volume"
    ? modalTarget.volume.count
    : Math.ceil(series.chaps / series.vols);

  const renderVolume = (v) => {
    const done = organized.has(v.n);
    const isOpen = openVolumes.has(v.n);
    const items = v.chapters.length
      ? v.chapters.map((c) => ({ key: `ch-${c.num}`, label: `Chapter ${c.num}`, file: `Ch_${String(c.num).padStart(3, "0")}.cbz` }))
      : (v.files.length
        ? v.files.map((file, index) => ({ key: `file-${index}`, label: file, file: "ready" }))
        : [{ key: "volume", label: `Volume ${v.n}`, file: done ? "organized" : "pending" }]);
    return (
      <div className={`vrow ${isOpen ? "is-open" : ""} ${v.n % 2 === 0 ? "vrow-alt" : ""}`} key={v.n}>
        <div
          className="vrow-head"
          role="button"
          tabIndex={0}
          onClick={() => toggleVolume(v.n)}
          onKeyDown={(e) => {
            if (e.key === "Enter" || e.key === " ") {
              e.preventDefault();
              toggleVolume(v.n);
            }
          }}
        >
          <div className="vthumb"><Cover s={{ ...series, tint: seriesBookTint(series) }} idx={v.n} size="md" showTexture={true} generic /></div>
          <div className="vrow-info">
            <div className="vrow-title mono">VOL.{String(v.n).padStart(2, "0")}</div>
            <div className="vrow-range mono">Ch. {v.start}–{v.end} · {v.count} chapters</div>
          </div>
          <div className="vrow-right">
            {done && <span className="vrow-badge mono is-done">✓ Organized</span>}
            <span className={`chev ${isOpen ? "up" : ""}`} aria-hidden="true">⌄</span>
          </div>
        </div>
        {isOpen && (
          <div className="vrow-chaps">
            {items.map((item) => (
              <div
                key={item.key}
                className="ch-cell file-cell"
                title={`${item.label} belongs to Vol. ${String(v.n).padStart(2, "0")}`}
              >
                <span className="ch-dot file-dot" aria-hidden="true"></span>
                <span className="ch-num">{item.label}</span>
                <span className="ch-file mono">{item.file}</span>
              </div>
            ))}
          </div>
        )}
      </div>
    );
  };

  const pad = (n) => String(n).padStart(2, "0");

  return (
    <div className="series-page">
      <div className="series-grid">
        {/* left: cover + meta */}
        <aside className="series-aside">
          <div className="crumb sticky-crumb mono"><button className="crumb-link" onClick={onBack}><span aria-hidden="true">←</span> Catalog</button></div>
          <div className="series-cover">
            <Cover s={series} idx={3} size="md" />
            {series.status && <span className={`cover-status mono ${series.status === "Completed" ? "is-done" : "is-ongoing"}`}>{series.status}</span>}
          </div>
          <div className="series-meta">
            <h1 className="series-title">{series.title}</h1>
            <div className="series-author">by {series.author}</div>
            <div className="meta-pills mono">
              <span className="pill">{series.vols} volumes</span>
              <span className="pill">{series.chaps} chapters</span>
            </div>
            {series.genres && series.genres.length > 0 && (
              <div className="meta-genres">
                {series.genres.map((g) => (
                  <button className="genre-tag mono" key={g} onClick={() => onGenre && onGenre(g)} title={`See ${g} series`}>{g}</button>
                ))}
              </div>
            )}
            {series.description && (
              <React.Fragment>
                <p className={`series-desc ${descOpen ? "is-open" : ""}`}>{series.description}</p>
                <button className="desc-toggle mono" onClick={(e) => {
                  const willOpen = !descOpen;
                  const btn = e.currentTarget;
                  setDescOpen(willOpen);
                  if (willOpen) setTimeout(() => {
                    const aside = btn.closest(".series-aside");
                    if (aside && aside.scrollHeight > aside.clientHeight + 4) {
                      aside.scrollTo({ top: aside.scrollHeight, behavior: "smooth" });
                    } else if (aside) {
                      aside.scrollIntoView({ behavior: "smooth", block: "end" });
                    }
                  }, 40);
                }}>{descOpen ? "Show less" : "Show more"}</button>
              </React.Fragment>
            )}
          </div>
          <button className="btn btn-accent btn-block organize-auto" onClick={() => openOrganizer({ kind: "all" })}><span className="oa-label">Organize automatically</span><span className="pro-crown" aria-hidden="true">👑</span></button>
        </aside>

        {/* right: volumes */}
        <main className="series-main">
          <div className="vols-head">
            <div>
              <h2 className="vols-h2">Volumes</h2>
              <span className="vols-count mono">{series.vols} volumes · {series.chaps} chapters</span>
            </div>
          </div>
          <div className="vols-list">
            {grouped
              ? groups.map((g, gi) => {
                  const gOpen = openGroups.has(gi);
                  return (
                    <div className={`vgroup ${gOpen ? "is-open" : ""}`} key={gi}>
                      <div
                        className="vgroup-head"
                        role="button"
                        tabIndex={0}
                        onClick={() => toggleGroup(gi)}
                        onKeyDown={(e) => {
                          if (e.key === "Enter" || e.key === " ") { e.preventDefault(); toggleGroup(gi); }
                        }}
                      >
                        <span className="vgroup-title mono">Vol. {pad(g[0].n)}–{pad(g[g.length - 1].n)}</span>
                        <span className="vgroup-meta mono">{g.length} volumes</span>
                        <span className={`chev ${gOpen ? "up" : ""}`} aria-hidden="true">⌄</span>
                      </div>
                      {gOpen && <div className="vgroup-body">{g.map(renderVolume)}</div>}
                    </div>
                  );
                })
              : volumes.map(renderVolume)}
          </div>
        </main>
      </div>

      {recommendations.length > 0 && (
        <section className="series-recs">
          <div className="vols-head">
            <div>
              <h2 className="vols-h2">You might also like</h2>
              <span className="vols-count mono">Based on {series.title}</span>
            </div>
          </div>
          <CatalogGrid series={recommendations} showTexture={showTexture} onOpen={onOpen} />
        </section>
      )}

      {/* small screens: folder-style action that slides up from the bottom */}
      <button className="organize-auto-mobile mono" onClick={() => openOrganizer({ kind: "all" })}>
        <span aria-hidden="true">📁</span> Organize automatically
      </button>

      <OrganizeModal
        open={!!modalTarget}
        series={series}
        seriesTitle={series.title}
        onClose={() => setModalTarget(null)}
      />

      {noticeOpen && (
        <div className="modal-overlay" onClick={() => setNoticeOpen(false)}>
          <div className="modal notice-modal" onClick={(e) => e.stopPropagation()}>
            <div className="notice-body">
              <div className="notice-icon" aria-hidden="true">🖥️</div>
              <h3 className="notice-title">Not available on this device</h3>
              <p className="notice-text">Automatic organizing isn't supported on phones or tablets yet. Please open tomugi on a computer (laptop or desktop) using <b>Google Chrome</b> or <b>Microsoft Edge</b> to organize your collection.</p>
              <button className="btn btn-accent btn-block" onClick={() => setNoticeOpen(false)}>Got it</button>
            </div>
          </div>
        </div>
      )}
    </div>
  );
}

Object.assign(window, { SeriesPage });
