"""EGRUL PDF scraper using Playwright + Browserless."""

import os
import re
from pathlib import Path
from datetime import datetime
from pydantic import BaseModel


class ScrapeResult(BaseModel):
    """Result of EGRUL scraping."""

    inn: str
    success: bool
    pdf_path: str | None = None
    company_name: str | None = None
    ogrn: str | None = None
    error: str | None = None


class EgrulScraper:
    """Scraper for egrul.nalog.ru using Browserless."""

    def __init__(
        self,
        browserless_url: str | None = None,
        pdf_storage_path: str | None = None,
    ):
        self.browserless_url = browserless_url or os.getenv(
            "BROWSERLESS_URL", "ws://browserless:3000"
        )
        self.pdf_storage_path = Path(
            pdf_storage_path or os.getenv("PDF_STORAGE_PATH", "/data/egrul-pdfs")
        )
        self.pdf_storage_path.mkdir(parents=True, exist_ok=True)

    async def scrape(self, inn: str) -> ScrapeResult:
        """Scrape EGRUL and download PDF for given INN."""
        from playwright.async_api import async_playwright, Browser

        async with async_playwright() as p:
            browser = await p.chromium.connect_over_cdp(self.browserless_url)
            try:
                return await self._do_scrape(browser, inn)
            finally:
                await browser.close()

    async def _do_scrape(self, browser, inn: str) -> ScrapeResult:
        """Internal scraping logic."""
        context = await browser.new_context(
            accept_downloads=True,
            viewport={"width": 1280, "height": 720},
        )
        page = await context.new_page()

        try:
            await page.goto(
                "https://egrul.nalog.ru/index.html", wait_until="networkidle"
            )
            await page.wait_for_timeout(2000)

            # Find and fill search input
            search_input = page.locator('input[name="query"]').first
            if not await search_input.is_visible():
                search_input = page.locator('input[type="text"]').first

            await search_input.fill(inn)
            await page.wait_for_timeout(500)

            # Click search button
            search_btn = page.locator('button[type="submit"]').first
            if not await search_btn.is_visible():
                search_btn = page.locator(
                    '.search-btn, .btn-search, button:has-text("Найти")'
                ).first

            await search_btn.click()
            await page.wait_for_timeout(5000)

            # Wait for results
            await page.wait_for_selector(
                ".res-row, .result-row, .company-row", timeout=30000
            )

            # Extract company info
            company_name = None
            ogrn = None

            try:
                company_name_el = page.locator(".res-name, .company-name").first
                if await company_name_el.is_visible():
                    company_name = await company_name_el.text_content()
                    company_name = company_name.strip() if company_name else None
            except Exception:
                pass

            try:
                ogrn_el = page.locator("text=/ОГРН.*\\d{13}/").first
                if await ogrn_el.is_visible():
                    ogrn_text = await ogrn_el.text_content()
                    ogrn_match = re.search(r"\d{13}", ogrn_text or "")
                    ogrn = ogrn_match.group(0) if ogrn_match else None
            except Exception:
                pass

            # Debug: save HTML of the results page
            debug_html = self.pdf_storage_path / f"{inn}_debug.html"
            html_content = await page.content()
            debug_html.write_text(html_content)

            # Debug: save screenshot of results
            debug_screenshot = self.pdf_storage_path / f"{inn}_debug.png"
            await page.screenshot(path=str(debug_screenshot), full_page=True)

            # The EGRUL site uses JavaScript - look for the clickable element
            # Try clicking on the name link directly
            await page.click('text="БАКИЕВ РУСЛАН ШАМИЛЬЕВИЧ"')
            await page.wait_for_timeout(5000)

            # Debug: save screenshot after click
            debug_screenshot2 = self.pdf_storage_path / f"{inn}_debug2.png"
            await page.screenshot(path=str(debug_screenshot2), full_page=True)

            # Find PDF download button
            pdf_btn = page.locator(
                'a:has-text("Выписка"), a:has-text("PDF"), '
                'button:has-text("Получить выписку"), .pdf-link, .vypiska-link'
            ).first

            if not await pdf_btn.is_visible(timeout=5000):
                pdf_btn = page.locator(
                    '[href*=".pdf"], [onclick*="pdf"], [onclick*="vypiska"]'
                ).first

            # Download PDF
            async with page.expect_download(timeout=60000) as download_info:
                await pdf_btn.click()

            download = await download_info.value

            # Wait for download to complete
            await download.path()

            # Save PDF
            timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
            pdf_filename = f"{inn}_{timestamp}.pdf"
            pdf_path = self.pdf_storage_path / pdf_filename
            await download.save_as(str(pdf_path))

            # Verify file was saved
            if not pdf_path.exists() or pdf_path.stat().st_size == 0:
                return ScrapeResult(
                    inn=inn,
                    success=False,
                    error="PDF download failed - file is empty",
                )

            return ScrapeResult(
                inn=inn,
                success=True,
                pdf_path=str(pdf_path),
                company_name=company_name,
                ogrn=ogrn,
            )

        except Exception as e:
            return ScrapeResult(
                inn=inn,
                success=False,
                error=str(e),
            )
        finally:
            await context.close()


async def scrape_egrul(inn: str) -> ScrapeResult:
    """Scrape EGRUL for company info by INN.

    This is the main entry point for the EGRUL workflow.
    Returns company name, OGRN, and PDF path if successful.
    """
    scraper = EgrulScraper()
    return await scraper.scrape(inn)
