"""Generic HTML adapter built on conservative standards-based extraction."""

from __future__ import annotations

from pathlib import PurePosixPath
from urllib.parse import urlsplit

from bs4 import BeautifulSoup

from app.adapters.base import ParsedPage, SiteAdapter
from app.adapters.media_adapter import MediaAdapter
from app.services.caption_parser import CaptionParser
from app.services.pagination import PaginationEngine


class GenericHTMLAdapter(SiteAdapter):
    name = "generic_html"

    def __init__(
        self,
        caption_parser: CaptionParser | None = None,
        pagination: PaginationEngine | None = None,
    ) -> None:
        self.caption_parser = caption_parser or CaptionParser()
        self.pagination = pagination or PaginationEngine()
        self.media_adapter = MediaAdapter(self.caption_parser)

    def supports(self, url: str) -> bool:
        # Domain authorization is enforced by NetworkGuard before this point.
        return urlsplit(url).scheme.lower() in {"http", "https"}

    @staticmethod
    def _fallback_title(url: str) -> str:
        stem = PurePosixPath(urlsplit(url).path).stem.replace("-", " ").replace("_", " ")
        return stem.strip()[:200]

    def parse(self, html: str, url: str) -> ParsedPage:
        soup = BeautifulSoup(html, "html.parser")
        caption = self.caption_parser.parse(
            soup,
            adapter=self,
            fallback_title=self._fallback_title(url),
        )
        videos, video_pages = self.media_adapter.extract(
            soup,
            url,
            caption,
            adapter=self,
            video_page_selectors=self.video_page_selectors,
        )
        next_page = self.pagination.detect(soup, url, adapter=self)
        return ParsedPage(
            url=url,
            title=caption.title,
            caption=caption.caption,
            videos=videos,
            video_pages=video_pages,
            next_page_url=next_page.url,
            next_page_strategy=next_page.strategy,
            caption_source=caption.source,
            adapter_name=self.name,
        )
