"""Tier 5: Browser daemon with credentials + CapSolver CAPTCHA solving.

Extends Tier 4 with:
- _do_login(page) / _is_logged_in(page) — auth lifecycle
- _ensure_logged_in(page) — auto-relogin on session expiry
- CapSolver config (API key, proxy string)
"""
from __future__ import annotations

import os
from abc import abstractmethod
from datetime import datetime, timezone

from aiohttp import web

from juris_base.tiers.tier4_daemon import BaseBrowserDaemon


class BaseAuthBrowserDaemon(BaseBrowserDaemon):
    """Tier 5: all of Tier 4 + credential auth + CAPTCHA solving."""

    LOGIN_URL: str            # subclass must set

    # CapSolver config — loaded from env by default
    @property
    def CAPSOLVER_API_KEY(self) -> str:
        return os.environ.get("CAPSOLVER_API_KEY", "")

    @property
    def CAPSOLVER_PROXY_PASS(self) -> str:
        return os.environ.get("CAPSOLVER_PROXY_PASS", "")

    @abstractmethod
    async def _do_login(self, page) -> bool:
        """Attempt login. Return True on success."""
        ...

    @abstractmethod
    async def _is_logged_in(self, page) -> bool:
        """Check if current page/session is authenticated."""
        ...

    async def _ensure_logged_in(self, page) -> bool:
        """Navigate to keepalive URL, relogin if session expired."""
        await page.goto(self.KEEPALIVE_URL, timeout=15000)
        await page.wait_for_load_state("networkidle", timeout=10000)
        if await self._is_logged_in(page):
            return True
        return await self._do_login(page)

    async def handle_search(self, request):
        params = dict(request.query)
        async with self._page_lock:
            page = await self._get_page()
            if not await self._ensure_logged_in(page):
                return web.json_response({"error": "Not logged in"}, status=401)
            try:
                result = await self._do_search(page, params)
                return web.json_response({**result, "timestamp": datetime.now(timezone.utc).isoformat()})
            except Exception as e:
                return web.json_response({"error": str(e)}, status=502)

    async def handle_get(self, request):
        id_ = request.query.get("id", "")
        if not id_:
            return web.json_response({"error": "id required"}, status=400)
        async with self._page_lock:
            page = await self._get_page()
            if not await self._ensure_logged_in(page):
                return web.json_response({"error": "Not logged in"}, status=401)
            try:
                result = await self._do_get(page, id_)
                return web.json_response({**result, "timestamp": datetime.now(timezone.utc).isoformat()})
            except Exception as e:
                return web.json_response({"error": str(e)}, status=502)
