# scraper2_hj3415/app/nfs/adapters/out/playwright/capabilities/scope.py
from __future__ import annotations

from typing import Any

from ._base import _PlaywrightBase  # pyright: ignore[reportPrivateUsage]


class PlaywrightScope(_PlaywrightBase):
    async def is_attached(self, selector: str, *, index: int = 0) -> bool:
        try:
            loc = self._page.locator(selector).nth(index)
            return await loc.count() > 0
        except Exception:
            return False

    async def computed_style(self, selector: str, *, index: int = 0, prop: str) -> str:
        loc = self._page.locator(selector).nth(index)
        return str(
            await loc.evaluate(  # pyright: ignore[reportAny]
                "(el, prop) => getComputedStyle(el)[prop] || ''", prop
            )
        )

    async def count_in_nth(
        self,
        scope_selector: str,
        *,
        scope_index: int,
        inner_selector: str,
    ) -> int:
        scope = self._page.locator(scope_selector).nth(scope_index)
        return await scope.locator(inner_selector).count()

    async def eval_in_nth_first(  # pyright: ignore[reportAny]
        self,
        scope_selector: str,
        *,
        scope_index: int,
        inner_selector: str,
        expression: str,
    ) -> Any:  # pyright: ignore[reportExplicitAny]
        scope = self._page.locator(scope_selector).nth(scope_index)
        loc = scope.locator(inner_selector).first

        if await loc.count() == 0:
            return None

        return await loc.evaluate(expression)  # pyright: ignore[reportAny]

    async def inner_text_in_nth(
        self,
        scope_selector: str,
        *,
        scope_index: int,
        inner_selector: str,
        inner_index: int = 0,
        timeout_ms: int = 10_000,
    ) -> str:
        scope = self._page.locator(scope_selector).nth(scope_index)
        inner = scope.locator(inner_selector).nth(inner_index)

        await inner.wait_for(state="attached", timeout=timeout_ms)

        try:
            return (await inner.inner_text()) or ""
        except Exception:
            return ""

    async def text_content_in_nth(
        self,
        scope_selector: str,
        *,
        scope_index: int,
        inner_selector: str,
        inner_index: int = 0,
        timeout_ms: int = 10_000,
    ) -> str:
        scope = self._page.locator(scope_selector).nth(scope_index)
        inner = scope.locator(inner_selector).nth(inner_index)

        await inner.wait_for(state="attached", timeout=timeout_ms)

        try:
            return (await inner.text_content()) or ""
        except Exception:
            return ""
