"""EXIF metadata embedding for generated poster images."""

import json
import os
import unicodedata
from datetime import datetime
from typing import Optional

from PIL import Image


def _to_ascii_safe(text: str) -> str:
    """Transliterate common non-ASCII characters for EXIF ASCII fields."""
    replacements = {
        "ä": "ae", "ö": "oe", "ü": "ue", "ß": "ss",
        "Ä": "Ae", "Ö": "Oe", "Ü": "Ue",
        "é": "e", "è": "e", "ê": "e", "à": "a", "â": "a",
    }
    result = text
    for char, repl in replacements.items():
        result = result.replace(char, repl)
    result = unicodedata.normalize("NFKD", result)
    return result.encode("ascii", "replace").decode("ascii")


def get_version() -> str:
    """Return the package version string."""
    try:
        from importlib.metadata import version
        return version("video-thumbnail-creator")
    except Exception:
        return "unknown"


def build_metadata(
    source: str,
    frame_index: int,
    crop_position: str,
    fmt: str,
    mode: str,
    input_file: str,
    overlay_title: str = "",
    overlay_category: str = "",
    overlay_category_logo: str = "",
    overlay_note: str = "",
    ai_reasoning: str = "",
    poster_template: str = "",
) -> dict:
    """Build the metadata dictionary for embedding into a poster image.

    Only includes fields that have non-empty values.
    """
    vtc_version = get_version()

    metadata: dict = {
        "vtc_version": vtc_version,
        "source": source,
        "format": fmt,
        "mode": mode,
        "input_file": os.path.basename(input_file),
        "created_at": datetime.now().isoformat(timespec="seconds"),
    }

    if frame_index >= 0:
        metadata["frame_index"] = frame_index
    if crop_position:
        metadata["crop_position"] = crop_position
    if overlay_title:
        metadata["overlay_title"] = overlay_title
    if overlay_category:
        metadata["overlay_category"] = overlay_category
    if overlay_category_logo:
        metadata["overlay_category_logo"] = os.path.basename(overlay_category_logo)
    if overlay_note:
        metadata["overlay_note"] = overlay_note
    if ai_reasoning:
        metadata["ai_reasoning"] = ai_reasoning
    if poster_template:
        metadata["poster_template"] = poster_template

    return metadata


def embed_metadata(image_path: str, metadata: dict) -> None:
    """Embed metadata into a JPEG image's EXIF data.

    Sets:
    - Software (0x0131): "video-thumbnail-creator {version}"
    - ImageDescription (0x010E): overlay_title if present
    - Artist (0x013B): overlay_category if present
    - UserComment (0x9286): Full JSON metadata block

    Uses Pillow's native EXIF support (no extra dependencies).
    """
    img = Image.open(image_path)
    exif = img.getexif()

    # Software tag
    exif[0x0131] = f"video-thumbnail-creator {metadata.get('vtc_version', 'unknown')}"

    # ImageDescription = overlay title (IFD0 string tags are ASCII-only per EXIF spec)
    title = metadata.get("overlay_title", "")
    if title:
        exif[0x010E] = _to_ascii_safe(title)

    # Artist = overlay category (text, not logo path)
    category = metadata.get("overlay_category", "")
    if category:
        exif[0x013B] = _to_ascii_safe(category)

    # UserComment = full JSON block with UNICODE\x00 charset prefix (EXIF standard)
    # EXIF UserComment (tag 0x9286) is in the Exif IFD, not IFD0
    exif_ifd = exif.get_ifd(0x8769)  # Exif IFD pointer
    json_str = json.dumps(metadata, ensure_ascii=False, indent=2)
    charset_prefix = b"UNICODE\x00"
    exif_ifd[0x9286] = charset_prefix + json_str.encode("utf-16-be")

    # Save with EXIF data
    img.save(image_path, exif=exif.tobytes(), quality=95)
    img.close()


def read_metadata(image_path: str) -> Optional[dict]:
    """Read embedded VTC metadata from a JPEG image's EXIF UserComment.

    Returns the parsed metadata dict, or None if no VTC metadata is found.
    """
    try:
        img = Image.open(image_path)
        exif = img.getexif()
        exif_ifd = exif.get_ifd(0x8769)
        user_comment = exif_ifd.get(0x9286, "")
        img.close()

        if not user_comment:
            return None

        # Handle EXIF UserComment charset prefix
        if isinstance(user_comment, bytes):
            if user_comment[:8] == b"UNICODE\x00":
                user_comment = user_comment[8:].decode("utf-16-be")
            elif user_comment[:8] == b"ASCII\x00\x00\x00":
                user_comment = user_comment[8:].decode("ascii", errors="replace")
            else:
                user_comment = user_comment.decode("utf-8", errors="replace")

        data = json.loads(user_comment)
        if "vtc_version" in data:
            return data
        return None
    except Exception:
        return None
