import assert from "node:assert/strict";
import { execFileSync } from "node:child_process";
import { readFile, stat } from "node:fs/promises";
import test from "node:test";

test("quality fill is normalized to the 30–100 range and thumb centre", async () => {
  const source = await readFile(new URL("../app/page.tsx", import.meta.url), "utf8");
  assert.match(source, /const qualityRatio = \(quality - 30\) \/ 70/);
  assert.match(source, /\(0\.5 - qualityRatio\) \* 17/);
  assert.match(source, /"--value": qualityFill/);
});

test("single-image downloads bypass ZIP creation", async () => {
  const source = await readFile(new URL("../app/page.tsx", import.meta.url), "utf8");
  const directDownload = source.indexOf("if (done.length === 1)");
  const zipCreation = source.indexOf("const zip = new JSZip()");
  assert.ok(directDownload > -1 && zipCreation > directDownload);
});

test("the approved BatchForge logo remains available as a brand asset", async () => {
  const logo = await readFile(new URL("../public/batchforge-logo.svg", import.meta.url), "utf8");
  const favicon = await readFile(new URL("../public/batchforge-icon-v3.svg", import.meta.url), "utf8");
  assert.match(logo, /Three white input tiles beside one green image output tile/);
  assert.match(logo, /fill="#1F7A54"/);
  assert.match(favicon, /fill="#000000"/);
  assert.match(favicon, /fill="#1F7A54"/);
});

test("the downloadable source archive matches the current family contract", async () => {
  const archive = new URL("../public/BatchForge-source.zip", import.meta.url);
  const transport = new URL("../public/BatchForge-source.zip.txt", import.meta.url);
  assert.ok((await stat(archive)).size > 100_000);
  assert.deepEqual(await readFile(archive), await readFile(transport));

  const themeSource = execFileSync(
    "unzip",
    ["-p", archive.pathname, "BatchForge/components/theme-switch.tsx"],
    { encoding: "utf8" },
  );
  const contract = execFileSync(
    "unzip",
    ["-p", archive.pathname, "BatchForge/docs/INTERFACE_CONTRACT.md"],
    { encoding: "utf8" },
  );
  assert.match(themeSource, /const DEFAULT_THEME: Theme = "gray"/);
  assert.match(themeSource, /Domain=myforgeworks\.net/);
  assert.match(contract, /Contract version: 1\.6\.0/);
});

test("the interface keeps one privacy statement and no marketing slogan", async () => {
  const source = await readFile(new URL("../app/page.tsx", import.meta.url), "utf8");
  assert.equal(source.match(/100% local · nothing uploaded/g)?.length, 1);
  assert.match(source, /<b>No batch cap<\/b>/);
  assert.match(source, /: "Convert"/);
  assert.doesNotMatch(source, /Built for the work nobody has time for/);
  assert.doesNotMatch(source, /Safe for student and school materials/);
});

test("file IDs have a fallback when randomUUID is unavailable", async () => {
  const source = await readFile(new URL("../app/page.tsx", import.meta.url), "utf8");
  assert.match(source, /typeof crypto\.randomUUID === "function"/);
  assert.match(source, /Math\.random\(\)\.toString\(36\)/);
  assert.match(source, /createItemId\(\)/);
});

test("uses the shared Forgeworks typography, alignment, and theme control", async () => {
  const source = await readFile(new URL("../app/page.tsx", import.meta.url), "utf8");
  const shell = await readFile(new URL("../components/site-shell.tsx", import.meta.url), "utf8");
  const guide = await readFile(new URL("../app/guide/page.tsx", import.meta.url), "utf8");
  const switchSource = await readFile(new URL("../components/theme-switch.tsx", import.meta.url), "utf8");
  const css = await readFile(new URL("../app/forgeworks-interface.css", import.meta.url), "utf8");
  const localCss = await readFile(new URL("../app/globals.css", import.meta.url), "utf8");
  const layout = await readFile(new URL("../app/layout.tsx", import.meta.url), "utf8");
  const contract = await readFile(new URL("../docs/INTERFACE_CONTRACT.md", import.meta.url), "utf8");
  const regularFont = await readFile(new URL("../public/fonts/ibm-plex-sans.ttf", import.meta.url));
  const boldFont = await readFile(new URL("../public/fonts/ibm-plex-sans-bold.ttf", import.meta.url));

  assert.match(shell, /className="site-header-inner"/);
  assert.match(shell, /<Link className="site-brand" href="\/"/);
  assert.match(shell, /className="site-footer"/);
  assert.match(shell, /<ThemeSwitch \/>/);
  assert.doesNotMatch(shell, /storageKey=/);
  assert.match(shell, /site-footer-links"><Link href="\/guide">Guide<\/Link>/);
  assert.doesNotMatch(shell, /download-source|LICENSE\.txt/);
  assert.match(guide, /family-container family-guide-layout/);
  assert.match(guide, /family-guide-index/);
  assert.match(guide, /Download the complete source package/);
  assert.match(guide, /MIT License/);
  assert.match(source, /className="family-hero-title"/);
  assert.match(source, /className="family-hero-description"/);
  assert.match(source, /workspace family-container family-intro-offset/);
  assert.doesNotMatch(shell, /site-brand-mark/);
  assert.doesNotMatch(source, /top-actions/);
  assert.doesNotMatch(localCss, /\.top-actions|\.brand-mark|\.theme-switch/);
  assert.match(css, /font-family: "IBM Plex Sans"/);
  assert.match(css, /--family-content: 1180px/);
  assert.match(css, /--family-header-height: 72px/);
  assert.match(css, /--family-header-blur: 18px/);
  assert.match(css, /radial-gradient\(circle at 75% 0%/);
  assert.match(css, /interface contract v1\.6\.0/);
  assert.match(layout, /import "\.\/globals\.css";\s*import "\.\/forgeworks-interface\.css";/);
  assert.match(layout, /metadataBase: new URL\("https:\/\/batchforge\.myforgeworks\.net"\)/);
  assert.match(layout, /data-theme="gray"/);
  assert.match(layout, /const key = "forgeworks-theme"/);
  assert.match(layout, /Domain=myforgeworks\.net/);
  assert.match(contract, /Contract version: 1\.6\.0/);
  assert.match(css, /\.site-footer \{\s*display: flex;[\s\S]*?justify-content: flex-end/);
  assert.doesNotMatch(css, /site-footer-brand|site-footer-description/);
  assert.doesNotMatch(shell, /site-footer-brand|site-footer-description|Local image conversion/);
  assert.match(switchSource, /aria-label="Light mode"/);
  assert.match(switchSource, /aria-label="Dark gray mode"/);
  assert.match(switchSource, /aria-label="Pure black mode"/);
  assert.match(switchSource, /import \{ Moon, Sun \}/);
  assert.match(switchSource, /className=\{`black-dot/);
  assert.match(switchSource, /const DEFAULT_THEME: Theme = "gray"/);
  assert.match(switchSource, /const THEME_STORAGE_KEY = "forgeworks-theme"/);
  assert.match(switchSource, /window\.addEventListener\("focus", syncTheme\)/);
  assert.match(css, /\.theme-switch \.black-dot span/);
  assert.match(css, /\.family-hero-title/);
  assert.match(css, /\.family-hero-description/);
  assert.match(css, /\.family-intro-offset \{\s*padding-top: 62px/);
  assert.match(css, /@media \(max-width: 820px\)[\s\S]*?\.family-intro-offset \{\s*padding-top: 40px/);
  assert.match(css, /@media \(max-width: 520px\)[\s\S]*?\.family-intro-offset \{\s*padding-top: 32px/);
  assert.doesNotMatch(localCss, /workspace\.family-container\{padding-top:/);
  assert.doesNotMatch(switchSource, /theme-full-moon|theme-crescent/);
  assert.doesNotMatch(css, /family-sun-turn|family-moon-breathe|family-crescent-drift/);
  assert.doesNotMatch(css, /site-brand-mark/);
  assert.ok(regularFont.byteLength > 50_000);
  assert.ok(boldFont.byteLength > 50_000);
});

test("uses semantic page chrome and the shared readable metadata floor", async () => {
  const source = await readFile(new URL("../app/page.tsx", import.meta.url), "utf8");
  const shell = await readFile(new URL("../components/site-shell.tsx", import.meta.url), "utf8");
  const css = await readFile(new URL("../app/globals.css", import.meta.url), "utf8");

  assert.match(shell, /<header className="site-header">/);
  assert.match(shell, /<main>\{children\}<\/main>/);
  assert.match(shell, /<footer className="site-footer">/);
  assert.match(source, /<SiteShell>/);
  assert.match(source, /<section className="workspace/);
  assert.match(css, /\.file-info span,.status,.savings,.benefits b,.benefits span\{font-size:12px\}/);
});
