from __future__ import annotations

import os
from pathlib import Path

from dotenv import load_dotenv
from playwright.sync_api import sync_playwright


load_dotenv()


TENANT_HOME_URL = os.getenv("TENANT_HOME_URL", "https://test-lianlianyun.lianlianwz.com/home")
WANYOUJI_PHONE = os.getenv("E2E_CERTIFIED_TENANT_PHONE", "19361091624")
WANYOUJI_PASSWORD = os.getenv("E2E_CERTIFIED_TENANT_PASSWORD", "test123456")
WANZHANGGUI_PHONE = os.getenv("E2E_WANZHANGGUI_TENANT_PHONE", "15555555555")
WANZHANGGUI_PASSWORD = os.getenv("E2E_WANZHANGGUI_TENANT_PASSWORD", "wss123456")


def login(page, phone: str, password: str) -> None:
    page.goto(TENANT_HOME_URL.replace("/home", "/login"), wait_until="domcontentloaded")
    page.locator("#password_login_phone").fill(phone)
    page.locator("#password_login_password").fill(password)
    page.get_by_text("登 录", exact=True).click()
    page.wait_for_load_state("domcontentloaded")
    page.wait_for_timeout(2500)
    if "/account/select" in page.url or page.get_by_text("选择账号").first.is_visible(timeout=1000):
        box = page.evaluate(
            """() => {
                const nodes = Array.from(document.querySelectorAll('taro-view-core, div'));
                const candidates = nodes
                  .map(el => ({ el, text: el.innerText || el.textContent || '', r: el.getBoundingClientRect() }))
                  .filter(item => item.text.includes('主账号'))
                  .filter(item => item.r.width > 300 && item.r.width < 800 && item.r.height > 50 && item.r.height < 140)
                  .sort((a, b) => (a.r.width * a.r.height) - (b.r.width * b.r.height));
                const target = candidates[0];
                if (!target) return null;
                return {
                    x: target.r.x,
                    y: target.r.y,
                    width: target.r.width,
                    height: target.r.height
                };
            }"""
        )
        if box:
            page.mouse.click(box["x"] + box["width"] - 30, box["y"] + box["height"] / 2)
        else:
            page.evaluate(
                """() => {
                const nodes = Array.from(document.querySelectorAll('taro-view-core, div'));
                const target = nodes.find(el => {
                    const text = el.innerText || el.textContent || '';
                    const r = el.getBoundingClientRect();
                    return text.includes('主账号') && r.width > 180 && r.height > 60;
                });
                if (target) target.click();
            }"""
            )
        page.wait_for_load_state("domcontentloaded")
        page.wait_for_timeout(2500)


def dump(page, label: str) -> None:
    out = Path("runtime/auth_probe")
    out.mkdir(parents=True, exist_ok=True)
    text = page.locator("body").inner_text(timeout=5000)
    (out / f"{label}.txt").write_text(f"URL: {page.url}\n\n{text}", encoding="utf-8")
    page.screenshot(path=str(out / f"{label}.png"), full_page=True)
    print(f"[{label}] {page.url}")
    print(text[:1500])
    print("-" * 80)


def click_text(page, text: str) -> bool:
    loc = page.get_by_text(text, exact=False).first
    try:
        loc.click(timeout=2500)
        page.wait_for_load_state("domcontentloaded")
        page.wait_for_timeout(1800)
        return True
    except Exception:
        return False


def click_account_menu_backend(page) -> bool:
    clicked = page.evaluate(
        """() => {
            const nodes = Array.from(document.querySelectorAll('taro-view-core, div, span'));
            const menuTrigger = nodes
              .map(el => ({ el, text: el.innerText || el.textContent || '', r: el.getBoundingClientRect() }))
              .filter(item => item.text.includes('主账号') && item.r.y < 120 && item.r.width > 80 && item.r.height > 20)
              .sort((a, b) => (a.r.width * a.r.height) - (b.r.width * b.r.height))[0];
            if (!menuTrigger) return false;
            menuTrigger.el.click();
            return true;
        }"""
    )
    if not clicked:
        return False
    page.wait_for_timeout(1000)
    return click_text(page, "管理后台")


def click_top_backend_button(page) -> bool:
    box = page.evaluate(
        """() => {
            const nodes = Array.from(document.querySelectorAll('taro-view-core, div, span, button'));
            const items = nodes
              .map(el => ({ el, text: (el.innerText || el.textContent || '').trim(), r: el.getBoundingClientRect() }))
              .filter(item => item.text === '进入后台')
              .filter(item => item.r.y < 80 && item.r.width > 60 && item.r.height > 20)
              .sort((a, b) => (a.r.width * a.r.height) - (b.r.width * b.r.height));
            const target = items[0];
            if (!target) return null;
            return { x: target.r.x, y: target.r.y, width: target.r.width, height: target.r.height };
        }"""
    )
    if not box:
        return False
    page.mouse.click(box["x"] + box["width"] / 2, box["y"] + box["height"] / 2)
    page.wait_for_load_state("domcontentloaded")
    page.wait_for_timeout(2500)
    return True


def probe_account(page, label: str, phone: str, password: str) -> None:
    login(page, phone, password)
    dump(page, f"{label}_home")
    if click_top_backend_button(page):
        dump(page, f"{label}_top_进入后台")
    if click_account_menu_backend(page):
        dump(page, f"{label}_管理后台")
    for text in ["进入后台", "企业管理", "授权管理", "授权密钥", "我的授权", "管理授权"]:
        if click_text(page, text):
            dump(page, f"{label}_{text}")


def main() -> None:
    with sync_playwright() as p:
        browser = p.chromium.launch(headless=False, slow_mo=120)
        context = browser.new_context(viewport={"width": 1440, "height": 900})
        probe_account(context.new_page(), "wanyouji", WANYOUJI_PHONE, WANYOUJI_PASSWORD)
        context.close()
        context = browser.new_context(viewport={"width": 1440, "height": 900})
        probe_account(context.new_page(), "wanzhanggui", WANZHANGGUI_PHONE, WANZHANGGUI_PASSWORD)
        context.close()
        browser.close()


if __name__ == "__main__":
    main()
