"""Utilities for detecting and converting image files to sRGB JPEG."""

import os
import shutil
import subprocess
import sys

IMAGE_EXTENSIONS = {".jpg", ".jpeg", ".png", ".tiff", ".tif", ".heic", ".heif"}

_SRGB_ICC = "/System/Library/ColorSync/Profiles/sRGB Profile.icc"


def is_image_file(path: str) -> bool:
    """Return True if the file extension indicates a supported image format."""
    ext = os.path.splitext(path)[1].lower()
    return ext in IMAGE_EXTENSIONS


def is_wide_gamut_image(image_path: str) -> bool:
    """Detect if an image has a wide-gamut color space requiring sRGB conversion.

    Uses ``sips`` on macOS to check the color space and ICC profile name.
    Returns False on non-macOS systems or when sips is unavailable.
    """
    sips = shutil.which("sips")
    if not sips:
        return False

    wide_gamut_keywords = ("p3", "rec. 2020", "rec.2020", "bt.2020", "display p3", "prophoto")

    # Check -g space
    try:
        result = subprocess.run(
            [sips, "-g", "space", image_path],
            capture_output=True, text=True, timeout=10,
        )
        for line in result.stdout.splitlines():
            if "space:" in line.lower():
                value = line.split(":", 1)[-1].strip().lower()
                if any(kw in value for kw in wide_gamut_keywords):
                    return True
    except Exception:
        pass

    # Fallback: check -g profileName
    try:
        result = subprocess.run(
            [sips, "-g", "profileName", image_path],
            capture_output=True, text=True, timeout=10,
        )
        for line in result.stdout.splitlines():
            if "profilename:" in line.lower():
                value = line.split(":", 1)[-1].strip().lower()
                if any(kw in value for kw in wide_gamut_keywords):
                    return True
    except Exception:
        pass

    return False


def prepare_image_source(image_path: str, output_path: str) -> str:
    """Convert an image file to an sRGB JPEG suitable for poster composition.

    Returns the absolute path to the prepared sRGB JPEG.
    """
    if not os.path.isfile(image_path):
        raise FileNotFoundError(f"Image file not found: '{image_path}'")

    ext = os.path.splitext(image_path)[1].lower()
    sips = shutil.which("sips")

    # Cache wide-gamut check to avoid triple subprocess invocation
    wide_gamut = is_wide_gamut_image(image_path)

    # Wide-gamut or non-JPEG formats: prefer sips on macOS
    needs_conversion = ext not in (".jpg", ".jpeg") or wide_gamut

    if needs_conversion and wide_gamut:
        print("   🎨 Wide-Gamut-Bild erkannt – konvertiere zu sRGB…", file=sys.stderr)

    if needs_conversion and sips and os.path.isfile(_SRGB_ICC):
        try:
            result = subprocess.run(
                [sips, "-s", "format", "jpeg", "-m", _SRGB_ICC, image_path, "--out", output_path],
                capture_output=True, text=True, timeout=60,
            )
            if result.returncode == 0 and os.path.isfile(output_path):
                return os.path.abspath(output_path)
            print(
                f"   Warning: sips conversion failed (rc={result.returncode}); falling back to Pillow.",
                file=sys.stderr,
            )
        except Exception as exc:
            print(f"   Warning: sips conversion error: {exc}; falling back to Pillow.", file=sys.stderr)

    if ext in (".jpg", ".jpeg") and not wide_gamut:
        # JPEG with sRGB — copy directly
        shutil.copy2(image_path, output_path)
        return os.path.abspath(output_path)

    # Fallback: Pillow conversion
    try:
        from PIL import Image as _Image
        with _Image.open(image_path) as img:
            rgb = img.convert("RGB")
            rgb.save(output_path, "JPEG", quality=95)
        return os.path.abspath(output_path)
    except Exception as exc:
        raise RuntimeError(f"Failed to convert image '{image_path}': {exc}") from exc
