#!/usr/bin/env python3
"""Generate AprilTag batches grouped by final exported size."""

import argparse
from pathlib import Path
import sys
from typing import List

from generate_apriltag_single import (
    APRILTAG_FAMILIES,
    build_tag_geometry,
    save_tag_artwork,
)


SUPPORTED_FORMATS = ("ai", "svg", "pdf", "png")


def format_cm_label(value: float) -> str:
    rounded = round(value)
    if abs(value - rounded) < 1e-9:
        return f"{value:.1f}"
    return f"{value:.3f}".rstrip("0").rstrip(".")


def normalize_formats(values: List[str]) -> List[str]:
    normalized = []
    seen = set()
    for value in values:
        fmt = value.lower().lstrip(".")
        if fmt == "cdr":
            raise SystemExit(
                "Native .cdr export is not supported. Use .ai output and open/import it in CorelDRAW."
            )
        if fmt not in SUPPORTED_FORMATS:
            supported = ", ".join(SUPPORTED_FORMATS + ("cdr",))
            raise SystemExit(f"Unsupported format '{value}'. Supported: {supported}")
        if fmt not in seen:
            normalized.append(fmt)
            seen.add(fmt)
    return normalized


def parse_args() -> argparse.Namespace:
    parser = argparse.ArgumentParser(
        description="Generate AprilTag ids 1-20 in multiple final sizes and separate folders"
    )
    parser.add_argument("--id-start", type=int, default=1, help="First tag ID, inclusive")
    parser.add_argument("--id-end", type=int, default=20, help="Last tag ID, inclusive")
    parser.add_argument(
        "--sizes-cm",
        type=float,
        nargs="+",
        default=[2.0, 1.5, 1.0],
        help="Square sizes in cm, one folder per size",
    )
    parser.add_argument(
        "--size-mode",
        type=str,
        default="canvas",
        choices=("canvas", "marker"),
        help=(
            "How to interpret --sizes-cm: canvas means final output size including white border; "
            "marker means black tag size excluding white border."
        ),
    )
    parser.add_argument(
        "--family",
        type=str,
        default="tag36h11",
        choices=sorted(APRILTAG_FAMILIES.keys()),
        help="AprilTag family",
    )
    parser.add_argument(
        "--tag-white-ratio",
        type=str,
        default="1:4",
        help="Total white border to marker ratio when --tag-white-border-cm is not set",
    )
    parser.add_argument(
        "--tag-white-border-cm",
        type=float,
        default=None,
        help="Optional override: white margin on each side in cm",
    )
    parser.add_argument(
        "--margin-cm",
        type=float,
        default=0.0,
        help="Extra white margin around the tag tile inside the final exported square",
    )
    parser.add_argument("--dpi", type=int, default=300, help="Output DPI for raster export")
    parser.add_argument(
        "--formats",
        nargs="+",
        default=["svg"],
        help="Output formats. Supported: ai, svg, pdf, png",
    )
    parser.add_argument(
        "--output-dir",
        type=Path,
        default=Path("generated_apriltags"),
        help="Root folder where size subfolders will be created",
    )
    return parser.parse_args()


def main() -> int:
    args = parse_args()

    if args.id_start < 0:
        raise SystemExit("id-start must be >= 0")
    if args.id_end < args.id_start:
        raise SystemExit("id-end must be >= id-start")
    if not args.sizes_cm:
        raise SystemExit("sizes-cm must contain at least one size")

    formats = normalize_formats(args.formats)
    total_files = 0

    for size_cm in args.sizes_cm:
        size_label = format_cm_label(size_cm)
        size_dir = args.output_dir / f"{size_label}x{size_label}cm"
        size_dir.mkdir(parents=True, exist_ok=True)

        for tag_id in range(args.id_start, args.id_end + 1):
            geometry, aruco_dict = build_tag_geometry(
                tag_id=tag_id,
                size_cm=size_cm,
                size_mode=args.size_mode,
                family=args.family,
                tag_white_ratio_text=args.tag_white_ratio,
                tag_white_border_cm=args.tag_white_border_cm,
                margin_cm=args.margin_cm,
            )

            for fmt in formats:
                output_path = size_dir / f"{tag_id}.{fmt}"
                save_tag_artwork(
                    output_path=output_path,
                    geometry=geometry,
                    aruco_dict=aruco_dict,
                    dpi=args.dpi,
                    a4_landscape=False,
                    exact_size_pdf=True,
                )
                total_files += 1

        print(
            f"Saved ids {args.id_start}-{args.id_end} at {size_label}x{size_label} cm -> {size_dir}"
        )

    print(
        f"Completed batch export: ids={args.id_start}-{args.id_end}, "
        f"sizes={len(args.sizes_cm)}, size_mode={args.size_mode}, "
        f"formats={','.join(formats)}, files={total_files}"
    )
    return 0


if __name__ == "__main__":
    sys.exit(main())
