"""AutoPOE2 - Execute Full Reconnect Pipeline (Post-Maintenance Phase 2).
=====================================================================
Quy trình khởi chạy và tái kết nối tự động có giám sát trên POE2 v0.5.5c:
1. KHÔNG dọn dẹp Shader cache (giữ nguyên cache để D3D12 nạp bytecode trong 4.0s).
2. Khởi chạy PathOfExile.exe với cờ CREATE_NEW_PROCESS_GROUP = 0x200.
3. Đón bắt cửa sổ POEWindowClass và gán cờ HWND_TOPMOST & Foreground.
4. Kích hoạt trực tiếp kịch bản Reconnect đưa Monk CI vào Shoreline Hideout.
5. Xác thực sự kiện chuyển cảnh Hideout từ Client.txt theo đúng PID tiến trình.
6. Ghi nhận trung thực Vitals từ OCR (RAM PE x64 v0.5.5c pending R&D offset, Rule 5: No Hardcode).
7. Duy trì Grace Period 10s & kích hoạt F8 Emergency Pause (INV-F8-MUTES-BRAIN).
8. Treo daemon proc.wait() để duy trì phiên game vĩnh viễn.
"""

from __future__ import annotations

import ctypes
import json
import os
import subprocess
import sys
import time
from datetime import datetime
from pathlib import Path
from typing import Any, Dict, Optional

try:
    if hasattr(sys.stdout, "reconfigure"):
        sys.stdout.reconfigure(encoding="utf-8")
        sys.stderr.reconfigure(encoding="utf-8")
except Exception:
    pass

sys.path.insert(0, str(Path(__file__).resolve().parent.parent))

from src.common.win32_input import emergency_f8_pause_and_release_all
from src.common.win32_window import attach_to_default_desktop, ensure_window_focus, find_poe2_window
import scripts.reconnect_and_enter_hideout as rc_mod


def log(msg: str, level: str = "INFO"):
    ts = datetime.now().strftime("%H:%M:%S.%f")[:-3]
    print(f"[{ts}][{level}][ReconnectPipeline] {msg}", flush=True)


def bring_window_topmost(hwnd: int) -> bool:
    """Đưa cửa sổ POE2 lên Foreground và thiết lập cờ HWND_TOPMOST."""
    if not hwnd or not ctypes.windll.user32.IsWindow(hwnd):
        return False
    from src.common.win32_window import attach_to_default_desktop, ensure_window_focus
    attach_to_default_desktop()
    user32 = ctypes.windll.user32
    SW_RESTORE = 9
    HWND_TOPMOST = -1
    SWP_NOSIZE = 0x0001
    SWP_NOMOVE = 0x0002
    SWP_SHOWWINDOW = 0x0040

    user32.ShowWindow(hwnd, SW_RESTORE)
    user32.SetWindowPos(hwnd, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_SHOWWINDOW)
    ensure_window_focus(hwnd)
    time.sleep(0.3)
    return True


def launch_poe2_via_wmi(exe_path: str, working_dir: str) -> Optional[int]:
    """Khởi chạy POE2 qua WMI Win32_Process.Create để tách hoàn toàn khỏi Task Job Object."""
    try:
        import win32com.client
        wmi = win32com.client.GetObject("winmgmts:")
        proc = wmi.Get("Win32_Process")
        in_params = proc.Methods_("Create").InParameters.SpawnInstance_()
        in_params.CommandLine = f'"{exe_path}"'
        in_params.CurrentDirectory = working_dir
        out = proc.ExecMethod_("Create", in_params)
        if int(out.ReturnValue) == 0:
            return int(out.ProcessId)
        log(f"WMI Create trả về mã lỗi: {out.ReturnValue}", level="WARN")
    except Exception as e:
        log(f"Lỗi khởi chạy WMI qua COM: {e}", level="WARN")
    return None


def main():
    exe_path = r"C:\Program Files (x86)\Grinding Gear Games\Path of Exile 2\PathOfExile.exe"
    working_dir = os.path.dirname(exe_path)

    if not os.path.exists(exe_path):
        log(f"❌ Không tìm thấy binary game tại: {exe_path}", level="ERROR")
        return False

    log("--- BƯỚC 1: KHỞI CHẠY POE2 CLIENT QUA WMI BREAKAWAY (GIỮ NGUYÊN SHADER CACHE) ---")
    pid = launch_poe2_via_wmi(exe_path, working_dir)
    if pid:
        log(f"✅ Đã khởi chạy POE2 client độc lập qua WMI thành công, PID: {pid}")
    else:
        log("⚠️ Khởi chạy WMI COM thất bại, fallback sang ShellExecuteW...", level="WARN")
        ctypes.windll.shell32.ShellExecuteW(None, "open", exe_path, None, working_dir, 1)

    if not pid:
        from src.common.win32_process import find_process_by_name
        for _ in range(20):
            time.sleep(0.5)
            p = find_process_by_name("PathOfExile.exe")
            if p:
                pid = p[0]
                break
    log(f"✅ Tiến trình POE2 đã phát hiện, PID: {pid}")
    log("--- BƯỚC 2: ĐÓN BẮT CỬA SỔ POEWindowClass (Tối đa 45s) ---")

    user32 = ctypes.windll.user32
    attach_to_default_desktop()
    found_hwnd = 0
    start_wait = time.time()

    for i in range(45):
        time.sleep(1.0)
        attach_to_default_desktop()
        h = find_poe2_window()
        if not h:
            h = user32.FindWindowW("POEWindowClass", None)
        if h:
            found_hwnd = int(h)
            elapsed = time.time() - start_wait
            log(f"🎯 ĐÃ TÌM THẤY CỬA SỔ POE2! HWND: 0x{found_hwnd:X} sau {elapsed:.1f}s")
            break
        from src.common.win32_process import is_poe2_running
        if not is_poe2_running():
            log(f"❌ Tiến trình PID {pid} đã thoát sớm.", level="ERROR")
            return False

    if not found_hwnd:
        log("❌ Không tìm thấy cửa sổ POE2 sau 45s.", level="ERROR")
        return False

    log(f"--- BƯỚC 3: ĐƯA CỬA SỔ HWND 0x{found_hwnd:X} LÊN TOPMOST & FOCUS ---")
    bring_window_topmost(found_hwnd)
    time.sleep(2.5)

    log("--- BƯỚC 4: KÍCH HOẠT KỊCH BẢN RECONNECT & ENTER HIDEOUT ---")
    rc_result = rc_mod.main(hwnd=found_hwnd, pid=pid)
    reconnect_ok = rc_result.get("success", False)
    log(f"Kết quả Reconnect: {reconnect_ok} | Zone: '{rc_result.get('zone')}'")

    if reconnect_ok:
        log("✅ Monk CI đã bước vào Shoreline Hideout thành công!")
        log("--- BƯỚC 5: DUY TRÌ GRACE PERIOD 10.0s (BẢO TOÀN BẤT KHẢ XÂM PHẠM) ---")
        time.sleep(10.0)
        log("Grace Period kết thúc.")

        log("--- BƯỚC 6: KÍCH HOẠT F8 EMERGENCY PAUSE & RELEASE ALL (INV-F8-MUTES-BRAIN) ---")
        emergency_f8_pause_and_release_all()
        log("🏁 Nhân vật Monk CI đã được park an toàn tuyệt đối tại Shoreline Hideout!")

        # Ghi nhận trung thực dữ liệu thực nghiệm (Rule 5: Authentic Data, No Hardcode)
        res_data = {
            "status": "SUCCESS",
            "pid": pid,
            "hwnd": hex(found_hwnd),
            "zone": rc_result.get("zone", "Shoreline Hideout"),
            "character": "Monk CI",
            "vitals": rc_result.get("vitals", {}),
            "ram_status": "PENDING_OFFSET_RND_v0.5.5c",
            "client_log_evidence": rc_result.get("client_log_evidence", []),
            "evidence_images": rc_result.get("evidence_images", {}),
            "grace_period_applied": True,
            "f8_pause_applied": True,
            "timestamp": datetime.now().strftime("%Y-%m-%d %H:%M:%S"),
        }
        with open("reconnect_result.json", "w", encoding="utf-8") as rf:
            json.dump(res_data, rf, indent=2, ensure_ascii=False)
        log("📊 Đã xuất kết quả thành công vào reconnect_result.json")
    else:
        log("⚠️ Reconnect chưa đạt trạng thái thành công hoàn toàn.", level="WARN")
        res_data = {
            "status": "FAILED",
            "pid": pid,
            "hwnd": hex(found_hwnd),
            "zone": rc_result.get("zone", "Unknown"),
            "error": rc_result.get("error", "Failed to enter hideout"),
            "evidence_images": rc_result.get("evidence_images", {}),
            "timestamp": datetime.now().strftime("%Y-%m-%d %H:%M:%S"),
        }
        with open("reconnect_result.json", "w", encoding="utf-8") as rf:
            json.dump(res_data, rf, indent=2, ensure_ascii=False)

    log("--- BƯỚC 7: KIỂM TRA TRẠNG THÁI TIẾN TRÌNH GAME ---")
    from src.common.win32_process import is_poe2_running
    if is_poe2_running():
        log(f"✅ Client game POE2 PID {pid} đang chạy ổn định trong background.")
    else:
        log(f"⚠️ Client game POE2 PID {pid} không còn chạy.", level="WARN")

    return reconnect_ok


if __name__ == "__main__":
    main()
