"""
Media Content Parsing Module

This module handles parsing of media files and content, including images, audio,
and video files, extracting metadata and analyzing media characteristics.

Key Features:
    - Image metadata extraction
    - Audio content processing
    - Video metadata analysis
    - Media file information extraction
    - Content type detection
    - Format support detection
    - Batch media processing

Main Classes:
    - MediaParser: Main media parsing class

Example Usage:
    >>> from semantica.parse import MediaParser
    >>> parser = MediaParser()
    >>> metadata = parser.parse("image.jpg")
    >>> info = parser.get_media_info("video.mp4")
    >>> formats = parser.get_supported_formats()

Author: Semantica Contributors
License: MIT
"""

from pathlib import Path
from typing import Any, Dict, List, Optional, Union

from ..utils.exceptions import ProcessingError, ValidationError
from ..utils.logging import get_logger
from ..utils.progress_tracker import get_progress_tracker
from .image_parser import ImageParser


class MediaParser:
    """
    Media content parsing handler.

    • Parses various media file formats
    • Extracts metadata and properties
    • Processes media content information
    • Handles different media types
    • Supports batch media processing
    • Analyzes media characteristics
    """

    def __init__(self, config=None, **kwargs):
        """Initialize media parser."""
        self.logger = get_logger("media_parser")
        self.config = config or {}
        self.config.update(kwargs)

        # Initialize parsers
        self.image_parser = ImageParser(**self.config.get("image", {}))

        # Supported formats
        self.supported_formats = {
            # Image formats
            ".jpg": "image",
            ".jpeg": "image",
            ".png": "image",
            ".gif": "image",
            ".bmp": "image",
            ".tiff": "image",
            ".webp": "image",
            # Audio formats (would need additional libraries)
            ".mp3": "audio",
            ".wav": "audio",
            ".flac": "audio",
            ".aac": "audio",
            # Video formats (would need additional libraries)
            ".mp4": "video",
            ".avi": "video",
            ".mov": "video",
            ".mkv": "video",
            ".webm": "video",
        }

    def parse_media(
        self, file_path: Union[str, Path], media_type: Optional[str] = None, **options
    ) -> Dict[str, Any]:
        """
        Parse media file of any supported type.

        Args:
            file_path: Path to media file
            media_type: Media type (auto-detected if None)
            **options: Parsing options

        Returns:
            dict: Parsed media data
        """
        file_path = Path(file_path)

        # Track media parsing
        tracking_id = self.progress_tracker.start_tracking(
            file=str(file_path),
            module="parse",
            submodule="MediaParser",
            message=f"Media: {file_path.name}",
        )

        try:
            if not file_path.exists():
                raise ValidationError(f"Media file not found: {file_path}")

            # Detect media type if not specified
            if media_type is None:
                media_type = self._detect_media_type(file_path)

            self.progress_tracker.update_tracking(
                tracking_id, message=f"Parsing {media_type}..."
            )

            if media_type == "image":
                result = self.image_parser.parse(file_path, **options)
            elif media_type == "audio":
                result = self._parse_audio(file_path, **options)
            elif media_type == "video":
                result = self._parse_video(file_path, **options)
            else:
                raise ValidationError(f"Unsupported media type: {media_type}")

            self.progress_tracker.stop_tracking(
                tracking_id,
                status="completed",
                message=f"Parsed {media_type} successfully",
            )
            return result

        except Exception as e:
            self.progress_tracker.stop_tracking(
                tracking_id, status="failed", message=str(e)
            )
            raise

    def extract_metadata(
        self, file_path: Union[str, Path], media_type: Optional[str] = None
    ) -> Dict[str, Any]:
        """
        Extract metadata from media file.

        Args:
            file_path: Path to media file
            media_type: Media type (auto-detected if None)

        Returns:
            dict: Media metadata
        """
        file_path = Path(file_path)

        if media_type is None:
            media_type = self._detect_media_type(file_path)

        if media_type == "image":
            return self.image_parser.extract_metadata(file_path).__dict__
        elif media_type == "audio":
            return self._extract_audio_metadata(file_path)
        elif media_type == "video":
            return self._extract_video_metadata(file_path)
        else:
            return {}

    def _detect_media_type(self, file_path: Path) -> str:
        """Detect media type from file extension."""
        suffix = file_path.suffix.lower()
        return self.supported_formats.get(suffix, "unknown")

    def _parse_audio(self, file_path: Path, **options) -> Dict[str, Any]:
        """Parse audio file."""
        metadata = self._extract_audio_metadata(file_path)

        return {"metadata": metadata, "type": "audio"}

    def _parse_video(self, file_path: Path, **options) -> Dict[str, Any]:
        """Parse video file."""
        metadata = self._extract_video_metadata(file_path)

        return {"metadata": metadata, "type": "video"}

    def _extract_audio_metadata(self, file_path: Path) -> Dict[str, Any]:
        """Extract audio metadata."""
        metadata = {
            "file_path": str(file_path),
            "file_size": file_path.stat().st_size,
            "format": file_path.suffix.lower(),
        }

        # Try to extract metadata using mutagen if available
        try:
            from mutagen import File

            audio_file = File(str(file_path))
            if audio_file:
                metadata.update(
                    {
                        "title": audio_file.get("TIT2", [None])[0]
                        or audio_file.get("TITLE", [None])[0],
                        "artist": audio_file.get("TPE1", [None])[0]
                        or audio_file.get("ARTIST", [None])[0],
                        "album": audio_file.get("TALB", [None])[0]
                        or audio_file.get("ALBUM", [None])[0],
                        "duration": audio_file.info.length
                        if hasattr(audio_file.info, "length")
                        else None,
                        "bitrate": audio_file.info.bitrate
                        if hasattr(audio_file.info, "bitrate")
                        else None,
                        "sample_rate": audio_file.info.sample_rate
                        if hasattr(audio_file.info, "sample_rate")
                        else None,
                    }
                )
        except (ImportError, OSError):
            self.logger.warning("mutagen not available for audio metadata extraction")
        except Exception as e:
            self.logger.warning(f"Failed to extract audio metadata: {e}")

        return metadata

    def _extract_video_metadata(self, file_path: Path) -> Dict[str, Any]:
        """Extract video metadata."""
        metadata = {
            "file_path": str(file_path),
            "file_size": file_path.stat().st_size,
            "format": file_path.suffix.lower(),
        }

        # Try to extract metadata using ffmpeg if available
        try:
            import subprocess

            result = subprocess.run(
                [
                    "ffprobe",
                    "-v",
                    "quiet",
                    "-print_format",
                    "json",
                    "-show_format",
                    "-show_streams",
                    str(file_path),
                ],
                capture_output=True,
                text=True,
            )

            if result.returncode == 0:
                import json

                video_data = json.loads(result.stdout)

                if "streams" in video_data:
                    for stream in video_data["streams"]:
                        if stream.get("codec_type") == "video":
                            metadata.update(
                                {
                                    "width": stream.get("width"),
                                    "height": stream.get("height"),
                                    "duration": float(
                                        video_data.get("format", {}).get("duration", 0)
                                    ),
                                    "codec": stream.get("codec_name"),
                                    "fps": eval(stream.get("r_frame_rate", "0/1"))
                                    if stream.get("r_frame_rate")
                                    else None,
                                }
                            )
                            break
        except FileNotFoundError:
            self.logger.warning("ffprobe not available for video metadata extraction")
        except Exception as e:
            self.logger.warning(f"Failed to extract video metadata: {e}")

        return metadata
