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 Page, 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 WanyoujiMemberData, WanyoujiMemberPage
from e2e.pages.wanzhanggui_order_page import WANYOUJI_CONSOLE_URL, WanyoujiFulfillmentPage
from e2e.utils.account_store import account_store
from e2e.utils.verification_code import FeishuConfig, VerificationCodeProvider


OUT_DIR = Path("runtime/probes/player_manual_operation")


def main() -> None:
    load_dotenv(ROOT_DIR / ".env")
    store = account_store()
    payload = store.load_payload()
    phone = os.getenv("E2E_TASK_PLAYER_PHONE", "").strip()
    source_order_no = os.getenv("E2E_TASK_SOURCE_ORDER_NO", "").strip()
    order_title = ""
    if not phone:
        orders = sorted(
            [
                item
                for item in payload.get("dispatched_orders", [])
                if item.get("task_player_phone") and item.get("status") in {"task_player_accepted", "delivery_started"}
            ],
            key=lambda item: item.get("updated_at", item.get("created_at", "")),
            reverse=True,
        )
        if orders:
            phone = orders[0]["task_player_phone"]
            source_order_no = source_order_no or orders[0].get("source_order_no", "")
            order_title = orders[0].get("order_title", "")
    elif source_order_no:
        for item in payload.get("dispatched_orders", []):
            if item.get("source_order_no") == source_order_no:
                order_title = item.get("order_title", "")
                break
    if not phone:
        raise SystemExit("未找到打手账号，请设置 E2E_TASK_PLAYER_PHONE")
    player = store.find(phone=phone)
    if player is None:
        raise SystemExit(f"台账中未找到打手账号：{phone}")

    provider = VerificationCodeProvider(
        mode=os.getenv("E2E_VERIFICATION_CODE_MODE", "feishu"),
        static_code=os.getenv("E2E_VERIFICATION_CODE_STATIC", ""),
        manual_code_file=os.getenv("E2E_MANUAL_CODE_FILE", "runtime/sms_code.txt"),
        manual_timeout_seconds=int(os.getenv("E2E_MANUAL_CODE_TIMEOUT_SECONDS", "180")),
        manual_poll_interval_seconds=int(os.getenv("E2E_MANUAL_CODE_POLL_INTERVAL_SECONDS", "2")),
        feishu_config=FeishuConfig(
            app_id=os.getenv("FEISHU_APP_ID", ""),
            app_secret=os.getenv("FEISHU_APP_SECRET", ""),
            chat_id=os.getenv("FEISHU_CHAT_ID", ""),
            timeout_seconds=int(os.getenv("FEISHU_TIMEOUT_SECONDS", "60")),
            poll_interval_seconds=int(os.getenv("FEISHU_POLL_INTERVAL_SECONDS", "3")),
        ),
    )

    OUT_DIR.mkdir(parents=True, exist_ok=True)
    run_id = datetime.now().strftime("%Y%m%d-%H%M%S")
    run_dir = OUT_DIR / f"{run_id}-{phone}"
    run_dir.mkdir(parents=True, exist_ok=True)

    with sync_playwright() as playwright:
        browser = playwright.chromium.launch(headless=False, slow_mo=80)
        context = browser.new_context(viewport={"width": 1920, "height": 1080})
        page = context.new_page()
        member_page = WanyoujiMemberPage(
            page,
            "https://test-lianlianyun.lianlianwz.com/home",
            code_provider=provider,
        )
        member = WanyoujiMemberData(
            phone=player.phone,
            password=player.password,
            role=player.member_role or "打手",
            name=player.contact_name,
            product="丸友集",
        )
        member_page.verify_member_can_login_by_sms(member)
        if source_order_no:
            fulfillment_page = WanyoujiFulfillmentPage(page, "https://test-lianlianyun.lianlianwz.com/home")
            fulfillment_page.verify_order_in_player_my_orders(source_order_no, order_title)
        else:
            page.goto(WANYOUJI_CONSOLE_URL, wait_until="domcontentloaded")
            page.wait_for_timeout(3000)

        print(f"已登录打手账号：{player.phone} / {player.contact_name}")
        print(f"当前订单：{source_order_no or '<未指定>'}")
        print(f"观察记录目录：{run_dir.resolve()}")
        print("现在可以在浏览器中操作。脚本会记录 10 分钟，完成后可关闭浏览器。")

        observe(page, run_dir, seconds=int(os.getenv("E2E_MANUAL_OBSERVE_SECONDS", "600")))
        context.close()
        browser.close()


def observe(page: Page, run_dir: Path, seconds: int) -> None:
    started = datetime.now()
    last_url = ""
    last_text = ""
    events = []
    for index in range(seconds // 3):
        page.wait_for_timeout(3000)
        timestamp = datetime.now().strftime("%Y%m%d-%H%M%S")
        prefix = run_dir / f"{index + 1:03d}-{timestamp}"
        try:
            url = page.url
            text = page.locator("body").inner_text(timeout=3000)
            frames = []
            for frame in page.frames:
                frame_text = ""
                try:
                    frame_text = frame.locator("body").inner_text(timeout=1000)
                except Exception:
                    pass
                frames.append({"url": frame.url, "text": frame_text[:2000]})
            if url != last_url or text[:1000] != last_text[:1000] or index % 10 == 0:
                page.screenshot(path=prefix.with_suffix(".png"), full_page=True)
                snapshot = {
                    "index": index + 1,
                    "started_at": started.isoformat(timespec="seconds"),
                    "captured_at": datetime.now().isoformat(timespec="seconds"),
                    "url": url,
                    "text": text[:4000],
                    "frames": frames,
                }
                prefix.with_suffix(".json").write_text(
                    json.dumps(snapshot, ensure_ascii=False, indent=2),
                    encoding="utf-8",
                )
                events.append({"index": index + 1, "url": url, "text": text[:800]})
                (run_dir / "events.json").write_text(
                    json.dumps(events, ensure_ascii=False, indent=2),
                    encoding="utf-8",
                )
                last_url = url
                last_text = text
        except Exception as exc:
            (prefix.with_suffix(".error.txt")).write_text(str(exc), encoding="utf-8")


if __name__ == "__main__":
    main()
