"use client";

import { useRef, useState } from "react";
import { DEVICE_TARGETS, HERO_TARGETS, type DeviceTarget } from "./devices";
import { SCREENS, type ScreenSpec } from "./screens";
import { MarketingTile } from "./marketing-tile";
import type { ScreenshotTheme } from "./device-mock";
import { exportTileJpeg } from "./export";

// App Store / Play Store marketing screenshot generator (dev-only).
//
// Renders one framed marketing tile per (screen × device) at the device's EXACT
// export pixel size, previewed shrunk. "Download JPEG" captures a tile 1:1 →
// pixel-exact file. This whole route is excluded from prod/native builds via the
// `page.screenshot.tsx` page extension (see next.config.ts) — 0 bytes shipped.

// On-screen preview height (px) — the tile is captured at full size regardless.
const PREVIEW_H = 460;

export default function ScreenshotsPage() {
  const [screenId, setScreenId] = useState<string>(SCREENS[0].id);
  const [busy, setBusy] = useState(false);
  const [mode, setMode] = useState<ScreenshotTheme>("dark");

  const screen = SCREENS.find((s) => s.id === screenId) ?? SCREENS[0];
  // The hero screen is a single composite tile; tablet-only screens hide the
  // phone targets; everything else uses the full per-device grid.
  const targets = screen.hero
    ? HERO_TARGETS
    : DEVICE_TARGETS.filter((t) => !screen.padOnly || t.deviceClass === "pad");

  return (
    <div className="scrollbar-none min-h-0 flex-1 overflow-y-auto px-6 py-8">
      <div className="mx-auto w-full max-w-7xl space-y-8">
        <header className="space-y-3">
          <h1 className="heading-large">App Store screenshots</h1>
          <p className="body-normal text-foreground-muted">
            Framed marketing tiles at exact store resolutions. Pick a screen, then
            download each device tile as a pixel-exact JPEG.
          </p>
          <div className="flex flex-wrap items-center gap-3">
            <div className="inline-flex flex-wrap rounded-full border border-surface-stroke p-0.5">
              {SCREENS.map((s) => (
                <button
                  key={s.id}
                  type="button"
                  onClick={() => setScreenId(s.id)}
                  aria-pressed={s.id === screenId}
                  className={`clickable-small rounded-full px-3.5 py-1.5 transition-colors ${
                    s.id === screenId
                      ? "bg-foreground-red-orange text-white"
                      : "text-foreground-muted hover:bg-surface-base-muted"
                  }`}
                >
                  {s.category}
                </button>
              ))}
            </div>
            {/* Dark / light theme toggle — swaps the app theme + tile chrome. */}
            <div className="inline-flex rounded-full border border-surface-stroke p-0.5">
              {(["dark", "light"] as const).map((m) => (
                <button
                  key={m}
                  type="button"
                  onClick={() => setMode(m)}
                  aria-pressed={mode === m}
                  className={`clickable-small rounded-full px-3.5 py-1.5 capitalize transition-colors ${
                    mode === m
                      ? "bg-surface-base-muted text-foreground-default"
                      : "text-foreground-muted hover:bg-surface-base-muted"
                  }`}
                >
                  {m}
                </button>
              ))}
            </div>
            <DownloadAllButton
              screen={screen}
              mode={mode}
              busy={busy}
              setBusy={setBusy}
            />
          </div>
        </header>

        <div className="flex flex-wrap items-start gap-8">
          {targets.map((target) => (
            <TilePreview
              key={target.id}
              screen={screen}
              target={target}
              mode={mode}
            />
          ))}
        </div>
      </div>
    </div>
  );
}

function TilePreview({
  screen,
  target,
  mode,
}: {
  screen: ScreenSpec;
  target: DeviceTarget;
  mode: ScreenshotTheme;
}) {
  const ref = useRef<HTMLDivElement>(null);
  const [downloading, setDownloading] = useState(false);
  const scale = PREVIEW_H / target.exportH;

  async function download() {
    if (!ref.current) return;
    setDownloading(true);
    try {
      await exportTileJpeg(ref.current, {
        width: target.exportW,
        height: target.exportH,
        fileName: `${screen.id}-${target.id}-${mode}-${target.exportW}x${target.exportH}.jpg`,
        backgroundColor: mode === "light" ? "#ffffff" : undefined,
      });
    } catch (err) {
      console.error("Screenshot export failed:", err);
    } finally {
      setDownloading(false);
    }
  }

  return (
    <div className="space-y-2">
      <div className="flex items-center justify-between gap-3">
        <div>
          <p className="body-prominent">{target.label}</p>
          <p className="stat-small text-foreground-muted">
            {target.exportW} × {target.exportH}
          </p>
        </div>
        <button
          type="button"
          onClick={() => void download()}
          disabled={downloading}
          className="clickable-small rounded-full bg-foreground-red-orange px-3.5 py-1.5 text-white hover:opacity-90 disabled:opacity-50"
        >
          {downloading ? "Exporting…" : "Download JPEG"}
        </button>
      </div>

      {/* Preview: the full-size tile shrunk to PREVIEW_H via transform. The
          reserved box matches the scaled footprint; the capture node inside is
          at true export px. */}
      <div
        className="overflow-hidden rounded-2xl ring-1 ring-surface-stroke"
        style={{ width: target.exportW * scale, height: PREVIEW_H }}
      >
        <div
          style={{
            width: target.exportW,
            height: target.exportH,
            transform: `scale(${scale})`,
            transformOrigin: "top left",
          }}
        >
          <MarketingTile ref={ref} screen={screen} target={target} mode={mode} />
        </div>
      </div>
    </div>
  );
}

// Sequentially exports every device tile for the current screen. Each tile is
// briefly mounted at full export size off-screen, captured, then unmounted, so
// we never hold four full-resolution canvases at once.
function DownloadAllButton({
  screen,
  mode,
  busy,
  setBusy,
}: {
  screen: ScreenSpec;
  mode: ScreenshotTheme;
  busy: boolean;
  setBusy: (b: boolean) => void;
}) {
  const stageRef = useRef<HTMLDivElement>(null);
  const [pending, setPending] = useState<DeviceTarget | null>(null);
  const captureRef = useRef<HTMLDivElement>(null);

  async function downloadAll() {
    setBusy(true);
    try {
      const targets = screen.hero
        ? HERO_TARGETS
        : DEVICE_TARGETS.filter((t) => !screen.padOnly || t.deviceClass === "pad");
      for (const target of targets) {
        setPending(target);
        // Let the staged tile mount + lay out before capture — long enough for
        // the real Technique tab's charts to size (ResizeObserver) and the
        // bar-path scroll pin to settle.
        await new Promise((r) => setTimeout(r, 700));
        const node = captureRef.current;
        if (!node) continue;
        await exportTileJpeg(node, {
          width: target.exportW,
          height: target.exportH,
          fileName: `${screen.id}-${target.id}-${mode}-${target.exportW}x${target.exportH}.jpg`,
          backgroundColor: mode === "light" ? "#ffffff" : undefined,
        });
      }
    } catch (err) {
      console.error("Download-all failed:", err);
    } finally {
      setPending(null);
      setBusy(false);
    }
  }

  return (
    <>
      <button
        type="button"
        onClick={() => void downloadAll()}
        disabled={busy}
        className="clickable-small rounded-full border border-surface-stroke px-3.5 py-1.5 text-foreground-default hover:bg-surface-base-muted disabled:opacity-50"
      >
        {busy ? "Exporting all…" : "Download all devices"}
      </button>

      {/* Off-screen full-size stage for sequential capture. */}
      <div
        ref={stageRef}
        aria-hidden
        style={{
          position: "fixed",
          left: -100000,
          top: 0,
          pointerEvents: "none",
        }}
      >
        {pending && (
          <MarketingTile
            ref={captureRef}
            screen={screen}
            target={pending}
            mode={mode}
          />
        )}
      </div>
    </>
  );
}
