from __future__ import annotations

import json
import os
import sys
from datetime import datetime
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.wanzhanggui_order_page import WanyoujiFulfillmentPage
from e2e.utils.account_store import account_store


def main() -> None:
    load_dotenv()
    source_order_no = os.getenv("E2E_S_FLOW_SOURCE_ORDER_NO", "E2EORDER0616113406")
    wanyouji_phone = os.getenv("E2E_ORDER_WANYOUJI_PHONE", "19988611833")
    account = account_store().find(phone=wanyouji_phone)
    if not account:
        raise AssertionError(f"未找到丸友集账号：{wanyouji_phone}")

    out_dir = Path("runtime/probes/s_flow_013_reject_modal") / datetime.now().strftime("%Y%m%d-%H%M%S")
    out_dir.mkdir(parents=True, exist_ok=True)

    with sync_playwright() as playwright:
        browser = playwright.chromium.launch(headless=False, slow_mo=120)
        context = browser.new_context(viewport={"width": 1920, "height": 1080})
        page = context.new_page()
        fulfillment = WanyoujiFulfillmentPage(page, "https://test-lianlianyun.lianlianwz.com/home")
        fulfillment.login_main_account(account.phone, account.password)
        frames = fulfillment.open_order_hall()

        result: dict = {
            "source_order_no": source_order_no,
            "wanyouji_phone": account.phone,
            "frames": [frame.url for frame in page.frames],
            "attempts": [],
        }

        target_frame = None
        for frame in frames:
            try:
                if not fulfillment.frame_has_order_hall_tabs(frame):
                    continue
                fulfillment.click_order_hall_tab(frame, "私单")
                fulfillment.search_order_by_labels(frame, source_order_no, ["来源单号"])
                text = frame.locator("body").inner_text(timeout=5000)
                row_text = fulfillment.order_hall_row_text(frame, [source_order_no])
                result["attempts"].append({"frame_url": frame.url, "body_has_source": source_order_no in text, "row_text": row_text})
                if source_order_no in text:
                    target_frame = frame
                    break
            except Exception as exc:
                result["attempts"].append({"frame_url": frame.url, "error": str(exc)})

        assert target_frame is not None, f"未在抢单大厅找到来源单号：{source_order_no}"

        dom = target_frame.evaluate(
            """sourceOrderNo => {
                const rect = el => {
                  const r = el.getBoundingClientRect();
                  return { x: Math.round(r.x), y: Math.round(r.y), w: Math.round(r.width), h: Math.round(r.height) };
                };
                const visible = el => {
                  const r = el.getBoundingClientRect();
                  return r.width > 0 && r.height > 0;
                };
                const all = Array.from(document.querySelectorAll('*'));
                const sourceNodes = all
                  .filter(el => visible(el) && (el.innerText || el.textContent || '').includes(sourceOrderNo))
                  .sort((a, b) => {
                    const ar = a.getBoundingClientRect();
                    const br = b.getBoundingClientRect();
                    return (ar.width * ar.height) - (br.width * br.height);
                  })
                  .slice(0, 12)
                  .map(el => {
                    const chain = [];
                    for (let node = el; node && node !== document.body && chain.length < 8; node = node.parentElement) {
                      chain.push({
                        tag: node.tagName,
                        cls: String(node.className || ''),
                        role: node.getAttribute('role') || '',
                        onclick: Boolean(node.onclick),
                        cursor: window.getComputedStyle(node).cursor,
                        rect: rect(node),
                        text: (node.innerText || node.textContent || '').trim().slice(0, 500),
                      });
                    }
                    return { tag: el.tagName, cls: String(el.className || ''), rect: rect(el), text: (el.innerText || el.textContent || '').trim().slice(0, 800), chain };
                  });
                const rejectNodes = all
                  .filter(el => visible(el) && (el.innerText || el.textContent || '').trim().includes('拒绝接单'))
                  .map(el => {
                    const clickable = el.closest('button, a, [role="button"], taro-view-core, taro-text-core') || el;
                    return {
                      tag: el.tagName,
                      cls: String(el.className || ''),
                      rect: rect(el),
                      text: (el.innerText || el.textContent || '').trim(),
                      clickableTag: clickable.tagName,
                      clickableClass: String(clickable.className || ''),
                      clickableRole: clickable.getAttribute('role') || '',
                      clickableOnclick: Boolean(clickable.onclick),
                      clickableCursor: window.getComputedStyle(clickable).cursor,
                      clickableRect: rect(clickable),
                      parentChain: (() => {
                        const chain = [];
                        for (let node = el; node && node !== document.body && chain.length < 8; node = node.parentElement) {
                          chain.push({
                            tag: node.tagName,
                            cls: String(node.className || ''),
                            role: node.getAttribute('role') || '',
                            onclick: Boolean(node.onclick),
                            cursor: window.getComputedStyle(node).cursor,
                            rect: rect(node),
                            text: (node.innerText || node.textContent || '').trim().slice(0, 500),
                          });
                        }
                        return chain;
                      })(),
                    };
                  });
                return { sourceNodes, rejectNodes };
            }""",
            source_order_no,
        )
        result["dom_before_click"] = dom

        clicked = target_frame.evaluate(
            """sourceOrderNo => {
                const visible = el => {
                  const r = el.getBoundingClientRect();
                  return r.width > 0 && r.height > 0;
                };
                const sourceNodes = Array.from(document.querySelectorAll('*'))
                  .filter(el => visible(el) && (el.innerText || el.textContent || '').includes(sourceOrderNo))
                  .sort((a, b) => {
                    const ar = a.getBoundingClientRect();
                    const br = b.getBoundingClientRect();
                    return (ar.width * ar.height) - (br.width * br.height);
                  });
                const anchor = sourceNodes[0];
                if (!anchor) return { ok: false, reason: 'no source anchor' };
                const ar = anchor.getBoundingClientRect();
                const rejectNodes = Array.from(document.querySelectorAll('button, a, [role="button"], span, div, taro-view-core, taro-text-core'))
                  .map(el => {
                    const text = (el.innerText || el.textContent || '').trim();
                    const r = el.getBoundingClientRect();
                    return { el, text, r };
                  })
                  .filter(item => item.r.width > 0 && item.r.height > 0 && item.text === '拒绝接单')
                  .filter(item => item.r.y >= ar.y - 80 && item.r.y <= ar.y + Math.max(ar.height, 260))
                  .sort((a, b) => Math.abs(a.r.y - ar.y) - Math.abs(b.r.y - ar.y) || (a.r.width * a.r.height) - (b.r.width * b.r.height));
                const target = rejectNodes[0];
                if (!target) return { ok: false, reason: 'no reject target near source', anchor: { x: ar.x, y: ar.y, w: ar.width, h: ar.height } };
                let clickable = target.el.closest('button, a, [role="button"]') || target.el;
                const cr = clickable.getBoundingClientRect();
                const x = cr.x + cr.width / 2;
                const y = cr.y + cr.height / 2;
                clickable.scrollIntoView({ block: 'center', inline: 'center' });
                for (const type of ['mouseover', 'pointerover', 'pointerdown', 'mousedown', 'pointerup', 'mouseup', 'click']) {
                  clickable.dispatchEvent(new MouseEvent(type, { bubbles: true, cancelable: true, clientX: x, clientY: y }));
                }
                if (typeof clickable.click === 'function') clickable.click();
                return {
                  ok: true,
                  tag: clickable.tagName,
                  cls: String(clickable.className || ''),
                  text: (clickable.innerText || clickable.textContent || '').trim(),
                  rect: { x: cr.x, y: cr.y, w: cr.width, h: cr.height },
                };
            }""",
            source_order_no,
        )
        result["click_result"] = clicked
        page.wait_for_timeout(1500)

        modal_script = """() => Array.from(document.querySelectorAll('.ant-modal, .ant-popover, .ant-popconfirm'))
          .map((el, index) => {
            const r = el.getBoundingClientRect();
            const fields = Array.from(el.querySelectorAll('input, textarea')).map(field => ({
              tag: field.tagName,
              placeholder: field.getAttribute('placeholder') || '',
              value: field.value || '',
              rect: { x: Math.round(field.getBoundingClientRect().x), y: Math.round(field.getBoundingClientRect().y), w: Math.round(field.getBoundingClientRect().width), h: Math.round(field.getBoundingClientRect().height) },
            }));
            return { index, visible: r.width > 0 && r.height > 0, rect: { x: Math.round(r.x), y: Math.round(r.y), w: Math.round(r.width), h: Math.round(r.height) }, text: (el.innerText || el.textContent || '').trim(), fields };
          })"""
        result["frame_modals_after_click"] = target_frame.evaluate(modal_script)
        result["page_modals_after_click"] = page.evaluate(modal_script)
        result["modal_text_helper"] = fulfillment.reject_order_modal_text(target_frame)

        page.screenshot(path=out_dir / "page_after_click.png", full_page=True)
        try:
            target_frame.locator("body").screenshot(path=out_dir / "frame_after_click.png", timeout=5000)
        except Exception:
            pass
        (out_dir / "result.json").write_text(json.dumps(result, ensure_ascii=False, indent=2), encoding="utf-8")
        print(str(out_dir / "result.json"))
        context.close()
        browser.close()


if __name__ == "__main__":
    main()
