from abc import ABC, abstractmethod
from typing import Any, Dict, List


class Loader(ABC):
    """Abstract base class for anime data loaders/providers."""
    @abstractmethod
    def subscribe_download_progress(self, handler):
        """Subscribe a handler to the download_progress event.
        Args:
            handler: Callable to be called with progress dict.
        """
    @abstractmethod
    def unsubscribe_download_progress(self, handler):
        """Unsubscribe a handler from the download_progress event.
        Args:
            handler: Callable previously subscribed.
        """

    @abstractmethod
    def search(self, word: str) -> List[Dict[str, Any]]:
        """Search for anime series by name.

        Args:
            word: Search term to look for

        Returns:
            List of found series as dictionaries containing series information
        """

    @abstractmethod
    def is_language(
        self,
        season: int,
        episode: int,
        key: str,
        language: str = "German Dub",
    ) -> bool:
        """Check if episode exists in specified language.

        Args:
            season: Season number (1-indexed)
            episode: Episode number (1-indexed)
            key: Unique series identifier/key
            language: Language to check (default: German Dub)

        Returns:
            True if episode exists in specified language, False otherwise
        """

    @abstractmethod
    def download(
        self,
        base_directory: str,
        serie_folder: str,
        season: int,
        episode: int,
        key: str,
        language: str = "German Dub"
    ) -> bool:
        """Download episode to specified directory.

        Args:
            base_directory: Base directory for downloads
            serie_folder: Series folder name within base directory
            season: Season number (0 for movies, 1+ for series)
            episode: Episode number within season
            key: Unique series identifier/key
            language: Language version to download (default: German Dub)

        Returns:
            True if download successful, False otherwise
        """

    @abstractmethod
    def get_site_key(self) -> str:
        """Get the site key/identifier for this provider.

        Returns:
            Site key string (e.g., 'aniworld.to', 'voe.com')
        """

    @abstractmethod
    def get_title(self, key: str) -> str:
        """Get the human-readable title of a series.

        Args:
            key: Unique series identifier/key

        Returns:
            Series title string
        """

    @abstractmethod
    def get_season_episode_count(self, slug: str) -> Dict[int, int]:
        """Get season and episode counts for a series.

        Args:
            slug: Series slug/key identifier

        Returns:
            Dictionary mapping season number (int) to episode count (int)
        """

