"""
4th API — select team by data-id, pick exchange type, click Next.
"""
import re

from playwright.async_api import Page

from app.automation.helpers import human_delay, safe_click
from app.automation.selectors import (
    EXCHANGE_NEXT_BUTTON,
    EXCHANGE_TYPE_ONE_WAY,
    EXCHANGE_TYPE_REQUEST,
    EXCHANGE_TYPE_TWO_WAY,
    SEARCH_TEAMS_UL,
    SUGGESTED_TEAMS_UL,
)
from app.automation.session_store import session_store
from app.automation.tasks.login import ensure_hudl_session
from app.automation.tasks.popup import close_hudl_popups

EXCHANGE_TYPE_MAP = {
    "two-way": EXCHANGE_TYPE_TWO_WAY,
    "one-way": EXCHANGE_TYPE_ONE_WAY,
    "request": EXCHANGE_TYPE_REQUEST,
}


def _team_id_from_url(url: str | None) -> str | None:
    if not url:
        return None
    match = re.search(r"/(?:manage/)?exchanges/(\d+)|/teams/(\d+)/exchanges", url)
    if not match:
        return None
    return match.group(1) or match.group(2)


def _resolve_owner_team_id(page: Page, owner_team_id: str | None) -> str:
    """Our Football/Basketball Hudl team — required to open the right exchange list."""
    explicit = (owner_team_id or "").strip()
    if explicit.isdigit():
        return explicit

    from_page = _team_id_from_url(page.url or "")
    if from_page:
        return from_page

    from_session = _team_id_from_url(session_store.get_exchanges_url())
    if from_session:
        return from_session

    raise ValueError(
        "owner_team_id required (Football/Basketball Hudl id). "
        "Select a team in Organizations first."
    )


def _already_on_owner_exchange(url: str, owner_id: str) -> bool:
    u = (url or "").lower()
    return (
        f"/manage/exchanges/{owner_id}" in u
        or f"/teams/{owner_id}/exchanges" in u
    )


async def _click_team_by_id(page: Page, team_id: str, team_source: str) -> None:
    # Activation-guide calendar often covers suggested teams — clear it first.
    await close_hudl_popups(page)

    if team_source == "suggested":
        container = page.locator(SUGGESTED_TEAMS_UL)
    else:
        container = page.locator(SEARCH_TEAMS_UL)

    team_block = container.locator(
        f'div[class*="ex-team-block"][data-id="{team_id}"]'
    ).first

    # Fallback: any matching team block on the page (list class can vary).
    if await team_block.count() == 0:
        team_block = page.locator(
            f'div[class*="ex-team-block"][data-id="{team_id}"]'
        ).first

    await team_block.wait_for(state="attached", timeout=8000)
    await team_block.scroll_into_view_if_needed()
    await human_delay(0.2, 0.4)

    # If the onboarding calendar is (or was) present, skip the slow Playwright
    # hit-test loop and go straight to a DOM click after dismissal.
    guide_present = await page.locator("#activation-guide-container").count() > 0
    if guide_present:
        await close_hudl_popups(page)

    try:
        await safe_click(team_block, timeout_ms=4000, force_after_ms=1500)
        return
    except Exception as click_err:
        print(f"Team safe_click failed ({click_err}); trying DOM click...")

    # Last resort: DOM click (bypasses overlay hit-testing).
    clicked = await page.evaluate(
        """(teamId) => {
          const el = document.querySelector(
            `div[class*="ex-team-block"][data-id="${teamId}"]`
          );
          if (!el) return false;
          el.scrollIntoView({ block: 'center' });
          el.click();
          return true;
        }""",
        team_id,
    )
    if not clicked:
        raise RuntimeError(f"Could not click exchange team data-id={team_id}")


async def run_select_exchange_type(
    page: Page,
    team_id: str,
    team_source: str,
    exchange_type: str,
    owner_team_id: str | None = None,
) -> dict:
    if exchange_type not in EXCHANGE_TYPE_MAP:
        raise ValueError(
            f"exchange_type must be one of: {list(EXCHANGE_TYPE_MAP.keys())}"
        )
    if team_source not in ("suggested", "search"):
        raise ValueError("team_source must be 'suggested' or 'search'")

    from app.automation.tasks.exchange import open_exchange
    from app.automation.tasks import search as search_task
    from app.automation.tasks.cancel_back import _close_smooth_modal_wizard, _modal_open

    # Do not call login_run() here — it can navigate to /home and leave Football
    # on the wrong page. ensure_hudl_session keeps the current URL when logged in.
    await ensure_hudl_session(page)

    # Leftover Football wizard (e.g. after FE Back to type) blocks team clicks.
    if await _modal_open(page):
        await _close_smooth_modal_wizard(page)
        await human_delay(0.5, 1.0)

    await close_hudl_popups(page)

    owner_id = _resolve_owner_team_id(page, owner_team_id)

    # Already on Football/Basketball exchange list (/teams/... or /manage/...)
    # — don't navigate away or the suggested-team list (and later the video
    # step) can be wiped before we scrape it for the frontend.
    if not _already_on_owner_exchange(page.url or "", owner_id):
        await open_exchange(page, team_id=owner_id)
        await close_hudl_popups(page)

    async def _restore_search_results_if_needed():
        """Search results are transient page state — any navigation/reload/cold
        start (including the open_exchange above) clears them. For a search-sourced
        team, re-run the last search query so the target team block exists before
        we try to click it."""
        if team_source != "search":
            return
        team_block = page.locator(SEARCH_TEAMS_UL).locator(
            f'div[class*="ex-team-block"][data-id="{team_id}"]'
        ).first
        if await team_block.count() > 0:
            return
        query = search_task._last_search_query
        if query:
            print(f"Search results missing; re-running last search '{query}' to restore them.")
            await search_task.run_search(page, query)
            await close_hudl_popups(page)

    async def _execute():
        await close_hudl_popups(page)
        await _restore_search_results_if_needed()
        await _click_team_by_id(page, team_id, team_source)
        await human_delay(1.2, 2.0)
        await close_hudl_popups(page)

        type_btn = page.locator(EXCHANGE_TYPE_MAP[exchange_type]).first
        await type_btn.wait_for(state="visible", timeout=12000)
        await safe_click(type_btn, timeout_ms=5000, force_after_ms=2000)
        await human_delay(0.5, 0.9)

        next_btn = page.locator(EXCHANGE_NEXT_BUTTON).first
        await next_btn.wait_for(state="visible", timeout=12000)
        await safe_click(next_btn, timeout_ms=5000, force_after_ms=2000)
        await human_delay(1.0, 1.6)

    try:
        await _execute()
    except Exception as exc:
        print(f"run_select_exchange_type failed: {exc}. Attempting page reload and retry...")
        try:
            await page.reload(wait_until="domcontentloaded")
            await human_delay(3, 5)
            await close_hudl_popups(page)
            await open_exchange(page, team_id=owner_id)
            await close_hudl_popups(page)
        except Exception as recovery_err:
            print(f"run_select_exchange_type reload/recovery failed: {recovery_err}")

        # Retry the execution once more
        await _execute()

    # Do NOT close popups here — Football video list lives inside the smooth-modal
    # that was just opened by clicking Next.
    await human_delay(0.8, 1.4)

    return {
        "status": "ok",
        "action": "exchange_types",
        "team_id": team_id,
        "owner_team_id": owner_id,
        "team_source": team_source,
        "exchange_type": exchange_type,
        "url": page.url,
        "message": f"Selected team {team_id}, chose {exchange_type}, clicked Next.",
    }
