from __future__ import annotations

import os
import sys
from pathlib import Path

from dotenv import load_dotenv
from playwright.sync_api import sync_playwright

sys.path.insert(0, str(Path(__file__).resolve().parents[1]))

from e2e.pages.tenant_auth_page import TenantAuthPage


load_dotenv()
sys.stdout.reconfigure(encoding="utf-8")

丸掌柜后台地址 = "https://test-merchant-lianlianyun.lianlianwz.com/productConsole?productCode=P20251204180120231330"
输出目录 = Path("runtime/push_probe")


def 点击左侧菜单(page, 文案: str, 展开父级: bool = False) -> None:
    菜单位置 = page.evaluate(
        """({ text, parent }) => {
            const nodes = Array.from(document.querySelectorAll('taro-view-core, div, span'));
            const target = nodes
              .map(el => ({ text: (el.innerText || el.textContent || '').trim(), r: el.getBoundingClientRect() }))
              .filter(item => item.r.x >= 0 && item.r.x < 240 && item.r.y > 40)
              .filter(item => item.r.width > 20 && item.r.width < 240 && item.r.height > 10)
              .filter(item => item.text === text || item.text.split(/\\s+/).includes(text))
              .filter(item => parent ? item.r.height >= 30 : true)
              .sort((a, b) => {
                  if (a.text === text && b.text !== text) return -1;
                  if (b.text === text && a.text !== text) return 1;
                  return a.r.y - b.r.y || (a.r.width * a.r.height) - (b.r.width * b.r.height);
              })[0];
            if (!target) return null;
            return { x: target.r.x, y: target.r.y, width: target.r.width, height: target.r.height };
        }""",
        {"text": 文案, "parent": 展开父级},
    )
    if not 菜单位置:
        raise AssertionError(f"未找到左侧菜单：{文案}")
    x = 菜单位置["x"] + 菜单位置["width"] - 16 if 展开父级 else 菜单位置["x"] + 菜单位置["width"] / 2
    page.mouse.click(x, 菜单位置["y"] + 菜单位置["height"] / 2)
    page.wait_for_load_state("domcontentloaded")
    page.wait_for_timeout(1200)


def 获取推单配置_frame(page):
    for frame in page.frames:
        if "test-futong-pc" in frame.url and "/dispatchStrategy" in frame.url:
            return frame
    raise AssertionError(f"未找到推单配置 iframe：{[frame.url for frame in page.frames]}")


def 点击按钮(frame, 文案: str) -> None:
    成功 = frame.evaluate(
        """text => {
            const normalized = text.replace(/\\s+/g, '');
            const target = Array.from(document.querySelectorAll('button')).find(el => {
                const value = (el.innerText || el.textContent || '').trim();
                return value === text || value.replace(/\\s+/g, '').includes(normalized);
            });
            if (!target) return false;
            target.click();
            return true;
        }""",
        文案,
    )
    if not 成功:
        raise AssertionError(f"未点击到按钮：{文案}")


def 点击单选(frame, 文案: str) -> None:
    成功 = frame.evaluate(
        """text => {
            const target = Array.from(document.querySelectorAll('.ant-modal label, .ant-modal .ant-radio-wrapper'))
              .find(el => (el.innerText || el.textContent || '').trim().includes(text));
            if (!target) return false;
            target.click();
            return true;
        }""",
        文案,
    )
    if not 成功:
        raise AssertionError(f"未点击到单选项：{文案}")


def 选择下拉(frame, page, 下拉序号: int, 选项文案: str) -> None:
    selectors = frame.locator(".ant-modal .ant-select-selector")
    selectors.nth(下拉序号).click(force=True)
    page.wait_for_timeout(800)
    option = frame.locator(".ant-select-dropdown:not(.ant-select-dropdown-hidden) .ant-select-item-option").filter(
        has_text=选项文案
    ).first
    option.click(force=True)
    page.wait_for_timeout(1000)


def 导出状态(frame, 名称: str) -> None:
    输出目录.mkdir(parents=True, exist_ok=True)
    状态 = frame.evaluate(
        """() => ({
            modalText: document.querySelector('.ant-modal')?.innerText || '',
            selectors: Array.from(document.querySelectorAll('.ant-modal .ant-select-selector')).map((el, index) => ({
                index,
                text: (el.innerText || el.textContent || '').trim(),
                html: el.outerHTML.slice(0, 2000),
                rect: (() => { const r = el.getBoundingClientRect(); return { x: r.x, y: r.y, width: r.width, height: r.height }; })()
            })),
            dropdowns: Array.from(document.querySelectorAll('.ant-select-dropdown:not(.ant-select-dropdown-hidden)')).map((dropdown, dropdownIndex) => ({
                dropdownIndex,
                text: (dropdown.innerText || dropdown.textContent || '').trim(),
                html: dropdown.outerHTML.slice(0, 6000),
                options: Array.from(dropdown.querySelectorAll('.ant-select-item-option')).map((el, index) => ({
                    index,
                    text: (el.innerText || el.textContent || '').trim(),
                    cls: String(el.className || ''),
                    ariaSelected: el.getAttribute('aria-selected'),
                    title: el.getAttribute('title'),
                    html: el.outerHTML.slice(0, 2000),
                }))
            }))
        })"""
    )
    (输出目录 / f"{名称}.txt").write_text(str(状态), encoding="utf-8")
    print(f"\n[{名称}]")
    print("selectors:", 状态["selectors"])
    print("dropdowns:", 状态["dropdowns"])


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})
        page = context.new_page()
        auth_page = TenantAuthPage(page, os.getenv("TENANT_HOME_URL", "https://test-lianlianyun.lianlianwz.com/home"))
        auth_page.login_main_account(
            os.getenv("E2E_PROBE_WZG_PHONE", "19147509308"),
            os.getenv("E2E_PROBE_WZG_PASSWORD", "test123456"),
        )
        page.goto(丸掌柜后台地址, wait_until="domcontentloaded")
        page.wait_for_timeout(3000)
        点击左侧菜单(page, "履约工作室/平台", 展开父级=True)
        点击左侧菜单(page, "工作室管理")
        点击左侧菜单(page, "推单配置")
        frame = 获取推单配置_frame(page)
        点击按钮(frame, "新增策略")
        page.wait_for_timeout(1200)
        name_input = frame.locator(".ant-modal input[placeholder='例如: 默认推单策略']").first
        name_input.fill("E2E探测多平台多授权")
        点击单选(frame, "多平台分发")
        page.wait_for_timeout(800)
        点击按钮(frame, "添加供应链配置")
        page.wait_for_timeout(1000)
        选择下拉(frame, page, 0, "丸友集")
        page.wait_for_timeout(1000)

        frame.locator(".ant-modal .ant-select-selector").nth(1).click(force=True)
        page.wait_for_timeout(1000)
        导出状态(frame, "授权商户号_打开下拉_未选择")

        # 先点第一家，再保持弹窗状态，观察下拉是否关闭、选择结果和选项状态。
        first_option = frame.locator(".ant-select-dropdown:not(.ant-select-dropdown-hidden) .ant-select-item-option").first
        first_option.click(force=True)
        page.wait_for_timeout(1000)
        导出状态(frame, "授权商户号_选择第一家后")

        frame.locator(".ant-modal .ant-select-selector").nth(1).click(force=True)
        page.wait_for_timeout(1000)
        导出状态(frame, "授权商户号_重新打开下拉_选择第一家后")
        browser.close()


if __name__ == "__main__":
    main()
