"""Wybór najlepszego iframe-hostera z page HTML tube'a typu wrapper.

Tube'y typu siska/perverzija/latestpornvideo nie hostują player'a same — embedują
zewnętrznych hosterów (luluvid, doodporn, mixdrop, streamtape, ...). Detail page
zawiera typowo 2-5 iframes:
  - ad-iframes (willingcease.com, popads, discord, about:blank)
  - dead hosters (streamtape malware, openload offline)
  - file-hosters (rapidgator, nitroflare — premium walled)
  - "fake" hosters typu playmogo (niszowe forki, brak extractora)
  - real KVS hosters (luluvid, doodporn, mixdrop, voe — `extract_stream_from_hoster`
    radzi sobie z nimi przez KVS markers + yt-dlp generic)

`extract_best_iframe()` filtruje śmieci i preferuje hostery known-working z naszej
implementacji. Używane przez scrapery (siska, latestpornvideo, perverzija) ŚW
2-etapowym scrape: page listing → URL sceny → fetch detail → pick iframe → save
jako `embed_url` w RawPlaybackSource.
"""
from __future__ import annotations

import re

from app.extractors.tubes._embed_iframe import DEAD_HOSTER_RE

# Ad / popup iframes — popunder networks + Discord widget + about:blank.
# Niektóre tube'y embedują kilka takich PRZED prawdziwym player'em żeby
# zmonetyzować ruch — naszego extractora trzeba przeskoczyć żeby trafić na video.
_AD_IFRAME_RE = re.compile(
    r"willingcease\.com"
    r"|popads|popunder|adsterra"
    r"|discord\.com/widget"
    r"|about:blank",
    re.IGNORECASE,
)

# Hostery których NIGDY nie obsłużymy direct extract (premium / file storage /
# proprietary players bez KVS / playmogo-style niche). Mobile WebView może je
# otworzyć, ale priorytet w pick'u to im trafić jako fallback NA OSTATNIM
# miejscu, nie pierwszym.
_LOW_PRIORITY_HOSTERS_RE = re.compile(
    r"rapidgator|nitroflare|filer\.net|frdl\."
    r"|playmogo\.com"  # generic player redirect, brak ext
    r"|easyvidplayer|embedseek|upns\.online|seekplayer|rpmplay",
    re.IGNORECASE,
)

# Hostery które MAMY potwierdzone że działają z `extract_stream_from_hoster`.
# Kolejność = priority list (lewy = najbardziej preferowany).
_PREFERRED_HOSTERS = (
    "luluvid",
    "lulustream",
    "doodporn",
    "doodstream",
    "dood.la",
    "mixdrop",
    "voe.sx",  # czasem działa
)


def _iframe_priority(url: str) -> int:
    """Lower = better. 0..N dla preferred, 500 dla nieznanych, 1000 low-priority."""
    if _LOW_PRIORITY_HOSTERS_RE.search(url):
        return 1000
    for i, h in enumerate(_PREFERRED_HOSTERS):
        if h in url.lower():
            return i
    return 500


_IFRAME_SRC_RE = re.compile(r'<iframe[^>]+src=["\']([^"\']+)["\']', re.IGNORECASE)


def extract_best_iframe(html: str, *, base_url: str | None = None) -> str | None:
    """Zwraca URL pierwszego iframe NIE-ad, NIE-dead, posortowanego po priority.

    `base_url` używany do resolwowania protocol-relative (//host/path) i relative
    URL-i (/embed/xxx) na absolute. Jeśli None i iframe jest relative, jest
    pomijany.
    """
    if not html:
        return None

    urls: list[str] = []
    for m in _IFRAME_SRC_RE.finditer(html):
        src = m.group(1).strip()
        if not src or src.lower() == "about:blank":
            continue
        if src.startswith("//"):
            src = "https:" + src
        elif src.startswith("/") and base_url:
            from urllib.parse import urljoin
            src = urljoin(base_url, src)
        urls.append(src)

    if not urls:
        return None

    clean = []
    for u in urls:
        if _AD_IFRAME_RE.search(u):
            continue
        if DEAD_HOSTER_RE.search(u):
            continue
        clean.append(u)

    if not clean:
        return None

    clean.sort(key=_iframe_priority)
    return clean[0]
