"""Cancel / back for the exchange wizard (classic footer + Football smooth-modal)."""
from playwright.async_api import Page

from app.automation.helpers import human_delay
from app.automation.tasks.popup import close_hudl_popups


async def _modal_open(page: Page) -> bool:
    try:
        return (
            await page.locator(
                ".smooth-modal, .smooth-modal-overlay, .multi-step-modal"
            ).count()
            > 0
        )
    except Exception:
        return False


async def _detect_wizard_step(page: Page) -> str:
    """
    Where the Football multi-step modal (or classic wizard) is after Back/Cancel.
    """
    try:
        info = await page.evaluate(
            """() => {
              const modal = document.querySelector(
                '.smooth-modal, .smooth-modal-overlay, .multi-step-modal'
              );
              if (!modal) {
                // Classic exchange list without modal.
                if (document.querySelector('#events-container, .ex-team-block, [class*="ex-team"]')) {
                  return 'exchange_list';
                }
                return 'closed';
              }
              const text = (modal.innerText || '').slice(0, 2500);
              if (/choose playlist/i.test(text) || /no playlists/i.test(text)) {
                return 'playlists';
              }
              if (
                /choose a game to exchange/i.test(text) ||
                modal.querySelector('section.step-2, .multi-step-modal-inner.step-2-active')
              ) {
                return 'games';
              }
              if (
                /two-way|one-way|request video|exchange type/i.test(text) ||
                modal.querySelector('section.step-1, .multi-step-modal-inner.step-1-active')
              ) {
                return 'type';
              }
              if (/include.*stats|game stats|team stats/i.test(text)) return 'stats';
              if (/add a note|optional message|notes/i.test(text)) return 'notes';
              if (/confirm|review|send your/i.test(text)) return 'confirm';
              return 'modal';
            }"""
        )
        return str(info or "modal")
    except Exception:
        if await _modal_open(page):
            return "modal"
        return "closed"


async def _close_smooth_modal_wizard(page: Page) -> bool:
    """
    Close the Football multi-step exchange wizard and return to suggested teams.
    Prefer Cancel / close controls inside .smooth-modal — do not reload the page.
    """
    selectors = (
        ".smooth-modal button:has-text('Cancel')",
        ".smooth-modal footer button:has-text('Cancel')",
        ".multi-step-modal button:has-text('Cancel')",
        ".smooth-modal-overlay button.uni-dismiss",
        ".smooth-modal button.uni-dismiss",
        ".smooth-modal [aria-label='Close']",
        ".smooth-modal [aria-label='close']",
        ".smooth-modal .smooth-modal-close",
        ".smooth-modal .uni-close",
        "button:has-text('Cancel')",
    )
    for selector in selectors:
        btn = page.locator(selector).first
        try:
            if await btn.count() > 0 and await btn.is_visible():
                await btn.click(timeout=5000)
                await human_delay(0.8, 1.4)
                return True
        except Exception:
            continue

    # Escape often dismisses smooth-modal without a full navigation.
    try:
        if await _modal_open(page):
            await page.keyboard.press("Escape")
            await human_delay(0.6, 1.0)
            if not await _modal_open(page):
                return True
            step = await _detect_wizard_step(page)
            if step in ("closed", "exchange_list"):
                return True
    except Exception:
        pass

    return False


async def cancel_exchange(page: Page, step_index: int) -> dict:
    """
    POST /exchange/cancel
    Close the wizard and land back on the suggested-teams exchange page
    (no full Hudl reload when the smooth-modal Cancel/X is available).
    """
    await human_delay(0.3, 0.6)

    # Football / newer UI: videos live in smooth-modal — close it in place.
    if await _modal_open(page):
        closed = await _close_smooth_modal_wizard(page)
        if closed:
            return {
                "status": "ok",
                "action": "cancel_exchange",
                "url": page.url,
                "method": "smooth_modal_close",
                "wizard_step": await _detect_wizard_step(page),
                "message": "Closed exchange wizard modal — back on suggested teams.",
            }

    # Classic footer Cancel button (Basketball / older wizard).
    try:
        selector = f"xpath=(//footer/button[1])[{step_index}]"
        btn = page.locator(selector).first
        await btn.wait_for(state="visible", timeout=8000)
        await btn.click()
        await human_delay(1.0, 1.8)
        return {
            "status": "ok",
            "action": "cancel_exchange",
            "url": page.url,
            "method": "footer_cancel",
            "wizard_step": await _detect_wizard_step(page),
            "message": f"Clicked cancel button at index {step_index}.",
        }
    except Exception as footer_err:
        # Last resort: dismiss generic popups, then try Escape.
        await close_hudl_popups(page)
        try:
            await page.keyboard.press("Escape")
            await human_delay(0.6, 1.0)
        except Exception:
            pass
        return {
            "status": "ok",
            "action": "cancel_exchange",
            "url": page.url,
            "method": "fallback",
            "wizard_step": await _detect_wizard_step(page),
            "message": f"Cancel fallback used ({footer_err}).",
        }


async def _click_visible_back(page: Page, back_index: int = 1) -> str | None:
    """Click the Hudl wizard Back control. Returns the selector used, or None."""
    modal_back_selectors = (
        ".smooth-modal .smooth-modal-back:visible",
        ".multi-step-modal .smooth-modal-back:visible",
        ".smooth-modal-header .smooth-modal-back",
        ".smooth-modal .smooth-modal-back",
        ".multi-step-modal .smooth-modal-back",
        f'xpath=(//div[contains(@class,"smooth-modal-back")])[{max(1, back_index)}]',
        ".smooth-modal button:has-text('Back')",
        ".multi-step-modal button:has-text('Back')",
        ".smooth-modal [aria-label='Back']",
        ".multi-step-modal [aria-label='Back']",
        ".smooth-modal [aria-label='Go back']",
        ".smooth-modal header button",
        ".multi-step-modal header button",
        # Classic wizard footer back (second button often).
        "xpath=(//footer//button[contains(., 'Back') or contains(@class,'back')])[1]",
    )
    for selector in modal_back_selectors:
        btn = page.locator(selector).first
        try:
            if await btn.count() == 0:
                continue
            if not await btn.is_visible():
                continue
            await btn.click(timeout=5000)
            await human_delay(0.9, 1.5)
            return selector
        except Exception:
            continue

    # JS fallback: click first element that looks like the modal back arrow.
    try:
        clicked = await page.evaluate(
            """() => {
              const root = document.querySelector(
                '.smooth-modal, .multi-step-modal, .smooth-modal-overlay'
              ) || document.body;
              const candidates = Array.from(
                root.querySelectorAll(
                  '.smooth-modal-back, [aria-label*="ack" i], [class*="back"], button, a, div'
                )
              );
              const el = candidates.find((n) => {
                const cls = (n.className || '').toString().toLowerCase();
                const label = (n.getAttribute('aria-label') || '').toLowerCase();
                const text = (n.innerText || '').trim().toLowerCase();
                if (cls.includes('smooth-modal-back')) return true;
                if (label.includes('back')) return true;
                if (text === 'back' || text === '←') return true;
                return false;
              });
              if (!el) return false;
              el.click();
              return true;
            }"""
        )
        if clicked:
            await human_delay(0.9, 1.5)
            return "js:back"
    except Exception:
        pass

    return None


async def go_back_exchange(page: Page, back_index: int) -> dict:
    """
    POST /exchange/back
    Clicks the back control in the wizard (smooth-modal-back or step back)
    and reports which wizard step Hudl landed on so the FE can stay in sync.
    """
    await human_delay(0.3, 0.6)
    before = await _detect_wizard_step(page)

    used = await _click_visible_back(page, back_index=back_index)
    if not used:
        # Last attempt with strict wait on classic xpath.
        selector = f'xpath=(//div[@class="smooth-modal-back"])[{max(1, back_index)}]'
        btn = page.locator(selector).first
        await btn.wait_for(state="visible", timeout=10000)
        await btn.click()
        await human_delay(1.0, 1.8)
        used = selector

    after = await _detect_wizard_step(page)
    # If still on the same playlist screen, try one more back click.
    if before == "playlists" and after == "playlists":
        again = await _click_visible_back(page, back_index=1)
        if again:
            used = f"{used} + {again}"
            after = await _detect_wizard_step(page)

    return {
        "status": "ok",
        "action": "go_back",
        "url": page.url,
        "back_index": back_index,
        "selector_used": used,
        "wizard_step_before": before,
        "wizard_step": after,
        "message": f"Clicked back ({used}) → {after}.",
    }
