/**
 * Generates app-icon.png (1024x1024) — the source for `bunx tauri icon`.
 * Rendered procedurally so the mark is reproducible without design assets:
 * an amber badge holding a lens ring with a check mark inside.
 */
import { deflateSync } from "node:zlib";
import { writeFileSync } from "node:fs";

const SIZE = 1024;
const AMBER = [245, 158, 11];
const WHITE = [255, 255, 255];
const SAMPLES = 3;

const roundRect = (x, y) => {
  const radius = SIZE * 0.22;
  const min = radius;
  const max = SIZE - radius;
  const cx = Math.min(Math.max(x, min), max);
  const cy = Math.min(Math.max(y, min), max);
  return Math.hypot(x - cx, y - cy) <= radius;
};

const ring = (x, y) => {
  const distance = Math.hypot(x - SIZE * 0.5, y - SIZE * 0.44);
  const radius = SIZE * 0.245;
  const thickness = SIZE * 0.072;
  return Math.abs(distance - radius) <= thickness / 2;
};

const segment = (x, y, [x1, y1], [x2, y2], thickness) => {
  const a = [x1 * SIZE, y1 * SIZE];
  const b = [x2 * SIZE, y2 * SIZE];
  const dx = b[0] - a[0];
  const dy = b[1] - a[1];
  const lengthSquared = dx * dx + dy * dy;
  const t = Math.min(Math.max(((x - a[0]) * dx + (y - a[1]) * dy) / lengthSquared, 0), 1);
  return Math.hypot(x - (a[0] + t * dx), y - (a[1] + t * dy)) <= thickness / 2;
};

const check = (x, y) => {
  const thickness = SIZE * 0.062;
  return (
    segment(x, y, [0.405, 0.445], [0.478, 0.53], thickness) ||
    segment(x, y, [0.478, 0.53], [0.605, 0.352], thickness)
  );
};

const pixels = Buffer.alloc(SIZE * SIZE * 4);
for (let py = 0; py < SIZE; py += 1) {
  for (let px = 0; px < SIZE; px += 1) {
    let inside = 0;
    let mark = 0;
    for (let sy = 0; sy < SAMPLES; sy += 1) {
      for (let sx = 0; sx < SAMPLES; sx += 1) {
        const x = px + (sx + 0.5) / SAMPLES;
        const y = py + (sy + 0.5) / SAMPLES;
        if (!roundRect(x, y)) continue;
        inside += 1;
        if (ring(x, y) || check(x, y)) mark += 1;
      }
    }
    const total = SAMPLES * SAMPLES;
    const offset = (py * SIZE + px) * 4;
    if (inside === 0) continue;
    const alpha = Math.round((inside / total) * 255);
    const mix = mark / inside;
    pixels[offset] = Math.round(AMBER[0] * (1 - mix) + WHITE[0] * mix);
    pixels[offset + 1] = Math.round(AMBER[1] * (1 - mix) + WHITE[1] * mix);
    pixels[offset + 2] = Math.round(AMBER[2] * (1 - mix) + WHITE[2] * mix);
    pixels[offset + 3] = alpha;
  }
}

const crcTable = Array.from({ length: 256 }, (unused, index) => {
  let value = index;
  for (let bit = 0; bit < 8; bit += 1) {
    value = value & 1 ? 0xedb88320 ^ (value >>> 1) : value >>> 1;
  }
  return value >>> 0;
});

const crc32 = (buffer) => {
  let crc = 0xffffffff;
  for (const byte of buffer) {
    crc = crcTable[(crc ^ byte) & 0xff] ^ (crc >>> 8);
  }
  return (crc ^ 0xffffffff) >>> 0;
};

const chunk = (type, data) => {
  const length = Buffer.alloc(4);
  length.writeUInt32BE(data.length);
  const body = Buffer.concat([Buffer.from(type, "ascii"), data]);
  const crc = Buffer.alloc(4);
  crc.writeUInt32BE(crc32(body));
  return Buffer.concat([length, body, crc]);
};

const header = Buffer.alloc(13);
header.writeUInt32BE(SIZE, 0);
header.writeUInt32BE(SIZE, 4);
header[8] = 8; // bit depth
header[9] = 6; // RGBA

const raw = Buffer.alloc(SIZE * (SIZE * 4 + 1));
for (let y = 0; y < SIZE; y += 1) {
  raw[y * (SIZE * 4 + 1)] = 0; // filter: none
  pixels.copy(raw, y * (SIZE * 4 + 1) + 1, y * SIZE * 4, (y + 1) * SIZE * 4);
}

const png = Buffer.concat([
  Buffer.from([0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a]),
  chunk("IHDR", header),
  chunk("IDAT", deflateSync(raw, { level: 9 })),
  chunk("IEND", Buffer.alloc(0)),
]);

const target = process.argv[2] ?? "app-icon.png";
writeFileSync(target, png);
console.log(`wrote ${target} (${png.length} bytes)`);