# -*- coding: utf-8 -*-
# filename: utils.py
# @Time    : 2025-01-16
# @Author  : Claude Code
# @Email   : noreply@anthropic.com
# @Software: PyCharm
"""Utility functions for image processing"""
import base64
import io
from pathlib import Path

import requests
from PIL import Image


def validate_image_file(file_path: str) -> bool:
    """
    Validate that a file exists and is a valid image

    Args:
        file_path: Path to the image file

    Returns:
        True if the file is a valid image, False otherwise
    """
    path = Path(file_path)
    if not path.exists():
        return False

    try:
        with Image.open(path) as img:
            img.verify()
        return True
    except Exception:
        return False


def ensure_png_format(image_source: str | bytes) -> bytes:
    """
    Ensure image is in PNG format

    Args:
        image_source: Path to image, URL, or bytes

    Returns:
        Image as PNG bytes
    """
    if isinstance(image_source, bytes):
        img = Image.open(io.BytesIO(image_source))
    elif image_source.startswith(("http://", "https://")):
        response = requests.get(image_source, timeout=30)
        response.raise_for_status()
        img = Image.open(io.BytesIO(response.content))
    else:
        img = Image.open(image_source)

    # Convert to RGB if necessary (PNG supports RGBA)
    if img.mode in ("RGBA", "LA", "P"):
        img = img.convert("RGBA")
    elif img.mode not in ("RGB", "L"):
        img = img.convert("RGB")

    output = io.BytesIO()
    img.save(output, format="PNG")
    return output.getvalue()


def image_to_base64(image_source: str | bytes, format: str = "PNG") -> str:
    """
    Convert image to base64 data URL

    Args:
        image_source: Path to image, URL, or bytes
        format: Image format (default: PNG)

    Returns:
        Base64 data URL string
    """
    if isinstance(image_source, bytes):
        img_bytes = image_source
    elif image_source.startswith(("http://", "https://")):
        response = requests.get(image_source, timeout=30)
        response.raise_for_status()
        img_bytes = response.content
    else:
        with open(image_source, "rb") as f:
            img_bytes = f.read()

    base64_data = base64.b64encode(img_bytes).decode("utf-8")
    return f"data:image/{format.lower()};base64,{base64_data}"


def base64_to_image(base64_data: str, output_path: str) -> None:
    """
    Save base64 image data to file

    Args:
        base64_data: Base64 data URL or raw base64 string
        output_path: Path to save the image
    """
    # Extract base64 string if it's a data URL
    if base64_data.startswith("data:"):
        base64_data = base64_data.split(",", 1)[1]

    img_bytes = base64.b64decode(base64_data)
    Path(output_path).parent.mkdir(parents=True, exist_ok=True)

    with open(output_path, "wb") as f:
        f.write(img_bytes)


def get_image_dimensions(image_source: str | bytes) -> tuple[int, int]:
    """
    Get image dimensions (width, height)

    Args:
        image_source: Path to image, URL, or bytes

    Returns:
        Tuple of (width, height)
    """
    if isinstance(image_source, bytes):
        img = Image.open(io.BytesIO(image_source))
    elif image_source.startswith(("http://", "https://")):
        response = requests.get(image_source, timeout=30)
        response.raise_for_status()
        img = Image.open(io.BytesIO(response.content))
    else:
        img = Image.open(image_source)

    return img.size
