// app.jsx — shell, tabs, gallery
const { useState: useStateA, useEffect: useEffectA, useRef: useRefA } = React;

/* ============================================================ */

function Header({ tab, setTab }) {
  return (
    <header>
      <div className="topbar">
        <a className="brand" href="https://playoxide.com/" target="_blank" rel="noopener noreferrer" title="Official Oxide site">
          <div className="brand-mark">
            <img src="assets/logo.png" alt="Oxide" />
          </div>
          <div className="brand-title">
            <span className="lockup"><span className="sub">WALLPAPERS</span></span>
          </div>
        </a>
        <div className="topbar-right">
          <a className="ext-link" href="https://playoxide.com/" target="_blank" rel="noopener noreferrer">
            OFFICIAL SITE
            <ExtIcon />
          </a>
          <a className="ext-link" href="https://creators.playoxide.com/" target="_blank" rel="noopener noreferrer">
            FOR CREATORS
            <ExtIcon />
          </a>
        </div>
      </div>

      <nav className="tabs">
        <button className={"tab " + (tab === "wallpapers" ? "active" : "")} onClick={() => setTab("wallpapers")}>
          <span className="num">01</span>WALLPAPERS
        </button>
        <button className={"tab " + (tab === "stickers" ? "active" : "")} onClick={() => setTab("stickers")}>
          <span className="num">02</span>STICKERS
        </button>
        <button className={"tab " + (tab === "constructor" ? "active" : "")} onClick={() => setTab("constructor")}>
          <span className="num">03</span>TEAM CONSTRUCTOR
        </button>
      </nav>
    </header>
  );
}

function ExtIcon() {
  return (
    <svg viewBox="0 0 12 12" fill="none" stroke="currentColor" strokeWidth="1.4" aria-hidden="true">
      <path d="M4.5 2.5H2.5v7h7v-2M7 2.5h2.5V5M9.5 2.5L5 7" />
    </svg>
  );
}

function Footer() {
  return (
    <footer className="foot">
      <div className="foot-left">
        <a className="brand-mark foot-mark" href="https://playoxide.com/" target="_blank" rel="noopener noreferrer" title="Official Oxide site">
          <img src="assets/logo.png" alt="Oxide" />
        </a>
        <span>WALLPAPERS · FAN HUB</span>
      </div>
      <div className="foot-links">
        <a href="https://playoxide.com/" target="_blank" rel="noopener noreferrer">OFFICIAL SITE <ExtIcon /></a>
        <a href="https://creators.playoxide.com/" target="_blank" rel="noopener noreferrer">FOR CREATORS <ExtIcon /></a>
      </div>
    </footer>
  );
}

function DownloadIcon() {
  return (
    <svg viewBox="0 0 12 12" fill="none" stroke="currentColor" strokeWidth="1.6">
      <path d="M6 1v8M2 6l4 4 4-4M1 11h10" />
    </svg>
  );
}

function MagnifyIcon() {
  return (
    <svg viewBox="0 0 16 16" fill="none" stroke="currentColor" strokeWidth="1.6">
      <circle cx="7" cy="7" r="4.5" />
      <path d="M10.5 10.5L14 14M5.5 7h3M7 5.5v3" />
    </svg>
  );
}

/* ===== Shared Lightbox ===== */
function Lightbox({ data, onClose }) {
  const canvasRef = useRefA(null);
  const [zoomed, setZoomed] = useStateA(false);
  const [pdfStatus, setPdfStatus] = useStateA("loading");

  useEffectA(() => {
    function onKey(e) { if (e.key === "Escape") onClose(); }
    window.addEventListener("keydown", onKey);
    return () => window.removeEventListener("keydown", onKey);
  }, [onClose]);

  useEffectA(() => { setZoomed(false); setPdfStatus("loading"); }, [data]);

  useEffectA(() => {
    if (!data || data.kind !== "pdf") return;
    let cancelled = false;
    (async () => {
      if (!window.pdfjsLib) { setPdfStatus("error"); return; }
      try {
        const pdf = await window.pdfjsLib.getDocument(data.file).promise;
        const page = await pdf.getPage(1);
        const vp1 = page.getViewport({ scale: 1 });
        const targetW = Math.min(1600, vp1.width * 2.2);
        const scale = targetW / vp1.width;
        const vp = page.getViewport({ scale });
        const c = canvasRef.current;
        if (!c || cancelled) return;
        c.width = vp.width;
        c.height = vp.height;
        await page.render({ canvasContext: c.getContext("2d"), viewport: vp }).promise;
        if (!cancelled) setPdfStatus("ok");
      } catch (e) {
        if (!cancelled) setPdfStatus("error");
      }
    })();
    return () => { cancelled = true; };
  }, [data]);

  if (!data) return null;

  const download = (e) => {
    e.stopPropagation();
    const a = document.createElement("a");
    a.href = data.downloadHref;
    a.download = data.downloadName || data.downloadHref.split("/").pop();
    a.click();
  };

  return (
    <div className="lb-backdrop" onClick={onClose}>
      <div className="lb-bar" onClick={(e) => e.stopPropagation()}>
        <span className="lb-title mono">{data.label}<span className="lb-name">{data.title}</span></span>
        <div className="lb-actions">
          <button className="lb-btn" onClick={download}>
            <DownloadIcon /><span>Download</span>
          </button>
          <button className="lb-close" onClick={onClose} aria-label="Close">×</button>
        </div>
      </div>

      <div className="lb-stage" onClick={(e) => e.stopPropagation()}>
        {data.kind === "image" ? (
          <img
            className={"lb-img " + (zoomed ? "zoomed" : "")}
            src={data.src}
            alt={data.title}
            onClick={() => setZoomed((z) => !z)}
          />
        ) : (
          <div className="lb-pdf-wrap">
            <canvas
              className={"lb-canvas " + (zoomed ? "zoomed" : "")}
              ref={canvasRef}
              onClick={() => setZoomed((z) => !z)}
              style={{ display: pdfStatus === "ok" ? "block" : "none" }}
            ></canvas>
            {pdfStatus === "loading" && <span className="spinner lb-spin"></span>}
            {pdfStatus === "error" && <div className="lb-pdf-err">Preview unavailable — use Download.</div>}
          </div>
        )}
      </div>
      {data.kind === "image" && (
        <div className="lb-hint mono">{zoomed ? "Click to fit" : "Click image to zoom"}</div>
      )}
    </div>
  );
}

function WallpaperCard({ item }) {
  const ext = item.src.split(".").pop();
  const dlName = `wp-${item.type}-${item.title}-${item.w}x${item.h}.${ext}`;

  const handleDownload = (e) => {
    e.stopPropagation();
    const a = document.createElement("a");
    a.href = item.src;
    a.download = dlName;
    a.click();
  };

  const openZoom = (e) => {
    e.stopPropagation();
    window.openLightbox({
      kind: "image",
      src: item.src,
      label: item.type === "mobile" ? "MOBILE / " : "DESKTOP / ",
      title: item.title,
      downloadHref: item.src,
      downloadName: dlName,
    });
  };

  return (
    <div className="card">
      <div className="thumb-wrap zoomable" onClick={openZoom}>
        {item.isNew && <span className="badge-new">NEW</span>}
        <img className="thumb" src={item.src} alt={item.title} loading="lazy" />
        <button className="zoom-btn" onClick={openZoom} aria-label="Zoom in">
          <MagnifyIcon />
        </button>
        <div className="card-actions">
          <button className="dl-btn" onClick={handleDownload} aria-label="Download">
            <DownloadIcon />
            <span className="dl-label">Download</span>
          </button>
        </div>
      </div>
      <div className="card-meta">
        <span className="card-title">
          <span className="num mono">{item.title}</span>
        </span>
        <span className="card-res">{item.res}</span>
      </div>
    </div>
  );
}

function Gallery() {
  const [filter, setFilter] = useStateA("desktop");

  const all = window.WALLPAPERS;
  const desktopCount = all.filter((w) => w.type === "desktop").length;
  const mobileCount = all.filter((w) => w.type === "mobile").length;
  const filtered = all.filter((w) => w.type === filter);

  return (
    <div>
      <div className="page-head">
        <div>
          <h1>WALLPAPERS <span className="h1-accent">/</span> GALLERY</h1>
        </div>
        <p>Official Oxide wallpaper collection. From the latest drops to classics. Free for all players.</p>
      </div>

      <div className="filterbar">
        <span className="label">PLATFORM</span>
        <button className={"chip " + (filter === "desktop" ? "active" : "")} onClick={() => setFilter("desktop")}>
          DESKTOP <span className="count">[{desktopCount}]</span>
        </button>
        <button className={"chip " + (filter === "mobile" ? "active" : "")} onClick={() => setFilter("mobile")}>
          MOBILE <span className="count">[{mobileCount}]</span>
        </button>
        <div className="spacer"></div>
      </div>

      <div className={"grid " + filter}>
        {filtered.map((w) => (
          <WallpaperCard key={w.id} item={w} />
        ))}
      </div>
    </div>
  );
}

function App() {
  const [tab, setTab] = useStateA("wallpapers");
  const [lb, setLb] = useStateA(null);

  useEffectA(() => {
    window.openLightbox = setLb;
    return () => { delete window.openLightbox; };
  }, []);

  return (
    <div className="shell">
      <Header tab={tab} setTab={setTab} />
      <main>
        {tab === "wallpapers" && <Gallery />}
        {tab === "stickers" && <Stickers />}
        {tab === "constructor" && <Constructor />}
      </main>
      <Footer />
      <Lightbox data={lb} onClose={() => setLb(null)} />
    </div>
  );
}

const root = ReactDOM.createRoot(document.getElementById("root"));
root.render(<App />);
