from __future__ import annotations

from dataclasses import dataclass
from datetime import datetime
from pathlib import Path
import json
import sys

from playwright.sync_api import sync_playwright

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

from e2e.pages.product_solution_admin_page import ProductSolutionAdminPage


@dataclass(frozen=True)
class Settings:
    admin_url: str = "https://test-saas-adminui.lianlianwz.com/pages/home/index"
    admin_username: str = "wangss"
    admin_password: str = "123456"


def main() -> None:
    settings = Settings()
    timestamp = datetime.now().strftime("%Y%m%d%H%M%S")
    out_dir = Path("runtime")
    out_dir.mkdir(exist_ok=True)
    json_path = out_dir / f"prodsol_menu_app_select_{timestamp}.json"
    screenshot_path = out_dir / f"prodsol_menu_app_select_{timestamp}.png"

    with sync_playwright() as playwright:
        browser = playwright.chromium.launch(headless=False, slow_mo=100)
        page = browser.new_page(viewport={"width": 1920, "height": 1080})
        admin = ProductSolutionAdminPage(page, settings.admin_url)
        admin.login(settings.admin_username, settings.admin_password)
        admin.open_product_menu_config_by_keywords(["自动化产品编辑", "自动化产品a", "自动化产品"])
        modal = admin._active_solution_menu_modal()
        admin.click_button_in_container(modal, ["创建菜单", "新建菜单", "新增菜单"], timeout=5000)
        page.wait_for_timeout(1200)
        admin._choose_solution_menu_radio("应用菜单")
        page.wait_for_timeout(500)

        page.evaluate(
            """() => {
              const input = document.querySelector('input#appId, input[aria-owns="appId_list"], input[aria-controls="appId_list"]');
              const select = input && input.closest('.ant-select');
              const target = select && (select.querySelector('.ant-select-arrow') || select.querySelector('.ant-select-selector') || select);
              if (!target) return false;
              const rect = target.getBoundingClientRect();
              target.dispatchEvent(new MouseEvent('mousedown', { bubbles: true, clientX: rect.right - 8, clientY: rect.top + rect.height / 2 }));
              target.click();
              return true;
            }"""
        )
        page.wait_for_timeout(2500)

        summary = page.evaluate(
            """() => {
              const compact = (value) => (value || '').replace(/\\s+/g, ' ').trim();
              const rectOf = (element) => {
                const rect = element.getBoundingClientRect();
                return { x: Math.round(rect.x), y: Math.round(rect.y), w: Math.round(rect.width), h: Math.round(rect.height) };
              };
              return {
                appInput: (() => {
                  const input = document.querySelector('input#appId, input[aria-owns="appId_list"], input[aria-controls="appId_list"]');
                  if (!input) return null;
                  return {
                    value: input.value,
                    attrs: {
                      id: input.id,
                      ariaExpanded: input.getAttribute('aria-expanded'),
                      ariaControls: input.getAttribute('aria-controls'),
                      ariaOwns: input.getAttribute('aria-owns'),
                    },
                    selectText: compact(input.closest('.ant-select')?.innerText || ''),
                    selectHtml: input.closest('.ant-select')?.outerHTML.slice(0, 2000),
                  };
                })(),
                dropdowns: Array.from(document.querySelectorAll('.ant-select-dropdown')).map((dropdown, index) => ({
                  index,
                  className: String(dropdown.className || ''),
                  visibleByClass: !String(dropdown.className || '').includes('hidden'),
                  rect: rectOf(dropdown),
                  text: compact(dropdown.innerText || dropdown.textContent || ''),
                  html: dropdown.outerHTML.slice(0, 3000),
                  options: Array.from(dropdown.querySelectorAll('.ant-select-item, .ant-select-item-option, .ant-select-item-option-content')).map((option, optionIndex) => ({
                    optionIndex,
                    className: String(option.className || ''),
                    rect: rectOf(option),
                    text: compact(option.innerText || option.textContent || ''),
                    html: option.outerHTML.slice(0, 800),
                  })),
                })),
              };
            }"""
        )
        page.screenshot(path=str(screenshot_path), full_page=True)
        json_path.write_text(json.dumps(summary, ensure_ascii=False, indent=2), encoding="utf-8")
        print(f"screenshot: {screenshot_path}")
        print(f"json: {json_path}")
        print(json.dumps(summary, ensure_ascii=False, indent=2)[:10000])
        browser.close()


if __name__ == "__main__":
    main()
