/**
 * ZPL(Zebra Programming Language) 생성
 * ZD421 등 Zebra 프린터용 라벨 데이터 생성 (200 DPI = 8 dots/mm 기준)
 */

import { BarcodeLabelLayout } from "@/types/barcode";

const MM_TO_PX = 4;
const DOTS_PER_MM = 8; // 200 DPI

function pxToDots(px: number): number {
  const mm = px / MM_TO_PX;
  return Math.round(mm * DOTS_PER_MM);
}

export function generateZPL(layout: BarcodeLabelLayout): string {
  const { width_mm, height_mm, components } = layout;
  const widthDots = Math.round(width_mm * DOTS_PER_MM);
  const heightDots = Math.round(height_mm * DOTS_PER_MM);

  const lines: string[] = [
    "^XA",
    "^PW" + widthDots,
    "^LL" + heightDots,
    "^LH0,0",
  ];

  const sorted = [...components].sort((a, b) => (a.zIndex ?? 0) - (b.zIndex ?? 0));

  for (const c of sorted) {
    const x = pxToDots(c.x);
    const y = pxToDots(c.y);
    const w = pxToDots(c.width);
    const h = pxToDots(c.height);

    if (c.type === "text") {
      const fontH = Math.max(10, Math.min(120, (c.fontSize || 10) * 4)); // 대략적 변환
      const fontW = Math.round(fontH * 0.6);
      lines.push(`^FO${x},${y}`);
      lines.push(`^A0N,${fontH},${fontW}`);
      lines.push(`^FD${escapeZPL(c.content || "")}^FS`);
    } else if (c.type === "barcode") {
      if (c.barcodeType === "QR") {
        const size = Math.min(w, h);
        const qrSize = Math.max(1, Math.min(10, Math.round(size / 20)));
        lines.push(`^FO${x},${y}`);
        lines.push(`^BQN,2,${qrSize}`);
        lines.push(`^FDQA,${escapeZPL(c.barcodeValue || "")}^FS`);
      } else {
        // CODE128: ^BC, CODE39: ^B3
        const mod = c.barcodeType === "CODE39" ? "^B3N" : "^BCN";
        const showText = c.showBarcodeText !== false ? "Y" : "N";
        lines.push(`^FO${x},${y}`);
        lines.push(`${mod},${Math.max(20, h - 10)},${showText},N,N`);
        lines.push(`^FD${escapeZPL(c.barcodeValue || "")}^FS`);
      }
    }
    // 이미지/선/사각형은 ZPL에서 비트맵 또는 ^GB 등으로 확장 가능 (생략)
  }

  lines.push("^XZ");
  return lines.join("\n");
}

function escapeZPL(s: string): string {
  return s.replace(/\^/g, "^^").replace(/~/g, "~~");
}
