"""FS7 (French Stream) series site downloader"""
import logging
import re
from typing import List, Dict, Any, Optional
from urllib.parse import urljoin, urlparse
from bs4 import BeautifulSoup
from app.utils import sanitize_filename
from .base import BaseSeriesSite

logger = logging.getLogger(__name__)


class FS7Downloader(BaseSeriesSite):
    """
    Downloader for FS7 (French Stream) series site.

    FS7 is a French streaming site for TV series and films.
    """

    def __init__(self):
        super().__init__()
        self.base_url = "https://fs7.lol"
        self.search_url = f"{self.base_url}/"
        # Update client headers to mimic browser
        self.client.headers.update({
            '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/webp,*/*;q=0.8',
            'Accept-Language': 'fr-FR,fr;q=0.9,en-US;q=0.8,en;q=0.7',
            'Accept-Encoding': 'gzip, deflate',
            'Connection': 'keep-alive',
            'Upgrade-Insecure-Requests': '1'
        })

    def can_handle(self, url: str) -> bool:
        """Check if this downloader can handle the given URL"""
        return "fs7.lol" in url.lower() or "french-stream" in url.lower()

    async def search_anime(
        self,
        query: str,
        lang: str = "vf"
    ) -> List[Dict[str, str]]:
        """
        Search for series on FS7.

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

        Returns:
            List of series with title, url, cover_image
        """
        try:
            logger.info(f"Searching FS7 for: {query}")

            # FS7 uses GET request with query parameters for search
            response = await self.client.get(
                self.search_url,
                params={
                    "do": "search",
                    "subaction": "search",
                    "story": query
                }
            )
            response.raise_for_status()
            html = response.text

            soup = BeautifulSoup(html, 'lxml')
            results = []

            # Look for series items (FS7 has both films and series in search results)
            # We filter for /s-tv/ URLs ending with .html (actual series/season pages)
            items = soup.find_all('a', href=re.compile(r'/s-tv/\d+-.+\.html'))

            for item in items[:20]:  # Limit to 20 results
                url = item.get('href', '')
                if not url.startswith('http'):
                    url = urljoin(self.base_url, url)

                # Extract title from the item
                title_elem = item.find('img', alt=True)
                if title_elem:
                    title = title_elem.get('alt', '').strip()
                else:
                    # Get text content and clean it
                    text = item.get_text(strip=True)
                    # Skip if it's just a category name
                    if any(cat in text.lower() for cat in ['séries', 'series', 'vf', 'vostfr', 'vo', 'netflix', 'disney', 'amazon', 'apple']):
                        continue
                    title = text

                # Clean up title: remove "affiche" suffix and clean extra whitespace
                title = re.sub(r'\s+affiche$', '', title, flags=re.IGNORECASE).strip()
                title = re.sub(r'\s+', ' ', title)  # Normalize whitespace

                # Extract cover image
                img = item.find('img')
                cover_image = img.get('src', '') if img else ''

                # Only add if we have a title and it's not empty
                if title and len(title) > 5:
                    # Avoid duplicates
                    if not any(r['url'] == url for r in results):
                        results.append({
                            'title': title,
                            'url': url,
                            'cover_image': cover_image
                        })

            logger.info(f"Found {len(results)} series on FS7")
            return results

        except Exception as e:
            logger.error(f"Error searching FS7: {e}")
            return []

    async def get_episodes(
        self,
        anime_url: str,
        lang: str = "vf"
    ) -> List[Dict[str, str]]:
        """
        Get episode list for a series.

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

        Returns:
            List of episodes with episode number and url
        """
        try:
            logger.info(f"Fetching episodes from: {anime_url}")

            response = await self.client.get(anime_url)
            response.raise_for_status()
            html = response.text

            soup = BeautifulSoup(html, 'lxml')
            episodes = []

            # Get series title for episode naming
            title_elem = soup.find('h1')
            series_title = title_elem.get_text(strip=True) if title_elem else "Series"
            # Clean up title: remove "affiche" suffix
            series_title = re.sub(r'\s+affiche$', '', series_title, flags=re.IGNORECASE).strip()

            # FS7 stores episode data in JavaScript div elements
            # Format: <div data-ep="1" data-vidzy="..." data-uqload="..." data-netu="..." data-voe="..."></div>
            episode_divs = soup.find_all('div', attrs={'data-ep': True})

            for div in episode_divs:
                ep_num = div.get('data-ep', '').strip()

                # Try different video players in order of preference
                video_url = None
                host_name = None
                for player in ['data-vidzy', 'data-uqload', 'data-voe', 'data-netu']:
                    player_url = div.get(player, '').strip()
                    if player_url:
                        video_url = player_url
                        # Extract host name from attribute name
                        host_name = player.replace('data-', '').title()
                        logger.debug(f"Found episode {ep_num} on {host_name}")
                        break

                if video_url and ep_num:
                    # Create episode title for filename
                    episode_title = f"{series_title} - Episode {ep_num}"

                    # Use pipe-separated format: video_url|anime_url|episode_title
                    combined_url = f"{video_url}|{anime_url}|{episode_title}"

                    episodes.append({
                        'episode': ep_num,
                        'url': combined_url,
                        'title': episode_title,
                        'host': host_name or 'Unknown'
                    })

            # Sort by episode number
            episodes.sort(key=lambda x: int(x['episode']) if x['episode'].isdigit() else 0)

            logger.info(f"Found {len(episodes)} episodes")
            return episodes

        except Exception as e:
            logger.error(f"Error getting episodes from FS7: {e}")
            return []

    async def get_anime_metadata(
        self,
        anime_url: str
    ) -> Dict[str, Any]:
        """
        Get metadata for a series.

        Args:
            anime_url: URL of the series page

        Returns:
            Dictionary with metadata
        """
        try:
            logger.info(f"Fetching metadata from: {anime_url}")

            response = await self.client.get(anime_url)
            response.raise_for_status()
            html = response.text

            soup = BeautifulSoup(html, 'lxml')

            # Extract title
            title = soup.find('h1')
            title = title.get_text(strip=True) if title else "Unknown"

            # Clean up title: remove "affiche" suffix
            title = re.sub(r'\s+affiche$', '', title, flags=re.IGNORECASE).strip()

            # Extract description/synopsis
            description_elem = soup.find('div', class_='full-text')
            description = description_elem.get_text(strip=True) if description_elem else ""

            # Extract cover image
            img = soup.find('img', class_='poster')
            poster_image = img.get('src', '') if img else ''

            # Try to get poster from meta tag if not found
            if not poster_image:
                meta_img = soup.find('meta', property='og:image')
                poster_image = meta_img.get('content', '') if meta_img else ''

            # Extract year
            year_match = re.search(r'\b(19|20)\d{2}\b', description)
            release_year = int(year_match.group()) if year_match else None

            return {
                'title': title,
                'synopsis': description,
                'poster_image': poster_image,
                'release_year': release_year,
                'genres': [],
                'rating': None,
                'studio': None,
                'total_episodes': None,
                'status': None
            }

        except Exception as e:
            logger.error(f"Error getting metadata from FS7: {e}")
            return {
                'title': "Unknown",
                'synopsis': "",
                'poster_image': '',
                'genres': [],
                'rating': None,
                'release_year': None,
                'studio': None,
                'total_episodes': None,
                'status': None
            }

    async def get_download_link(
        self,
        url: str,
        target_filename: Optional[str] = None
    ) -> tuple[str, str]:
        """
        Extract download link from video player URL.

        Args:
            url: Video player URL
            target_filename: Optional filename override

        Returns:
            Tuple of (download_url, filename)
        """
        # FS7 uses embedded video players
        # Delegate to the appropriate video player downloader
        from app.downloaders.video_players import get_video_player

        player = get_video_player(url)
        if player:
            return await player.get_download_link(url, target_filename)
        else:
            raise ValueError(f"No video player found for URL: {url}")
