"""
Media Optimization Engine for Hotel MCP Server.

This module provides media URL optimization and metadata handling with:
- Automatic thumbnail generation
- Format optimization (webp, jpg, webm)
- CDN integration
- Responsive image URLs
"""

import logging
import os
from dataclasses import dataclass
from enum import Enum
from typing import Any, Dict, List, Optional
from urllib.parse import parse_qs, urlencode, urlparse, urlunparse

logger = logging.getLogger(__name__)


class MediaFormat(Enum):
    """Supported media formats."""

    WEBP = "webp"
    JPEG = "jpg"
    PNG = "png"
    WEBM = "webm"
    MP4 = "mp4"


class ImageSize(Enum):
    """Standard image sizes for optimization."""

    THUMBNAIL = "150x150"
    SMALL = "300x200"
    MEDIUM = "600x400"
    LARGE = "1200x800"
    ORIGINAL = "original"


@dataclass
class MediaConfig:
    """Configuration for media optimization."""

    base_url: Optional[str] = None
    default_format: MediaFormat = MediaFormat.WEBP
    default_size: ImageSize = ImageSize.MEDIUM
    enable_optimization: bool = True
    quality: int = 85

    def __post_init__(self):
        if self.base_url is None:
            self.base_url = os.getenv("MEDIA_BASE_URL", "")


class MediaOptimizer:
    """
    Media optimization engine for hotel content.

    Provides URL optimization, format conversion, and metadata handling
    for images and videos in hotel records.
    """

    def __init__(self, config: Optional[MediaConfig] = None):
        """Initialize the media optimizer."""
        self.config = config or MediaConfig()

        logger.info(
            f"Media optimizer initialized with base URL: {self.config.base_url or 'None'}"
        )

    def _is_valid_url(self, url: str) -> bool:
        """Check if a URL is valid."""
        try:
            result = urlparse(url)
            return all([result.scheme, result.netloc])
        except Exception:
            return False

    def _build_optimized_url(
        self,
        original_url: str,
        size: Optional[ImageSize] = None,
        format_type: Optional[MediaFormat] = None,
        quality: Optional[int] = None,
    ) -> str:
        """
        Build an optimized URL with transformation parameters.

        Args:
            original_url: Original media URL
            size: Target image size
            format_type: Target format
            quality: Image quality (1-100)

        Returns:
            Optimized URL
        """
        if not self._is_valid_url(original_url):
            return original_url

        if not self.config.enable_optimization:
            return original_url

        # Parse the original URL
        parsed = urlparse(original_url)
        query_params = parse_qs(parsed.query)

        # Add optimization parameters
        if size and size != ImageSize.ORIGINAL:
            query_params["resize"] = [size.value]

        if format_type:
            query_params["format"] = [format_type.value]

        if quality:
            query_params["quality"] = [str(quality)]
        else:
            query_params["quality"] = [str(self.config.quality)]

        # Rebuild the URL
        new_query = urlencode(query_params, doseq=True)
        optimized_url = urlunparse(
            (
                parsed.scheme,
                parsed.netloc,
                parsed.path,
                parsed.params,
                new_query,
                parsed.fragment,
            )
        )

        return optimized_url

    def optimize_image_url(
        self,
        url: str,
        size: Optional[ImageSize] = None,
        format_type: Optional[MediaFormat] = None,
        quality: Optional[int] = None,
    ) -> str:
        """
        Optimize an image URL for performance and format.

        Args:
            url: Original image URL
            size: Target size
            format_type: Target format
            quality: Image quality

        Returns:
            Optimized image URL
        """
        if not url:
            return url

        # Use defaults if not specified
        target_size = size or self.config.default_size
        target_format = format_type or self.config.default_format
        target_quality = quality or self.config.quality

        # Skip optimization for non-image formats
        if not any(
            ext in url.lower() for ext in [".jpg", ".jpeg", ".png", ".webp", ".gif"]
        ):
            return url

        optimized_url = self._build_optimized_url(
            url, target_size, target_format, target_quality
        )

        logger.debug(f"Optimized image URL: {url} -> {optimized_url}")
        return optimized_url

    def generate_responsive_urls(self, url: str) -> Dict[str, str]:
        """
        Generate responsive image URLs for different screen sizes.

        Args:
            url: Original image URL

        Returns:
            Dictionary mapping size names to optimized URLs
        """
        if not url:
            return {}

        responsive_urls = {}

        for size in ImageSize:
            if size == ImageSize.ORIGINAL:
                responsive_urls[size.name.lower()] = url
            else:
                responsive_urls[size.name.lower()] = self.optimize_image_url(
                    url, size=size, format_type=self.config.default_format
                )

        return responsive_urls

    def optimize_media_field(self, field_value: Any) -> Any:
        """
        Optimize a media field value (URL, list of URLs, or nested structure).

        Args:
            field_value: Field value to optimize

        Returns:
            Optimized field value
        """
        if isinstance(field_value, str):
            # Single URL
            return self.optimize_image_url(field_value)

        elif isinstance(field_value, list):
            # List of URLs
            return [
                self.optimize_image_url(url) if isinstance(url, str) else url
                for url in field_value
            ]

        elif isinstance(field_value, dict):
            # Nested structure - recursively optimize
            optimized = {}
            for key, value in field_value.items():
                if key.lower() in ["url", "src", "href", "image", "photo", "picture"]:
                    optimized[key] = self.optimize_media_field(value)
                else:
                    optimized[key] = value
            return optimized

        else:
            # Return as-is for other types
            return field_value

    def optimize_record_media(
        self, record: Dict[str, Any], media_fields: Optional[List[str]] = None
    ) -> Dict[str, Any]:
        """
        Optimize all media fields in a database record.

        Args:
            record: Database record to optimize
            media_fields: List of field names containing media (auto-detected if None)

        Returns:
            Record with optimized media URLs
        """
        if not record:
            return record

        # Auto-detect media fields if not specified
        if media_fields is None:
            media_fields = [
                key
                for key in record.keys()
                if any(
                    term in key.lower()
                    for term in [
                        "image",
                        "photo",
                        "picture",
                        "url",
                        "src",
                        "media",
                        "gallery",
                        "thumbnail",
                        "banner",
                        "cover",
                    ]
                )
            ]

        # Create optimized copy
        optimized_record = record.copy()

        for field in media_fields:
            if field in optimized_record:
                optimized_record[field] = self.optimize_media_field(
                    optimized_record[field]
                )

        # Add responsive URLs for main image fields
        main_image_fields = ["image", "photo", "main_image", "cover_image"]
        for field in main_image_fields:
            if field in optimized_record and isinstance(optimized_record[field], str):
                responsive_field = f"{field}_responsive"
                optimized_record[responsive_field] = self.generate_responsive_urls(
                    optimized_record[field]
                )

        # Add media optimization metadata
        optimized_record["_media_meta"] = {
            "optimized_fields": media_fields,
            "optimization_enabled": self.config.enable_optimization,
            "default_format": self.config.default_format.value,
            "default_size": self.config.default_size.value,
            "quality": self.config.quality,
        }

        return optimized_record

    def optimize_records_media(
        self, records: List[Dict[str, Any]], media_fields: Optional[List[str]] = None
    ) -> List[Dict[str, Any]]:
        """
        Optimize media fields in a list of database records.

        Args:
            records: List of database records
            media_fields: List of field names containing media

        Returns:
            List of records with optimized media
        """
        if not records:
            return records

        logger.debug(f"Optimizing media for {len(records)} records")

        return [self.optimize_record_media(record, media_fields) for record in records]

    def get_media_metadata(self, url: str) -> Dict[str, Any]:
        """
        Extract metadata from a media URL.

        Args:
            url: Media URL to analyze

        Returns:
            Dictionary with media metadata
        """
        if not url:
            return {}

        parsed = urlparse(url)

        # Extract file extension
        path_parts = parsed.path.split(".")
        extension = path_parts[-1].lower() if len(path_parts) > 1 else ""

        # Determine media type
        image_extensions = ["jpg", "jpeg", "png", "webp", "gif", "svg"]
        video_extensions = ["mp4", "webm", "avi", "mov"]

        if extension in image_extensions:
            media_type = "image"
        elif extension in video_extensions:
            media_type = "video"
        else:
            media_type = "unknown"

        return {
            "url": url,
            "type": media_type,
            "extension": extension,
            "domain": parsed.netloc,
            "path": parsed.path,
            "is_optimized": "resize" in parse_qs(parsed.query),
            "responsive_urls": (
                self.generate_responsive_urls(url) if media_type == "image" else {}
            ),
        }


# Global media optimizer instance
_media_optimizer: Optional[MediaOptimizer] = None


def get_media_optimizer() -> MediaOptimizer:
    """Get the global media optimizer instance."""
    global _media_optimizer
    if _media_optimizer is None:
        _media_optimizer = MediaOptimizer()
    return _media_optimizer
