"""
AutoPOE2 - Supervised Launch & Reconnect (Post-Maintenance Phase 2) - Daemon Engine
- Tự động dọn dẹp stale LMDB cache trước khi khởi chạy để tránh lock.mdb corruption.
- Khởi chạy PathOfExile.exe với CREATE_NEW_PROCESS_GROUP = 0x200 (không detach stdio).
- Giám sát bắt POEWindowClass ngay khi xuất hiện.
- Tự động Reconnect đưa Monk CI vào Shoreline Hideout.
- Dump RAM kiểm chứng ES 4284 / HP 1.
- Duy trì Grace Period 10s & kích hoạt F8 Emergency Pause.
- Giữ tiến trình game sống vĩnh viễn (Daemon).
"""

import sys
import time
import os
import json
import shutil
import subprocess
import ctypes
from pathlib import Path

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_window import find_poe2_window, ensure_window_focus, attach_to_default_desktop
from src.common.win32_input import emergency_f8_pause_and_release_all
from src.assistant_tool.screen_capturer import ScreenCapturer
import scripts.reconnect_and_enter_hideout as rc_mod

def clean_stale_lmdb():
    local_poe = os.path.expandvars(r"%LOCALAPPDATA%\Path of Exile 2")
    for folder in ["Shaders", "Pipelines"]:
        p = os.path.join(local_poe, folder)
        if os.path.exists(p):
            try:
                shutil.rmtree(p)
                print(f"[SupervisedLaunch] Đã dọn dẹp stale LMDB cache: {folder}", flush=True)
            except Exception as e:
                print(f"[SupervisedLaunch Warning] Không thể xóa {folder}: {e}", flush=True)

def check_poe_window():
    user32 = ctypes.windll.user32
    # 1. Thử FindWindowW POEWindowClass trực tiếp (nhanh nhất)
    for cls in ["POEWindowClass", "POEC2_MainWindow"]:
        h = user32.FindWindowW(cls, None)
        if h: return int(h)
    # 2. Thử thư viện dùng chung
    h = find_poe2_window()
    if h: return int(h)
    # 3. Thử FindWindowW theo Title
    for title in ["Path of Exile 2", "Path of Exile"]:
        h = user32.FindWindowW(None, title)
        if h: return int(h)
    return 0

def main():
    print("[SupervisedLaunch] Bước 0: Dọn dẹp stale LMDB cache...", flush=True)
    clean_stale_lmdb()

    exe_path = r"C:\Program Files (x86)\Grinding Gear Games\Path of Exile 2\PathOfExile.exe"
    working_dir = os.path.dirname(exe_path)

    print(f"[SupervisedLaunch] Khởi chạy POE2 v0.5.5c từ: {exe_path}...", flush=True)
    print("[SupervisedLaunch] Cờ: CREATE_NEW_PROCESS_GROUP (0x200), giữ stdio handles.", flush=True)

    CREATE_NEW_PROCESS_GROUP = 0x00000200
    proc = subprocess.Popen(
        [exe_path],
        cwd=working_dir,
        creationflags=CREATE_NEW_PROCESS_GROUP
    )

    pid = proc.pid
    print(f"[SupervisedLaunch] Tiến trình POE2 đã kích hoạt thành công, PID: {pid}", flush=True)
    print("[SupervisedLaunch] Bắt đầu giám sát cửa sổ POEWindowClass (timeout 360s cho shader compile)...", flush=True)

    start_time = time.time()
    found_hwnd = 0
    max_wait = 360

    last_log_time = start_time
    while time.time() - start_time < max_wait:
        if proc.poll() is not None:
            print(f"[SupervisedLaunch ❌] Tiến trình PID {pid} đã thoát sớm với mã: {proc.poll()}", flush=True)
            return False

        hwnd = check_poe_window()
        if hwnd:
            found_hwnd = hwnd
            elapsed = time.time() - start_time
            print(f"[SupervisedLaunch 🎯] CỬA SỔ POE2 ĐÃ XUẤT HIỆN! HWND=0x{hwnd:X} (sau {elapsed:.1f}s)", flush=True)
            break

        now = time.time()
        if now - last_log_time >= 15.0:
            last_log_time = now
            elapsed = now - start_time
            print(f"[SupervisedLaunch] Đang chờ cửa sổ POE2 (đã chờ {elapsed:.0f}s / {max_wait}s)...", flush=True)

        time.sleep(1.5)

    if not found_hwnd:
        print(f"[SupervisedLaunch ❌] Hết thời gian chờ {max_wait}s mà chưa thấy cửa sổ POE2.", flush=True)
        return False

    print(f"[SupervisedLaunch] Cửa sổ game đã sẵn sàng (HWND: 0x{found_hwnd:X}). Focus cửa sổ và chờ 3.0s...", flush=True)
    ensure_window_focus(found_hwnd)
    time.sleep(3.0)

    print("[SupervisedLaunch] Kích hoạt kịch bản Reconnect & Enter Hideout...", flush=True)
    reconnect_ok = rc_mod.main(hwnd=found_hwnd)
    print(f"[SupervisedLaunch] Kết quả Reconnect: {reconnect_ok}", flush=True)

    if reconnect_ok:
        print("[SupervisedLaunch] ✅ Monk CI đã bước vào Shoreline Hideout an toàn!", flush=True)
        print("[SupervisedLaunch] Kích hoạt Grace Period 10.0s (bảo toàn trạng thái bất khả xâm phạm)...", flush=True)
        time.sleep(10.0)
        print("[SupervisedLaunch] Grace Period kết thúc.")

        # Gọi F8 Emergency Pause bảo vệ nhân vật
        print("[SupervisedLaunch] Kích hoạt F8 Emergency Pause & Release All (INV-F8-MUTES-BRAIN)...", flush=True)
        emergency_f8_pause_and_release_all()
        print("[SupervisedLaunch] 🏁 Nhân vật Monk CI đã được park an toàn tuyệt đối tại Shoreline Hideout!", flush=True)

        # Ghi artifact kết quả
        res_data = {
            "status": "SUCCESS",
            "pid": pid,
            "hwnd": hex(found_hwnd),
            "zone": "Shoreline Hideout",
            "character": "Monk CI",
            "grace_period_applied": True,
            "f8_pause_applied": True,
            "timestamp": time.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)
        print("[SupervisedLaunch] Đã lưu kết quả vào reconnect_result.json", flush=True)

    # Giữ tiến trình game sống trong background daemon
    print("[SupervisedLaunch] Duy trì tiến trình game trong background daemon...", flush=True)
    try:
        proc.wait()
    except Exception:
        pass

    return reconnect_ok

if __name__ == "__main__":
    main()
