import { createPreviewLoop, generateSyntheticFreq } from "../utils.ts";

export const category = "ascii";

export const params = [
  {
    key: "char",
    type: "text",
    default: "#",
    label: "char",
    inputStyle: { width: "1ch" },
  },
  {
    key: "rowCount",
    type: "number",
    default: 16,
    min: 4,
    max: 64,
    label: "rows",
  },
  {
    key: "colCount",
    type: "number",
    default: 8,
    min: 2,
    max: 64,
    label: "cols",
  },
  { key: "barColor", type: "color", default: "#ffffff", label: "fg" },
  { key: "bgColor", type: "color", default: "#000000", label: "bg" },
];

export function draw(
  canvas: HTMLCanvasElement,
  freq: Uint8Array,
  options: Record<string, string | number | HTMLImageElement>,
) {
  const ctx = canvas.getContext("2d");
  if (!ctx) return;

  ctx.fillStyle = String(options.bgColor ?? "#000000");
  ctx.fillRect(0, 0, canvas.width, canvas.height);

  const rowCount = Number(options.rowCount ?? 8);
  const colCount = Number(options.colCount ?? 8);
  const barColor = String(options.barColor ?? "#ffffff");
  const ch = String(options.char ?? "#").charAt(0);
  const cellW = canvas.width / rowCount;
  const cellH = canvas.height / colCount;

  ctx.fillStyle = barColor;
  ctx.font = `${cellH}px monospace`;
  ctx.textAlign = "center";
  ctx.textBaseline = "middle";

  const textWidth = ctx.measureText(ch).width;
  const scale = Math.min(cellW / (textWidth || 1), 1);

  for (let i = 0; i < rowCount; i++) {
    const freqIndex = Math.floor((i / rowCount) * freq.length);
    const freqAmpl = freq[freqIndex] / 255;
    const filledCells = Math.round(freqAmpl * colCount);

    for (let j = 0; j < filledCells; j++) {
      const cx = i * cellW + cellW / 2;
      const cy = canvas.height - j * cellH - cellH / 2;
      ctx.save();
      ctx.translate(cx, cy);
      ctx.scale(scale, scale);
      ctx.fillText(ch, 0, 0);
      ctx.restore();
    }
  }
}

export function preview(
  canvas: HTMLCanvasElement,
  _freq: Uint8Array,
  getOptions: () => Record<string, string | number | HTMLImageElement>,
  fps: number,
) {
  let phase = 0;
  const size = 1024;
  const freq = new Uint8Array(size);

  return createPreviewLoop(canvas, fps, (offscreen, dt) => {
    phase += 3 * dt;
    generateSyntheticFreq(freq, phase);
    draw(offscreen, freq, getOptions());
  });
}
