import asyncio
from celery import shared_task
from asgiref.sync import sync_to_async
from playwright.async_api import async_playwright

from html_agregator.html_fetcher import fetch_and_save_html_for_pages
from html_agregator.utils.process import get_pages_to_process
from extractly.models import NetworkMonitoredPage
from link_agregator.source_managment import scrape_all_sources
from django.core.cache import cache


# --- wspólne ustawienia "stealth" dla Playwrighta ---
PLAYWRIGHT_ARGS = [
    "--disable-blink-features=AutomationControlled",
    "--no-sandbox",
    "--disable-dev-shm-usage",
]
CTX_KW = dict(
    user_agent=(
        "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 "
        "(KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36"
    ),
    locale="pl-PL",
    timezone_id="Europe/Warsaw",
    viewport={"width": 1366, "height": 768},
    extra_http_headers={
        "Accept-Language": "pl-PL,pl;q=0.9,en;q=0.8",
        "Upgrade-Insecure-Requests": "1",
    },
)
STEALTH_INIT_SCRIPT = """
Object.defineProperty(Navigator.prototype, 'webdriver', { get: () => undefined });
window.chrome = window.chrome || { runtime: {} };
Object.defineProperty(navigator, 'languages', { get: () => ['pl-PL','pl'] });
Object.defineProperty(navigator, 'plugins',  { get: () => [1,2,3,4,5] });
"""


LOCK_KEY = "html_aggr_lock"
LOCK_TTL = 20 * 60  # 20 min

@shared_task
def html_agregator_task(enable: str = "true", names=None, include_fetched: bool = False, requeue_if_locked: bool = False, requeue_delay: int = 60):
    # 🔒 spróbuj założyć lock
    got = cache.add(LOCK_KEY, "1", timeout=LOCK_TTL)
    if not got:
        print("[html_agregator_task] already running -> locked")
        if requeue_if_locked:
            # opcjonalnie przełóż start za chwilę
            html_agregator_task.apply_async(
                kwargs={"enable": enable, "names": names, "include_fetched": include_fetched, "requeue_if_locked": False},
                countdown=requeue_delay,
            )
        return {"status": "locked"}

    async def runner():
        browser = None
        context = None
        try:
            pages_qs = await get_pages_to_process(enable=enable, name=names, include_fetched=include_fetched)
            pages = await sync_to_async(list)(pages_qs)
            print(f"[html_agregator_task] Do pobrania: {len(pages)} stron")
            if not pages:
                return

            async with async_playwright() as p:
                browser = await p.chromium.launch(headless=True, args=PLAYWRIGHT_ARGS)
                context = await browser.new_context(**CTX_KW)
                await context.add_init_script(STEALTH_INIT_SCRIPT)

                page = await context.new_page()
                await fetch_and_save_html_for_pages(page, pages=pages)
        finally:
            # bezpieczne zamykanie
            try:
                if context:
                    await context.close()
            except Exception:
                pass
            try:
                if browser:
                    await browser.close()
            except Exception:
                pass

    try:
        asyncio.run(runner())
        return {"status": "ok"}
    finally:
        cache.delete(LOCK_KEY)



@shared_task
def link_agregator_task():
    """
    Uruchamia scraper dla wszystkich źródeł w trybie 'fetch'.
    (scrape_all_sources ma już w sobie własny kontekst/UA/locale/itd.)
    """
    async def runner():
        try:
            print("Uruchamiam scrape_all_sources (mode=fetch)")
            await scrape_all_sources(
                source_id=None,
                params=None,
                mode="fetch",
                headless=True
            )
        except Exception as e:
            print(f"Błąd w link_agregator_task: {e}")

    asyncio.run(runner())


@shared_task
def is_active_check_task():
    """
    Uruchamia scraper w trybie 'check', który sprawdza status aktywności źródeł.
    (scrape_all_sources ma już w sobie własny kontekst/UA/locale/itd.)
    """
    async def runner():
        try:
            print("Uruchamiam scrape_all_sources (mode=check)")
            await scrape_all_sources(
                source_id=None,
                params=None,
                mode="check",
                headless=True
            )
        except Exception as e:
            print(f"Błąd w is_active_check_task: {e}")

    asyncio.run(runner())
