// ui_kits/portfolio/screens.jsx
// Archive, Post, About, NotFound — mobile-aware, animated.

const { useState: useStateS, useMemo: useMemoS, useEffect: useEffectS, useRef: useRefS } = React;

// ============================================================
// ARCHIVE
// ============================================================
function Archive({ lang, go }) {
  const t = useT(lang);
  const activePosts = useMemoS(() => POSTS.filter(p => !p.archived), []);
  const archivedPosts = useMemoS(() => POSTS.filter(p => p.archived), []);

  const allTags = useMemoS(() => {
    const s = new Set();
    activePosts.forEach(p => { p.tags.forEach(tag => s.add(tag)); s.add(p.category); });
    return ["all", ...Array.from(s).sort()];
  }, [activePosts]);
  const [activeTag, setActiveTag] = useStateS("all");
  const [sort, setSort] = useStateS("newest");
  const [q, setQ] = useStateS("");
  const [archiveOpen, setArchiveOpen] = useStateS(false);

  const filtered = useMemoS(() => {
    let list = activePosts.slice();
    if (activeTag !== "all") {
      list = list.filter(p => p.tags.includes(activeTag) || p.category === activeTag);
    }
    if (q.trim()) {
      const ql = q.toLowerCase();
      list = list.filter(p => tx(p.title, lang).toLowerCase().includes(ql) || tx(p.excerpt, lang).toLowerCase().includes(ql));
    }
    if (sort === "newest") list.sort((a, b) => b.date.localeCompare(a.date));
    if (sort === "oldest") list.sort((a, b) => a.date.localeCompare(b.date));
    if (sort === "title")  list.sort((a, b) => tx(a.title, lang).localeCompare(tx(b.title, lang)));
    return list;
  }, [activePosts, activeTag, sort, q, lang]);

  return (
    <div className="page page-archive">
      <header className="page__head">
        <div className="page__head-left">
          <div className="kicker">002 / ARCHIVE</div>
          <h1 className="page__h1">{t.archive.title}</h1>
          <p className="page__sub">{t.archive.sub}</p>
        </div>
        <div className="page__head-right">
          <div className="search-wrap">
            <span className="search-slash">/</span>
            <input className="input search-input" placeholder={lang === "es" ? "buscar..." : "search..."} value={q} onChange={(e) => setQ(e.target.value)} />
          </div>
          <div className="archive-count">{t.archive.count(filtered.length)}</div>
        </div>
      </header>

      <div className="archive-controls">
        <div className="archive-controls__block">
          <div className="control-lbl">{t.archive.filterLabel}</div>
          <div className="tags-row">
            {allTags.map(tag => (
              <button key={tag} data-cursor="filter"
                      onClick={() => setActiveTag(tag)}
                      className={"tag" + (activeTag === tag ? " is-active" : "")}>
                {tag === "all" ? t.archive.all : tag}
              </button>
            ))}
          </div>
        </div>
        <div className="archive-controls__block archive-controls__block--right">
          <div className="control-lbl">{t.archive.sortLabel}</div>
          <select className="input sort-select" value={sort} onChange={(e) => setSort(e.target.value)}>
            <option value="newest">{t.archive.sorts.newest}</option>
            <option value="oldest">{t.archive.sorts.oldest}</option>
            <option value="title">{t.archive.sorts.title}</option>
          </select>
        </div>
      </div>

      {filtered.length === 0 ? (
        <div className="archive-empty">{t.archive.empty}</div>
      ) : (
        <ul className="archive-list">
          {filtered.map((p, i) => (
            <Reveal key={p.id} as="li" delay={i * 50} y={10}>
              <a href="#" data-cursor={t.home.readMore} onClick={(e) => { e.preventDefault(); go("post", { slug: p.slug }); }}
                 className="archive-row">
                <div className="archive-row__num">{String(i + 1).padStart(3, "0")}</div>
                <div className="archive-row__date">{formatDate(p.date, lang)}</div>
                <div className="archive-row__title feat-title">{tx(p.title, lang)}</div>
                <div className="archive-row__tags">
                  {p.tags.slice(0, 3).map(tg => <span key={tg} className="archive-row__tag">#{tg}</span>)}
                </div>
                <div className="archive-row__arrow arrow">→</div>
              </a>
            </Reveal>
          ))}
        </ul>
      )}

      {/* Archived game design work */}
      <div className="archive-vault">
        <button className="archive-vault__toggle" data-cursor="open" onClick={() => setArchiveOpen(v => !v)}>
          <span className="control-lbl">{lang === "es" ? "003 / TRABAJOS ARCHIVADOS" : "003 / ARCHIVED WORK"}</span>
          <span className="archive-vault__count">
            {archivedPosts.length} {lang === "es" ? "entradas" : "entries"}
          </span>
          <span className="archive-vault__chevron">{archiveOpen ? "↑" : "↓"}</span>
        </button>
        {archiveOpen && (
          <ul className="archive-list archive-list--vault">
            {archivedPosts.map((p, i) => (
              <Reveal key={p.id} as="li" delay={i * 40} y={8}>
                <a href="#" data-cursor={t.home.readMore} onClick={(e) => { e.preventDefault(); go("post", { slug: p.slug }); }}
                   className="archive-row archive-row--vault">
                  <div className="archive-row__num">{String(i + 1).padStart(3, "0")}</div>
                  <div className="archive-row__date">{formatDate(p.date, lang)}</div>
                  <div className="archive-row__title feat-title">{tx(p.title, lang)}</div>
                  <div className="archive-row__tags">
                    {p.tags.slice(0, 3).map(tg => <span key={tg} className="archive-row__tag">#{tg}</span>)}
                  </div>
                  <div className="archive-row__arrow arrow">→</div>
                </a>
              </Reveal>
            ))}
          </ul>
        )}
      </div>
    </div>
  );
}

// ============================================================
// POST — single article view
// ============================================================
function Post({ lang, go, slug }) {
  const t = useT(lang);
  const post = POSTS.find(p => p.slug === slug) || POSTS[0];
  const index = POSTS.findIndex(p => p.slug === post.slug);
  const prev = POSTS[(index - 1 + POSTS.length) % POSTS.length];
  const next = POSTS[(index + 1) % POSTS.length];

  return (
    <article className="page page-post">
      <Reveal>
        <header className="post__head">
          <div className="post__kicker">
            <a href="#" data-cursor="archive" onClick={(e) => { e.preventDefault(); go("archive"); }} style={{ color: "var(--fg-2)" }}>← {t.nav.archive}</a>
            <span>{formatDate(post.date, lang)}</span>
            <span style={{ color: "var(--accent)" }}>{post.category.toUpperCase()}</span>
            <span>· {post.readTime} {lang === "es" ? "MIN" : "MIN READ"}</span>
          </div>
          <h1 className="post__title">{tx(post.title, lang)}</h1>
          <div className="post__tags">
            {post.tags.map(tg => <span key={tg} className="tag">{tg}</span>)}
          </div>
        </header>
      </Reveal>

      {post.cover && (
        <Reveal delay={120}>
          <div className="post__cover">
            <img src={post.cover} alt="" />
          </div>
        </Reveal>
      )}

      <Reveal delay={180}>
        <div className="post__body">
          <p className="post__lead">{tx(post.excerpt, lang)}</p>
          {post.body
            ? <div className="post__md" dangerouslySetInnerHTML={{ __html: marked.parse(post.body) }} />
            : <p style={{ color: "var(--fg-3)", fontStyle: "italic" }}>
                {lang === "es" ? "Contenido próximamente." : "Content coming soon."}
              </p>
          }
        </div>
      </Reveal>

      <nav className="post__nav">
        <a href="#" data-cursor={lang === "es" ? "anterior" : "previous"} onClick={(e) => { e.preventDefault(); go("post", { slug: prev.slug }); }} className="post__nav-link">
          <span className="post__nav-lbl">← {lang === "es" ? "ANTERIOR" : "PREVIOUS"}</span>
          <span className="post__nav-title">{tx(prev.title, lang)}</span>
        </a>
        <a href="#" data-cursor={lang === "es" ? "siguiente" : "next"} onClick={(e) => { e.preventDefault(); go("post", { slug: next.slug }); }} className="post__nav-link post__nav-link--right">
          <span className="post__nav-lbl">{lang === "es" ? "SIGUIENTE" : "NEXT"} →</span>
          <span className="post__nav-title">{tx(next.title, lang)}</span>
        </a>
      </nav>
    </article>
  );
}

// ============================================================
// PortraitFrame — interactive cell behind the photo.
// Pixel grid that warps toward the cursor + scanline + soft glass blob.
// ============================================================
function PortraitFrame() {
  const wrap = useRefS(null);
  const grid = useRefS(null);

  const noise = useMemoS(() => {
    // build a fine pixel grid as a single repeating-conic via canvas — but a CSS grid is cheaper.
    const cells = [];
    const COLS = 14, ROWS = 18;
    for (let r = 0; r < ROWS; r++) {
      for (let c = 0; c < COLS; c++) {
        cells.push({ r, c, COLS, ROWS, on: ((r * 7 + c * 3) % 11) < 3 });
      }
    }
    return cells;
  }, []);

  useEffectS(() => {
    let raf = 0;
    let mx = 0.5, my = 0.5; // 0..1
    const onMove = (e) => {
      if (!wrap.current) return;
      const r = wrap.current.getBoundingClientRect();
      mx = Math.max(0, Math.min(1, (e.clientX - r.left) / r.width));
      my = Math.max(0, Math.min(1, (e.clientY - r.top) / r.height));
    };
    const tick = () => {
      if (grid.current) {
        grid.current.style.setProperty("--mx", mx);
        grid.current.style.setProperty("--my", my);
      }
      raf = requestAnimationFrame(tick);
    };
    window.addEventListener("mousemove", onMove);
    tick();
    return () => { window.removeEventListener("mousemove", onMove); cancelAnimationFrame(raf); };
  }, []);

  return (
    <div className="portrait" ref={wrap}>
      {/* Pixel grid */}
      <div className="portrait__grid" ref={grid}>
        {noise.map((cell, i) => {
          const cx = (cell.c + 0.5) / cell.COLS;
          const cy = (cell.r + 0.5) / cell.ROWS;
          return (
            <span key={i} className={"portrait__cell" + (cell.on ? " is-on" : "")}
                  style={{
                    gridColumn: cell.c + 1,
                    gridRow: cell.r + 1,
                    "--cx": cx,
                    "--cy": cy,
                  }} />
          );
        })}
      </div>

      {/* Scanlines */}
      <div className="portrait__scan" aria-hidden="true" />
      {/* The photo */}
      <img className="portrait__img" src="assets/images/FotoPerfil.jpg" alt="Eduardo López" />
      {/* Corner labels */}
      <div className="portrait__corner portrait__corner--tl">SUBJECT_001</div>
      <div className="portrait__corner portrait__corner--tr">MADRID, ES</div>

      <div className="portrait__corner portrait__corner--br">2024 · EL</div>
    </div>
  );
}

// ============================================================
// ABOUT
// ============================================================
function About({ lang, go }) {
  const t = useT(lang);
  return (
    <div className="page page-about">
      <header className="about__head">
        <div className="kicker">{t.about.kicker}</div>
        <h1 className="page__h1">{t.about.title}</h1>
        <p className="about__lead">{t.about.lead}</p>
      </header>

      <section className="about__grid">
        <Reveal>
          <div className="about__photo-wrap">
            <PortraitFrame />
            <div className="about__photo-cap">FOTO · MADRID 2024</div>
          </div>
        </Reveal>
        <Reveal delay={120}>
          <div className="about__bio">
            {t.about.bio.map((para, i) => (
              <p key={i} className="about__para">{para}</p>
            ))}
          </div>
        </Reveal>
      </section>

      <Reveal>
        <section className="about__stack">
          <header className="about__sub-head">
            <div className="sub-kicker">{t.about.stackLabel}</div>
            <h2 className="page__h2">{lang === "es" ? "Lo que uso" : "What I use"}</h2>
          </header>
          <ul className="stack-list">
            {t.about.stack.map((row, i) => (
              <li key={i} className="stack-row">
                <span className="stack-row__k">{String(i + 1).padStart(2, "0")} · {row.k}</span>
                <span className="stack-row__v">{row.v}</span>
              </li>
            ))}
          </ul>
        </section>
      </Reveal>

      <Reveal>
        <section className="about__links">
          <div className="sub-kicker">{t.about.linksLabel}</div>
          <ul className="links-list">
            {t.about.links.map((l, i) => (
              <li key={i} className="links-row">
                <span className="links-row__k">{l.k}</span>
                <a className="links-row__v" data-cursor="open" href={l.href} target="_blank" rel="noreferrer">{l.v} ↗</a>
              </li>
            ))}
          </ul>
        </section>
      </Reveal>

      <Reveal>
        <section className="about__contact">
          <div className="sub-kicker">{t.about.contactLabel}</div>
          <a href={`mailto:${t.about.contact}`} data-cursor="email" className="about__email glitch" data-text={t.about.contact}>{t.about.contact} →</a>
        </section>
      </Reveal>
    </div>
  );
}

// ============================================================
// NOT FOUND
// ============================================================
function NotFound({ lang, go }) {
  const t = useT(lang);
  return (
    <div className="page page-404">
      <div className="nf__code glitch" data-text="404">404</div>
      <div className="nf__lines">
        <div className="nf__line1">{t.notFound.line1}</div>
        <div className="nf__line2">{t.notFound.line2}</div>
      </div>
      <a href="#" data-cursor="home" onClick={(e) => { e.preventDefault(); go("home"); }} className="btn btn--accent nf__back">{t.notFound.back}</a>
    </div>
  );
}

Object.assign(window, { Archive, Post, About, NotFound, PortraitFrame });
