from __future__ import annotations
from bs4 import BeautifulSoup
from ..models import DocumentContent, TextSegment


async def parse_web_js(
    url: str,
    wait_for_selector: str | None = None,
    wait_ms: int = 0,
) -> tuple[str, DocumentContent]:
    """Fetch a URL using a headless Chromium browser (Playwright).

    Use this instead of ``parse_web`` when the target page requires JavaScript
    to render its content (SPAs, AJAX-loaded text, DevExpress portals, etc.).

    Requires the ``js`` extra::

        pip install ai-citer[js]
        playwright install chromium

    Parameters
    ----------
    url:
        The URL to fetch.
    wait_for_selector:
        Optional CSS selector to wait for before extracting text.
        Useful for pages that lazy-load content into a specific element.
    wait_ms:
        Additional milliseconds to wait after navigation / selector match.
        Use for pages that animate or defer content rendering.
    """
    try:
        from playwright.async_api import async_playwright
    except ImportError:
        raise ImportError(
            "playwright is required for parse_web_js. "
            "Install it with: pip install 'ai-citer[js]' && playwright install chromium"
        )

    async with async_playwright() as p:
        browser = await p.chromium.launch()
        try:
            page = await browser.new_page()
            await page.goto(url, wait_until="networkidle", timeout=60_000)

            if wait_for_selector:
                await page.wait_for_selector(wait_for_selector, timeout=30_000)

            if wait_ms:
                await page.wait_for_timeout(wait_ms)

            html = await page.content()
        finally:
            await browser.close()

    soup = BeautifulSoup(html, "html.parser")

    title_tag = soup.find("title")
    title = title_tag.get_text().strip() if title_tag else url

    for tag in soup(["script", "style", "noscript", "nav", "footer", "header"]):
        tag.decompose()

    text_parts: list[str] = []
    for el in soup.find_all(["p", "h1", "h2", "h3", "h4", "h5", "h6", "li", "td"]):
        text = el.get_text().strip()
        if text:
            text_parts.append(text)

    segments: list[TextSegment] = []
    raw_text = ""
    for text in text_parts:
        segments.append(TextSegment(text=text, charOffset=len(raw_text)))
        raw_text += text + "\n\n"

    return title, DocumentContent(rawText=raw_text.rstrip(), segments=segments)
