from typing import Dict, Any
import logging

logger = logging.getLogger(__name__)

class Video:
    def get_metadata(self) -> Dict[str, Any]:
        """
        Return metadata about the video.

        Returns:
            Dictionary containing metadata.
        """
        return self._backend.get_metadata()

    def frame_to_seconds(self, frame_number: int) -> float:
        """
        Convert a frame number to seconds.

        Args:
            frame_number: Frame number to convert

        Returns:
            Time in seconds corresponding to the frame number

        Raises:
            ValueError: If the video FPS is not available
        """
        if not hasattr(self, "fps") or self.fps is None or self.fps == 0:
            raise ValueError("Video FPS not available")

        return frame_number / self.fps

    def seconds_to_frame(self, seconds: float) -> int:
        """
        Convert seconds to the nearest frame number.

        Args:
            seconds: Time in seconds

        Returns:
            Nearest frame number corresponding to the time

        Raises:
            ValueError: If the video FPS is not available
        """
        if not hasattr(self, "fps") or self.fps is None or self.fps == 0:
            raise ValueError("Video FPS not available")

        return round(seconds * self.fps)

    def extract_frames(self,
                      start_time: float = 0,
                      end_time: float = None,
                      fps: float = None,
                      output_pattern: str = "frame_%04d.jpg") -> 'Video':
        """
        Extract frames from the video to disk.

        Args:
            start_time: Start time in seconds (default: 0)
            end_time: End time in seconds (default: end of video)
            fps: Frame rate for extraction (default: original video fps)
            output_pattern: Pattern for output filenames with %d or %0nd format
                           (e.g., "frame_%04d.jpg" for frame_0001.jpg)

        Returns:
            Self for method chaining

        Note:
            This method uses FFmpeg to extract frames efficiently.
        """
        import subprocess
        import os
        from pathlib import Path

        # Set default end time to video duration
        if end_time is None:
            end_time = self.duration

        # Set default fps to video fps
        if fps is None:
            fps = self.fps

        # Ensure output directory exists
        output_dir = os.path.dirname(output_pattern)
        if output_dir:
            os.makedirs(output_dir, exist_ok=True)

        # Build FFmpeg command
        cmd = [
            "ffmpeg", "-y",
            "-i", self.path,
            "-ss", str(start_time),
            "-to", str(end_time),
            "-vf", f"fps={fps}",
            "-q:v", "2",  # High quality JPEG
            output_pattern
        ]

        # Run FFmpeg
        try:
            subprocess.run(cmd, check=True, stderr=subprocess.PIPE)
        except subprocess.CalledProcessError as e:
            logger.error(f"Error extracting frames: {e.stderr.decode()}")
            raise RuntimeError(f"Failed to extract frames: {e}")

        return self
