"""
Script chẩn đoán và nghiệm thu trực quan:
1. Khởi chạy PathOfExile.exe (elevated runas)
2. Theo dõi tiến trình và tìm HWND chính xác qua PID
3. Chờ game ổn định (sau giai đoạn D3D12/Streamline handshake)
4. Dời cửa sổ sang Màn hình ảo Monitor 2 (Virtual Display) bằng SWP_NOSIZE an toàn
5. Chụp ảnh màn hình ảo Monitor 2 (Live PiP capture) và lưu vào captures/poe2_virtual_display_live.png
6. Chụp ảnh màn hình chính Monitor 1 để chứng minh desktop người dùng hoàn toàn không bị ảnh hưởng!
"""
import ctypes
import os
import sys
import time
import psutil
import win32gui
import win32process

if sys.platform == "win32":
    sys.stdout.reconfigure(encoding="utf-8", errors="replace")

sys.path.insert(0, r"C:\Projects\AutoPOE2")

from src.common.virtual_display_manager import (
    get_virtual_monitor,
    get_all_monitors,
    is_window_on_virtual_display,
    move_window_to_virtual_display,
    capture_virtual_display,
)

target_exe = r"C:\Program Files (x86)\Grinding Gear Games\Path of Exile 2\PathOfExile.exe"
working_dir = os.path.dirname(target_exe)
client_log = os.path.join(working_dir, "logs", "Client.txt")

vm = get_virtual_monitor()
print(f"[Launcher] Màn hình ảo phụ (Monitor 2): {vm.device if vm else 'KHÔNG TÌM THẤY'} ({vm.width}x{vm.height} tại {vm.left},{vm.top})", flush=True)

print(f"[Launcher] Khởi chạy POE2 từ: {target_exe}...", flush=True)
ret = ctypes.windll.shell32.ShellExecuteW(None, "runas", target_exe, None, working_dir, 1)
print(f"[Launcher] ShellExecuteW mã trả về: {ret}", flush=True)
if ret <= 32:
    print(f"[Launcher Error] Không thể khởi chạy, mã lỗi: {ret}", flush=True)
    sys.exit(1)

last_log_size = os.path.getsize(client_log) if os.path.exists(client_log) else 0
poe_pid = None
poe_hwnd = None
moved_to_vd = False

for sec in range(1, 40):
    time.sleep(1.0)
    
    # 1. Tìm PID nếu chưa có
    if not poe_pid:
        for p in psutil.process_iter(["pid", "name"]):
            try:
                name = (p.info["name"] or "").lower()
                if "pathofexile" in name:
                    poe_pid = p.pid
                    break
            except Exception:
                pass

    # 2. Tìm HWND của PID
    if poe_pid and not poe_hwnd:
        def _enum_find_hwnd(hwnd, _):
            global poe_hwnd
            if win32gui.IsWindowVisible(hwnd):
                _, w_pid = win32process.GetWindowThreadProcessId(hwnd)
                if w_pid == poe_pid:
                    poe_hwnd = hwnd
                    return False
            return True
        win32gui.EnumWindows(_enum_find_hwnd, None)

    # 3. Đọc log mới
    new_logs = []
    if os.path.exists(client_log):
        cur_size = os.path.getsize(client_log)
        if cur_size > last_log_size:
            with open(client_log, "r", encoding="utf-8", errors="ignore") as f:
                f.seek(last_log_size)
                new_logs = [l.strip() for l in f.readlines() if l.strip()]
            last_log_size = cur_size

    # 4. Kiểm tra trạng thái cửa sổ
    status_parts = []
    if poe_pid:
        try:
            p = psutil.Process(poe_pid)
            rss = p.memory_info().rss / (1024 * 1024)
            status_parts.append(f"PID={poe_pid} (RSS={rss:.1f}MB)")
        except Exception:
            status_parts.append(f"PID={poe_pid} (DEAD)")
            poe_pid = None
    else:
        status_parts.append("PID=None (OFFLINE)")

    if poe_hwnd and win32gui.IsWindow(poe_hwnd):
        rect = win32gui.GetWindowRect(poe_hwnd)
        title = win32gui.GetWindowText(poe_hwnd)
        on_vd = is_window_on_virtual_display(poe_hwnd, vm) if vm else False
        status_parts.append(f"HWND={poe_hwnd} Rect={rect} OnVD={on_vd}")
    else:
        status_parts.append("HWND=None")

    print(f"[{sec:02d}s] {' | '.join(status_parts)}", flush=True)
    for nl in new_logs:
        print(f"     [Log] {nl}", flush=True)

    # 5. Dời cửa sổ sang màn hình ảo sau khi game đã nạp scene (khoảng giây thứ 22-25)
    if sec >= 22 and poe_hwnd and win32gui.IsWindow(poe_hwnd) and not moved_to_vd and vm:
        user32 = ctypes.windll.user32
        is_hung = user32.IsHungAppWindow(poe_hwnd)
        if not is_hung:
            print(f"[{sec:02d}s] >>> THỰC HIỆN DỜI CỬA SỔ HWND {poe_hwnd} SANG MÀN HÌNH ẢO {vm.device}...", flush=True)
            ok = move_window_to_virtual_display(poe_hwnd, vm, borderless=False, keep_size=True)
            print(f"[{sec:02d}s] >>> Kết quả dời cửa sổ: {ok}", flush=True)
            moved_to_vd = ok
            time.sleep(1.0)
            
            # Chụp ảnh nghiệm thu từ màn hình ảo Monitor 2
            os.makedirs("captures", exist_ok=True)
            vd_img = capture_virtual_display(vm)
            if vd_img:
                vd_path = "captures/poe2_virtual_display_live.png"
                vd_img.save(vd_path)
                print(f"[{sec:02d}s] [CHỨNG THỰC THỰC NGHIỆM] Đã chụp ảnh màn hình ảo: {vd_path} ({vd_img.size})", flush=True)
            else:
                print(f"[{sec:02d}s] [Cảnh báo] Không chụp được ảnh màn hình ảo.", flush=True)

    if not poe_pid and sec > 5:
        print(f"[{sec:02d}s] Tiến trình game đã tắt.", flush=True)
        break
