"""
Backend interface for FMUS-VID.

This module defines the abstract base class that all backends must implement.
"""

from abc import ABC, abstractmethod
from typing import Union, List, Tuple, Optional, Dict, Any, Callable
from pathlib import Path
import os
from ..operations.subtitle import SubtitleEntry

class Backend(ABC):
    """Abstract base class for all video processing backends."""

    @abstractmethod
    def load(self, path: Union[str, Path], **kwargs) -> Any:
        """Load a video file."""
        pass

    @abstractmethod
    def create(self, width: int, height: int, duration: float, fps: float,
               color: Tuple[int, int, int], **kwargs) -> Any:
        """Create a blank video."""
        pass

    @abstractmethod
    def save(self, video: Any, output_path: Union[str, Path],
             progress_callback: Optional[Callable[[float], None]] = None, **kwargs) -> None:
        """Save video to file."""
        pass

    @abstractmethod
    def get_info(self, video: Any) -> Dict[str, Any]:
        """Get video information (width, height, duration, etc.)."""
        pass

    @abstractmethod
    def trim(self, video: Any, start: float, end: Optional[float] = None) -> Any:
        """Trim video to specified time range."""
        pass

    @abstractmethod
    def resize(self, video: Any, width: Optional[int] = None,
               height: Optional[int] = None, keep_aspect: bool = True) -> Any:
        """Resize video to specified dimensions."""
        pass

    @abstractmethod
    def crop(self, video: Any, x: int, y: int, width: int, height: int) -> Any:
        """Crop video to specified region."""
        pass

    @abstractmethod
    def rotate(self, video: Any, degrees: float) -> Any:
        """Rotate video by specified degrees."""
        pass

    @abstractmethod
    def grayscale(self, video: Any) -> Any:
        """Convert video to grayscale."""
        pass

    @abstractmethod
    def blur(self, video: Any, radius: float) -> Any:
        """Apply Gaussian blur with specified radius."""
        pass

    @abstractmethod
    def brightness(self, video: Any, factor: float) -> Any:
        """Adjust video brightness."""
        pass

    @abstractmethod
    def contrast(self, video: Any, factor: float) -> Any:
        """Adjust video contrast."""
        pass

    @abstractmethod
    def mute(self, video: Any) -> Any:
        """Remove audio track."""
        pass

    @abstractmethod
    def volume(self, video: Any, level: float) -> Any:
        """Set audio volume."""
        pass

    @abstractmethod
    def add_audio(self, video: Any, audio_path: Union[str, Path],
                  start: float = 0, volume: float = 1.0) -> Any:
        """Add audio track starting at specified time."""
        pass

    @abstractmethod
    def extract_frame(self, video: Any, time: float) -> Any:
        """Extract a single frame at specified time."""
        pass

    @abstractmethod
    def overlay(self, video: Any, overlay_video: Any,
                position: Tuple[int, int] = (0, 0),
                start: float = 0, duration: Optional[float] = None,
                opacity: float = 1.0) -> Any:
        """Overlay another video (picture-in-picture)."""
        pass

    @abstractmethod
    def concat(self, videos: List[Any]) -> Any:
        """Concatenate multiple videos."""
        pass

    @abstractmethod
    def grid(self, videos: List[Any], rows: int, cols: int) -> Any:
        """Arrange videos in a grid layout."""
        pass

    @abstractmethod
    def add_subtitles(self, video: Any, entries: List[SubtitleEntry],
                     font: str = "Arial", size: int = 24,
                     color: Union[str, Tuple[int, int, int]] = "white",
                     position: Optional[Tuple[int, int]] = None) -> Any:
        """Add subtitles from a list of entries."""
        pass

    @abstractmethod
    def add_subtitle_text(self, video: Any, entry: SubtitleEntry,
                         font: str = "Arial", size: int = 24,
                         color: Union[str, Tuple[int, int, int]] = "white") -> Any:
        """Add a single subtitle entry."""
        pass

    @abstractmethod
    def speed(self, video: Any, factor: float) -> Any:
        """Change playback speed (factor > 1 = faster, factor < 1 = slower)."""
        pass

    @abstractmethod
    def reverse(self, video: Any) -> Any:
        """Reverse video playback."""
        pass

    @abstractmethod
    def fade_in(self, video: Any, duration: float) -> Any:
        """Fade video in from black."""
        pass

    @abstractmethod
    def fade_out(self, video: Any, duration: float) -> Any:
        """Fade video out to black."""
        pass

    @abstractmethod
    def fade_audio_in(self, video: Any, duration: float) -> Any:
        """Fade audio in."""
        pass

    @abstractmethod
    def fade_audio_out(self, video: Any, duration: float) -> Any:
        """Fade audio out."""
        pass

    @abstractmethod
    def chroma_key(self, video: Any, color: Tuple[int, int, int],
                  similarity: float = 0.1, blend: float = 0.0) -> Any:
        """Remove green screen / chroma key."""
        pass

    @abstractmethod
    def normalize_audio(self, video: Any, target_db: float = -16.0) -> Any:
        """Normalize audio to target dB level."""
        pass

    @abstractmethod
    def crossfade(self, video1: Any, video2: Any, duration: float) -> Any:
        """Crossfade between two videos."""
        pass

    @abstractmethod
    def replace_audio(self, video: Any, audio_path: Union[str, Path]) -> Any:
        """Replace audio track with new audio."""
        pass

    @abstractmethod
    def export_gif(self, video: Any, output_path: Union[str, Path],
                   fps: Optional[float] = None, quality: int = 95,
                   loop: int = 0, width: Optional[int] = None) -> None:
        """Export video as animated GIF."""
        pass

    @abstractmethod
    def export_frames(self, video: Any, output_dir: Union[str, Path],
                      prefix: str = "frame_", format: str = "png",
                      start: Optional[float] = None, end: Optional[float] = None,
                      fps: Optional[float] = None) -> List[Path]:
        """Export video frames as images."""
        pass

    @abstractmethod
    def add_text(self, video: Any, overlay: Any) -> Any:
        """Add text overlay to video."""
        pass

    @abstractmethod
    def add_image(self, video: Any, overlay: Any) -> Any:
        """Add image overlay to video."""
        pass

    @staticmethod
    def is_available() -> bool:
        """Check if the backend is available on the system."""
        return False
