"""Select a user by email in the Users list."""
from __future__ import annotations

from dataclasses import dataclass
from pathlib import Path
from playwright.sync_api import Page

from ....core.artifacts import shot
from ....core.log import log_step


@dataclass
class UserSelectResult:
    found: bool
    page_index: int = 0
    matched_email: str | None = None


def _wait_table_ready(page: Page) -> None:
    page.wait_for_selector("table#tblUsers", timeout=30_000)
    page.wait_for_selector("table#tblUsers tbody tr", state="attached", timeout=30_000)
    page.wait_for_function(
        """() => {
            const tbl = document.querySelector('table#tblUsers');
            if (!tbl) return false;
            const rows = Array.from(tbl.querySelectorAll('tbody tr'));
            if (rows.length === 0) return false;
            return rows.some(r => {
                const rect = r.getBoundingClientRect();
                return !!(r.offsetParent) && rect.height > 0 && rect.width > 0;
            });
        }""",
        timeout=30_000,
    )


def _find_row_by_email(page: Page, email: str):
    target = email.strip().lower()
    rows = page.locator("table#tblUsers tbody tr")
    return rows.filter(has_text=target)


def _try_use_search_box(page: Page, email: str) -> bool:
    email = email.strip()
    candidates = [
        page.locator("input[type='search']").first,
        page.locator("input[placeholder*='Search']").first,
        page.locator("input[aria-label*='Search']").first,
        page.locator("input[name*='search']").first,
    ]
    for inp in candidates:
        try:
            if inp.count() == 0:
                continue
            inp.click(timeout=1500)
            inp.fill("")
            inp.type(email, delay=30)
            page.wait_for_timeout(800)
            return True
        except Exception:
            continue
    return False


def _click_next(page: Page) -> bool:
    candidates = [
        page.get_by_role("link", name="Next"),
        page.get_by_role("button", name="Next"),
        page.locator("a:has-text('Next')").first,
        page.locator("button:has-text('Next')").first,
        page.locator("[aria-label='Next']").first,
        page.locator(".afDataTable__paginate a:has-text('Next')").first,
    ]
    for c in candidates:
        try:
            if c.count() == 0:
                continue
            c.click(timeout=3000)
            page.wait_for_timeout(800)
            return True
        except Exception:
            continue
    return False


def select_user_by_email(
    page: Page,
    email: str,
    run_dir: Path | None = None,
    max_pages: int = 30,
    click_profile: bool = True,
    timeout_ms: int = 8_000,
) -> UserSelectResult:
    email = email.strip()
    _wait_table_ready(page)

    _try_use_search_box(page, email)
    page.wait_for_timeout(500)

    for i in range(max_pages):
        _wait_table_ready(page)
        row = _find_row_by_email(page, email)

        if run_dir:
            shot(page, run_dir, f"users-find-email-page-{i+1}")
            log_step(f"users-find-email-page-{i+1}", page)

        if row.count() == 1:
            if click_profile:
                row.first.locator('a[href*="thisUser=1"]').first.click(timeout=timeout_ms)
                page.wait_for_load_state("networkidle", timeout=timeout_ms)
            return UserSelectResult(found=True, page_index=i + 1, matched_email=email)

        if row.count() > 1:
            raise RuntimeError(f"Multiple rows matched email: {email}")

        if not _click_next(page):
            break

    return UserSelectResult(found=False)
