#!/usr/bin/env python3
from __future__ import annotations

import argparse
from pathlib import Path

from PIL import Image, ImageDraw, ImageFont


def parse_args() -> argparse.Namespace:
    parser = argparse.ArgumentParser(description="Build side-by-side ROI prediction comparisons")
    parser.add_argument("--left-dir", required=True, help="Directory containing left prediction images")
    parser.add_argument("--right-dir", required=True, help="Directory containing right prediction images")
    parser.add_argument("--output-dir", required=True, help="Directory to write comparison images")
    parser.add_argument("--left-title", default="Left", help="Title shown above left image")
    parser.add_argument("--right-title", default="Right", help="Title shown above right image")
    return parser.parse_args()


def load_font() -> ImageFont.ImageFont:
    for candidate in ("arial.ttf", "C:/Windows/Fonts/arial.ttf", "C:/Windows/Fonts/msyh.ttc"):
        try:
            return ImageFont.truetype(candidate, 22)
        except OSError:
            continue
    return ImageFont.load_default()


def fit_height(image: Image.Image, target_height: int) -> Image.Image:
    if image.height == target_height:
        return image
    scale = target_height / image.height
    target_width = max(1, int(round(image.width * scale)))
    return image.resize((target_width, target_height), Image.Resampling.LANCZOS)


def build_pair(left_path: Path, right_path: Path, output_path: Path, left_title: str, right_title: str, font: ImageFont.ImageFont) -> None:
    with Image.open(left_path) as left_image, Image.open(right_path) as right_image:
        left_rgb = left_image.convert("RGB")
        right_rgb = right_image.convert("RGB")

    target_height = max(left_rgb.height, right_rgb.height)
    left_rgb = fit_height(left_rgb, target_height)
    right_rgb = fit_height(right_rgb, target_height)

    gap = 20
    padding = 16
    title_band = 48
    canvas_width = left_rgb.width + right_rgb.width + gap + (padding * 2)
    canvas_height = target_height + title_band + (padding * 2)

    canvas = Image.new("RGB", (canvas_width, canvas_height), color=(245, 243, 238))
    draw = ImageDraw.Draw(canvas)

    left_x = padding
    right_x = padding + left_rgb.width + gap
    image_y = padding + title_band

    draw.text((left_x, padding), left_title, fill=(32, 32, 32), font=font)
    draw.text((right_x, padding), right_title, fill=(32, 32, 32), font=font)

    canvas.paste(left_rgb, (left_x, image_y))
    canvas.paste(right_rgb, (right_x, image_y))

    draw.rectangle(
        (left_x - 2, image_y - 2, left_x + left_rgb.width + 1, image_y + left_rgb.height + 1),
        outline=(160, 160, 160),
        width=2,
    )
    draw.rectangle(
        (right_x - 2, image_y - 2, right_x + right_rgb.width + 1, image_y + right_rgb.height + 1),
        outline=(160, 160, 160),
        width=2,
    )

    output_path.parent.mkdir(parents=True, exist_ok=True)
    canvas.save(output_path, quality=95)


def main() -> None:
    args = parse_args()
    left_dir = Path(args.left_dir)
    right_dir = Path(args.right_dir)
    output_dir = Path(args.output_dir)
    output_dir.mkdir(parents=True, exist_ok=True)

    font = load_font()
    left_images = {path.name: path for path in left_dir.glob("*.jpg")}
    right_images = {path.name: path for path in right_dir.glob("*.jpg")}
    shared_names = sorted(set(left_images) & set(right_images))

    for name in shared_names:
        build_pair(
            left_images[name],
            right_images[name],
            output_dir / name,
            args.left_title,
            args.right_title,
            font,
        )

    summary_lines = [
        f"left_dir={left_dir}",
        f"right_dir={right_dir}",
        f"pairs={len(shared_names)}",
        "",
    ]
    summary_lines.extend(shared_names)
    (output_dir / "summary.txt").write_text("\n".join(summary_lines) + "\n", encoding="utf-8")


if __name__ == "__main__":
    main()
