"""Base class for anime streaming sites (catalogs)"""
from abc import abstractmethod
from typing import List, Dict, Any, Optional, Tuple
import logging
import httpx
from bs4 import BeautifulSoup

logger = logging.getLogger(__name__)


class BaseAnimeSite:
    """
    Base class for anime streaming sites.

    Anime sites provide catalogs, metadata, and episode listings.
    They typically link to video players for actual file hosting.

    Examples: Anime-Sama, Neko-Sama, Anime-Ultime, Vostfree, etc.

    KEY FEATURE: Provides rich metadata and episode management
    """

    def __init__(self):
        # Realistic browser headers to avoid blocking by video hosts
        headers = {
            "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36",
            "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8",
            "Accept-Language": "en-US,en;q=0.9,fr;q=0.8",
            "Referer": "https://anime-sama.tv/",
        }
        # Initialize HTTP client with browser headers
        self.client = httpx.AsyncClient(timeout=10.0, follow_redirects=True, headers=headers)



    @abstractmethod
    def can_handle(self, url: str) -> bool:
        """Check if this anime site can handle the given URL"""
        pass

    @abstractmethod
    async def search_anime(
        self,
        query: str,
        lang: str = "vostfr"
    ) -> List[Dict[str, str]]:
        """
        Search for anime on this site.

        Args:
            query: Search query (anime title)
            lang: Language preference (vostfr, vf)

        Returns:
            List of anime with keys:
                - title: Anime title
                - url: Anime page URL
                - cover_image: Optional cover image URL
                - lang: Available languages
        """
        pass

    @abstractmethod
    async def get_episodes(
        self,
        anime_url: str,
        lang: str = "vostfr"
    ) -> List[Dict[str, str]]:
        """
        Get list of episodes for an anime.

        Args:
            anime_url: URL of the anime page
            lang: Language preference

        Returns:
            List of episodes with keys:
                - episode_number: Episode number
                - url: Episode page URL
                - title: Optional episode title
                - host: Video player hosting the file
        """
        pass

    @abstractmethod
    async def get_anime_metadata(self, anime_url: str) -> Dict[str, Any]:
        """
        Get detailed metadata for an anime.

        Args:
            anime_url: URL of the anime page

        Returns:
            Dict with metadata:
                - title: Anime title
                - synopsis: Plot summary
                - genres: List of genres
                - rating: Rating (e.g., "8.5/10")
                - release_year: Release year
                - studio: Animation studio
                - poster_image: Poster URL
                - total_episodes: Total episode count
                - status: Airing status (ongoing, completed)
                - languages: Available languages
        """
        pass

    @abstractmethod
    async def get_download_link(self, url: str) -> Tuple[str, str]:
        """
        Get download link for a specific episode.

        For anime sites, this extracts the video player URL from an episode page.
        Note: Returns video player URL, NOT direct download link!

        Returns:
            Tuple of (video_player_url, episode_title)
        """
        pass

    # Common methods for all anime sites
    async def close(self):
        """Close HTTP client"""
        await self.client.aclose()

    async def _fetch_page(self, url: str) -> str:
        """Fetch HTML page content"""
        response = await self.client.get(url)
        response.raise_for_status()
        return response.text

    def _parse_html(self, html: str) -> BeautifulSoup:
        """Parse HTML with BeautifulSoup"""
        return BeautifulSoup(html, 'lxml')

    def _extract_season_number(self, title: str) -> Optional[int]:
        """Extract season number from title (e.g., 'Saison 2' -> 2)"""
        import re
        match = re.search(r'saison\s*(\d+)', title.lower())
        return int(match.group(1)) if match else None
