#!/usr/bin/env python3
"""
ZPL Calibration Label Generator

Generates ZPL calibration templates with configurable dimensions.
The calibration label includes:
- Multiple border rectangles with progressive offsets
- Central crosshairs for alignment
- Label dimensions and DPI information
- Offset indicators for printer calibration
"""

import argparse
import os
import json


def generate_calibration_zpl(width_mm: float, height_mm: float, dpi: int = 300) -> str:
    """
    Generate ZPL code for a calibration label.

    Args:
        width_mm: Label width in millimeters
        height_mm: Label height in millimeters
        dpi: Dots per inch (default: 300)

    Returns:
        Complete ZPL template as string
    """
    # Convert mm to pixels at given DPI
    # 1 inch = 25.4mm, so pixels = (mm / 25.4) * dpi
    width_px = int((width_mm / 25.4) * dpi)
    height_px = int((height_mm / 25.4) * dpi)

    # Calculate center points for crosshairs
    center_x = width_px // 2
    center_y = height_px // 2

    # Fixed settings
    offset_step = 20
    num_borders = 4
    version = "2.5.1.0"

    # Build ZPL template
    zpl_lines = ["^XA", "^LS0^FS", "^LT00^FS", "^PQ1^FS", ""]

    # Generate progressive border rectangles
    for i in range(num_borders):
        offset = i * offset_step
        border_width = width_px - (offset * 2)
        border_height = height_px - (offset * 2)

        if border_width > 0 and border_height > 0:
            zpl_lines.append(f"^FO{offset},{offset}^GB{border_width},{border_height},2^FS")

    zpl_lines.extend(
        [
            "",
            "^CF0,30^FS",
            f"^FO0,{center_y - 46}^FB{width_px},1,0,C^FD{width_mm:.0f}x{height_mm:.0f}mm\\&^FS",
            f"^FO0,{center_y - 6}^FB{width_px},1,0,C^FD{dpi} DPI\\&^FS",
            f"^FO0,{center_y + 34}^FB{width_px},1,0,C^FDOffset x:0 y:0\\&^FS",
            "",
            f"^FO0,{center_y}^GB{width_px},1,1^FS",
            "",
            f"^FO{center_x},0^GB1,{height_px},1^FS",
            "",
            "^CF0,20^FS",
            f"^FO70,70^FDBoxes with {offset_step}pt offset ({offset_step * 25.4 / dpi:.1f}mm)^FS",
            f"^FO70,{center_y + 14}^FD+LS^FS",
            f"^FO{width_px - 110},{center_y + 14}^FD-LS^FS",
            f"^FO{center_x + 5},68^FD-LT^FS",
            f"^FO{center_x + 5},{height_px - 93}^FD+LT^FS",
            "",
            f"^FO70,{height_px - 93}^FDMedianWeb V{version}^FS",
            "",
            "^PQ1^FS",
            "^XZ",
        ]
    )

    return "\n".join(zpl_lines)


def main():
    """Main function to handle command line interface."""
    parser = argparse.ArgumentParser(
        description="Generate ZPL calibration labels",
        formatter_class=argparse.RawDescriptionHelpFormatter,
        epilog="""
Examples:
  %(prog)s 102 68                    # Generate 102x68mm label at 300 DPI
  %(prog)s 50 25 --dpi 203           # Generate 50x25mm label at 203 DPI
        """,
    )

    # Required dimensions
    parser.add_argument("width", type=float, help="Label width in mm")
    parser.add_argument("height", type=float, help="Label height in mm")
    parser.add_argument("--dpi", type=int, default=300, help="Dots per inch (default: 300)")

    args = parser.parse_args()

    # Generate filenames
    base_filename = f"calibrate_{args.width:.0f}x{args.height:.0f}_{args.dpi}"
    output_filename = f"{base_filename}.tzpl"
    json_filename = f"{base_filename}.json"

    # Generate ZPL
    zpl_content = generate_calibration_zpl(width_mm=args.width, height_mm=args.height, dpi=args.dpi)

    script_dir = os.path.dirname(os.path.abspath(__file__))
    output_path = os.path.join(script_dir, output_filename)
    json_path = os.path.join(script_dir, json_filename)

    # Write ZPL file, overwriting if it exists
    with open(output_path, "w", encoding="utf-8") as f:
        f.write(zpl_content)

    # Write empty JSON file only if it doesn't exist
    if not os.path.exists(json_path):
        with open(json_path, "w", encoding="utf-8") as f:
            json.dump({}, f, indent=2)

    print(f"Generated calibration label: {output_filename}")
    print(f"Generated empty JSON file: {json_filename}")
    print(
        f"Dimensions: {args.width}x{args.height}mm "
        f"({int((args.width / 25.4) * args.dpi)}x{int((args.height / 25.4) * args.dpi)}px)"
    )
    print(f"DPI: {args.dpi}")


if __name__ == "__main__":
    main()
