from __future__ import annotations

import json
import sys
from pathlib import Path

from playwright.sync_api import sync_playwright

ROOT_DIR = Path(__file__).resolve().parents[1]
if str(ROOT_DIR) not in sys.path:
    sys.path.insert(0, str(ROOT_DIR))

from e2e.pages.wanyouji_member_page import WANYOUJI_CONSOLE_URL, WanyoujiMemberPage
from e2e.utils.account_store import account_store


OUT_DIR = Path("runtime/member_probe")


def main() -> None:
    store = account_store()
    parent = store.find_wanyouji_owner_for_member()
    if parent is None:
        raise SystemExit("台账中没有已开通丸友集的主账号")

    OUT_DIR.mkdir(parents=True, exist_ok=True)
    with sync_playwright() as p:
        browser = p.chromium.launch(headless=False, slow_mo=100)
        context = browser.new_context(viewport={"width": 1920, "height": 1080})
        page = context.new_page()
        member_page = WanyoujiMemberPage(page, "https://test-lianlianyun.lianlianwz.com/home")
        member_page.login_main_account(parent.phone, parent.password)
        page.goto(WANYOUJI_CONSOLE_URL, wait_until="domcontentloaded")
        member_page.wait_for_enterprise_console_shell()
        member_page.click_first_available_entry(["组织与部门管理", "成员管理", "组织管理", "员工管理", "成员"])
        page.wait_for_timeout(5000)
        dump_page(page)
        frame = next((item for item in page.frames if "/organization" in item.url), page.main_frame)
        click_text(frame, "创建员工")
        page.wait_for_timeout(3000)
        dump_page(page, suffix="创建员工后")
        browser.close()


def dump_page(page, suffix: str = "组织与部门管理") -> None:
    payload = {
        "url": page.url,
        "frames": [
            {
                "name": frame.name,
                "url": frame.url,
                "text": safe_text(frame)[:2000],
                "nodes": safe_nodes(frame),
            }
            for frame in page.frames
        ],
        "visible_nodes": page.evaluate(
            """() => Array.from(document.querySelectorAll('button, a, span, div, taro-view-core'))
              .map((el, index) => {
                const r = el.getBoundingClientRect();
                return {
                  index,
                  tag: el.tagName,
                  text: (el.innerText || el.textContent || '').trim(),
                  className: String(el.className || ''),
                  id: el.id || '',
                  title: el.getAttribute('title') || '',
                  aria: el.getAttribute('aria-label') || '',
                  rect: { x: r.x, y: r.y, width: r.width, height: r.height },
                };
              })
              .filter(item => item.rect.width > 0 && item.rect.height > 0 && item.text)
              .slice(0, 500)"""
        ),
    }
    (OUT_DIR / f"{suffix}.json").write_text(
        json.dumps(payload, ensure_ascii=False, indent=2),
        encoding="utf-8",
    )


def click_text(frame, text: str) -> bool:
    return bool(
        frame.evaluate(
            """text => {
                const nodes = Array.from(document.querySelectorAll('button, a, span, div'));
                const target = nodes
                  .map(el => ({ el, text: (el.innerText || el.textContent || '').trim(), r: el.getBoundingClientRect() }))
                  .filter(item => item.r.width > 0 && item.r.height > 0)
                  .filter(item => item.text === text || item.text.includes(text))
                  .sort((a, b) => (a.r.width * a.r.height) - (b.r.width * b.r.height))[0];
                if (!target) return false;
                target.el.click();
                return true;
            }""",
            text,
        )
    )


def safe_text(frame) -> str:
    try:
        return frame.locator("body").inner_text(timeout=3000)
    except Exception as exc:
        return f"<无法读取：{exc}>"


def safe_nodes(frame) -> list[dict]:
    try:
        return list(
            frame.evaluate(
                """() => Array.from(document.querySelectorAll('button, a, span, div, input, textarea, .ant-select-selector'))
                  .map((el, index) => {
                    const r = el.getBoundingClientRect();
                    return {
                      index,
                      tag: el.tagName,
                      text: (el.innerText || el.textContent || '').trim(),
                      placeholder: el.getAttribute?.('placeholder') || '',
                      className: String(el.className || ''),
                      rect: { x: r.x, y: r.y, width: r.width, height: r.height },
                    };
                  })
                  .filter(item => item.rect.width > 0 && item.rect.height > 0)
                  .slice(0, 500)"""
            )
        )
    except Exception:
        return []


if __name__ == "__main__":
    main()
