"""
Video Streaming Module
Extract and serve video streaming URLs
"""

from fastapi import HTTPException
from typing import Optional
import logging

logger = logging.getLogger(__name__)


async def get_video_info(url: str, api_base_url: str = "http://localhost:8000") -> dict:
    """
    Get video streaming information for a given URL
    
    Args:
        url: Video page URL (e.g., https://xnxx.com/video-123)
        api_base_url: Base URL of the API for proxy links (e.g., https://my-api.com)
        
    Returns:
        {
            ...
        }
    """
    # Import here to avoid circular dependency
    from app.scrapers import xnxx, xhamster, xvideos, masa49, pornhub, youporn, redtube, beeg, spankbang, fapnut, pornxp, hqporner, xxxparodyhd, pornwex, tube8, pornhat, brazzpw, gosexpod, watcherotic
    from app.api.endpoints import thumbnails
    from urllib.parse import urlparse
    
    # Parse URL to get host
    parsed = urlparse(url)
    host = parsed.netloc
    
    logger.info(f"Getting video info for: {url}")
    
    # Determine which scraper to use
    scraper_module = None
    if xnxx.can_handle(host):
        scraper_module = xnxx
    elif xhamster.can_handle(host):
        scraper_module = xhamster
    elif xvideos.can_handle(host):
        scraper_module = xvideos
    elif masa49.can_handle(host):
        scraper_module = masa49
    elif pornhub.can_handle(host):
        scraper_module = pornhub
    elif youporn.can_handle(host):
        scraper_module = youporn
    elif redtube.can_handle(host):
        scraper_module = redtube
    elif beeg.can_handle(host):
        scraper_module = beeg
    elif spankbang.can_handle(host):
        scraper_module = spankbang
    elif fapnut.can_handle(host):
        scraper_module = fapnut
    elif pornxp.can_handle(host):
        scraper_module = pornxp
    elif hqporner.can_handle(host):
        scraper_module = hqporner
    elif xxxparodyhd.can_handle(host):
        scraper_module = xxxparodyhd
    elif pornwex.can_handle(host):
        scraper_module = pornwex
    elif tube8.can_handle(host):
        scraper_module = tube8
    elif pornhat.can_handle(host):
        scraper_module = pornhat
    elif brazzpw.can_handle(host):
        scraper_module = brazzpw
    elif gosexpod.can_handle(host):
        scraper_module = gosexpod
    elif watcherotic.can_handle(host):
        scraper_module = watcherotic
    else:
        raise HTTPException(
            status_code=400,
            detail=f"Unsupported host: {host}. Supported: xnxx, xhamster, xvideos, masa49, pornhub, youporn, redtube, beeg, spankbang, fapnut, pornxp, hqporner, xxxparodyhd, pornwex, tube8, pornhat, brazzpw, gosexpod, watcherotic"
        )
    
    try:
        # Scrape the page (now includes video URLs)
        metadata = await scraper_module.scrape(url)
    except Exception as e:
        logger.error(f"Failed to scrape video info: {e}")
        raise HTTPException(
            status_code=400,
            detail=f"Failed to extract video info: {str(e)}"
        )
    
    # Check if video URLs were extracted
    video_data = metadata.get("video", {})
    if not video_data.get("has_video"):
        raise HTTPException(
            status_code=404,
            detail="No video streams found for this URL. Video may be premium or removed."
        )
    
    # Post-process streams to wrap with proxy if needed (Beeg, etc.)
    # This logic mirrors get_stream_url's proxy wrapping but for the entire list
    if video_data.get("has_video") and video_data.get("streams"):
        from urllib.parse import quote
        
        # Helper to wrap URL
        def proxy_wrap(stream_url):
            should_proxy = False
            referer = ""
            
            if "externulls.com" in stream_url or "beeg.com" in stream_url:
                if ".m3u8" in stream_url or "media=hls" in stream_url:
                    should_proxy = True
                    referer = "https://beeg.com/"
            
            if "pornxp.com" in stream_url or "porn-xp.com" in stream_url:
                should_proxy = True
                referer = "https://pornxp.io/"
            
            if "brazzpw.com" in stream_url:
                should_proxy = True
                referer = "https://brazzpw.com/"
                
            # Gosexpod CDN hotlink protection (e2c.gosexpod.com, e3c.gosexpod.com, etc.)
            if "gosexpod.com" in stream_url and stream_url != url:
                should_proxy = True
                referer = "https://www.gosexpod.com/"
                
            if should_proxy:
                encoded_url = quote(stream_url)
                encoded_referer = quote(referer)
                # Ensure api_base_url is valid and stripped of trailing slashes
                base = str(api_base_url).rstrip("/") if api_base_url else "http://localhost:8000"
                
                proxy_url = f"{base}/api/v1/hls/proxy?url={encoded_url}&referer={encoded_referer}"
                # RedTube user_agent logic removed
                    
                return proxy_url
            return stream_url

        # Wrap extracted streams
        for stream in video_data["streams"]:
            stream["url"] = proxy_wrap(stream["url"])
            
        # Wrap default stream
        if video_data.get("default"):
            video_data["default"] = proxy_wrap(video_data["default"])
            
        # Wrap HLS stream specifically if present as key
        if video_data.get("hls"):
            video_data["hls"] = proxy_wrap(video_data["hls"])

    # Build response with consistent field order
    # For SpankBang, exclude metadata fields as they're not reliably extracted
    if scraper_module == spankbang:
        # SpankBang: minimal metadata
        response = {
            "url": url,
            "tags": metadata.get("tags", []),
            "related_videos": metadata.get("related_videos", []),
            "video": video_data,
            "playable": True,
        }
    else:
        # All other sources: full metadata
        thumbnail_url = metadata.get("thumbnail_url")
        if thumbnail_url:
            thumbnail_url = thumbnails.wrap_thumbnail_url(thumbnail_url, api_base_url)
            
        response = {
            "url": url,
            "title": metadata.get("title"),
            "description": metadata.get("description"),
            "thumbnail_url": thumbnail_url,
            "duration": metadata.get("duration"),
            "views": metadata.get("views"),
            "uploader_name": metadata.get("uploader_name"),
            "category": metadata.get("category"),
            "tags": metadata.get("tags", []),
            "upload_date": metadata.get("upload_date"),
            "related_videos": metadata.get("related_videos", []),
            "preview_url": metadata.get("preview_url"),
            "video": video_data,
            "playable": True,
        }
    
    return response


async def get_stream_url(url: str, quality: str = "default", api_base_url: str = "http://localhost:8000") -> dict:
    """
    Get direct stream URL for a specific quality
    
    Args:
        url: Video page URL
        quality: Desired quality (1080p, 720p, 480p, or "default")
        api_base_url: Base URL for proxy links
        
    Returns:
        {"stream_url": "https://...mp4", "quality": "1080p", "format": "mp4"}
    """
    # Note: get_video_info is async, so this needs to be awaited if called directly.
    # But usually this is called by endpoint which calls get_video_info first.
    # Refactoring: we'll just call get_video_info here too.
    # Using default localhost for this low-level helper as it returns raw data
    info = await get_video_info(url, api_base_url=api_base_url) 
    video_data = info["video"]
    
    if quality == "default":
        stream_url = video_data["default"]
        selected_quality = "default"
        
        # Try to find the quality metadata of the default stream
        streams = video_data.get("streams", [])
        for s in streams:
            if s.get("url") == stream_url:
                found_quality = s.get("quality", "default")
                # Normalize quality: add 'p' suffix if missing
                if found_quality and found_quality.isdigit():
                    selected_quality = f"{found_quality}p"
                else:
                    selected_quality = found_quality
                break
    else:
        # Find matching quality
        streams = video_data["streams"]
        matching = [s for s in streams if s["quality"] == quality]
        
        if matching:
            stream_url = matching[0]["url"]
            selected_quality = matching[0]["quality"]
        else:
            # Fallback to default
            stream_url = video_data["default"]
            selected_quality = "default"
            logger.warning(f"Quality {quality} not available, using default")
    
    # Determine format and refine quality label
    # First, check if the scraper provided a specific format
    fmt = "mp4"
    selected_stream = matching[0] if (quality != "default" and matching) else None
    if not selected_stream and quality == "default":
        # Try to find the stream object for the default URL
        streams = video_data.get("streams", [])
        for s in streams:
            if s.get("url") == stream_url:
                selected_stream = s
                break
    
    if selected_stream and selected_stream.get("format"):
        fmt = selected_stream["format"]
    elif ".m3u8" in stream_url:
        fmt = "hls"
        if selected_quality == "default":
            selected_quality = "adaptive"

    should_proxy = False
    referer = ""
            
    # PROXY WRAPPER FOR BEEG and RedTube
    if "externulls.com" in stream_url or "beeg.com" in stream_url:
         should_proxy = True
         referer = "https://beeg.com/"
         
    # Also proxy MP4s from PornXP
    if "pornxp.com" in stream_url or "porn-xp.com" in stream_url:
         should_proxy = True
         referer = "https://pornxp.io/"
         
    if "brazzpw.com" in stream_url:
         should_proxy = True
         referer = "https://brazzpw.com/"
         
    if should_proxy:
            from urllib.parse import quote
            # Construct proxy URL
            # api_base_url comes from get_video_info caller
            # We need to ensure we have a valid api_base_url
            if not api_base_url:
                api_base_url = "http://localhost:8000" # fallback
            base = str(api_base_url).rstrip("/")
                
            # Prevent double wrapping
            if "/api/v1/hls/proxy" not in stream_url:
                encoded_url = quote(stream_url)
                encoded_referer = quote(referer)
                stream_url = f"{base}/api/v1/hls/proxy?url={encoded_url}&referer={encoded_referer}"
                # RedTube user_agent logic removed
    
    # Build base response
    response = {
        "stream_url": stream_url,
        "quality": selected_quality,
        "format": fmt
    }
    
    # Add available_qualities for Pornhub, YouPorn, and RedTube
    from urllib.parse import urlparse
    parsed_url = urlparse(url)
    if ("pornhub.com" in parsed_url.netloc.lower() or 
        "youporn.com" in parsed_url.netloc.lower() or
        "redtube.com" in parsed_url.netloc.lower() or
        "redtube.net" in parsed_url.netloc.lower() or
        "tube8.com" in parsed_url.netloc.lower() or
        "xxxparodyhd.net" in parsed_url.netloc.lower() or
        "xparody.com" in parsed_url.netloc.lower() or
        "pornhat.com" in parsed_url.netloc.lower()):
        qualities = {}
        all_streams = video_data.get("streams", [])
        
        # Debug logging for RedTube
        if "redtube.com" in parsed_url.netloc.lower():
            logger.info(f"RedTube: Found {len(all_streams)} total streams")
            for idx, s in enumerate(all_streams):
                logger.info(f"  Stream {idx}: format={s.get('format')}, quality={s.get('quality')}, url={s.get('url')[:60]}...")
        
        for s in all_streams:
            # For Tube8, we exclusively want to serve HLS streams in the stream endpoint to support all qualities
            if "tube8.com" in parsed_url.netloc.lower() and s.get("format", "").lower() == "mp4":
                continue

            # Include both HLS and MP4 for these sites to support both streaming and download options
            # Also include 'embed' format for sites like xxxparodyhd
            quality_label = s.get("quality", "unknown")
            
            # Normalize quality label: ensure it has 'p' suffix (e.g., "720" -> "720p")
            if quality_label and str(quality_label).isdigit():
                quality_label = f"{quality_label}p"
                
            qualities[quality_label] = s.get("url")
        
        if "redtube.com" in parsed_url.netloc.lower():
            logger.info(f"RedTube: Found {len(qualities)} HLS quality streams")
        
        # Add qualities as flat fields in response
        for quality_label, quality_url in qualities.items():
            response[quality_label] = quality_url
            
    return response
