import os
import sys
import time
import ctypes
from ctypes import wintypes
import numpy as np

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

from src.common.win32_window import attach_to_default_desktop, find_poe2_window
from src.common.virtual_display_manager import capture_virtual_display

attach_to_default_desktop()
user32 = ctypes.windll.user32
kernel32 = ctypes.windll.kernel32

hwnd = find_poe2_window()
print(f"PoE2 HWND: {hex(hwnd)}")

class KEYBDINPUT(ctypes.Structure):
    _fields_ = [
        ("wVk", wintypes.WORD),
        ("wScan", wintypes.WORD),
        ("dwFlags", wintypes.DWORD),
        ("time", wintypes.DWORD),
        ("dwExtraInfo", ctypes.c_ulong),
    ]

class INPUT_I(ctypes.Union):
    _fields_ = [("ki", KEYBDINPUT)]

class INPUT(ctypes.Structure):
    _fields_ = [("type", wintypes.DWORD), ("i", INPUT_I)]

INPUT_KEYBOARD = 1
KEYEVENTF_SCANCODE = 0x0008
KEYEVENTF_KEYUP = 0x0002
SC_W = 0x11
VK_W = 0x57
VK_MENU = 0x12

# 1. Capture before
img1 = capture_virtual_display()
img1.save("captures/test_real_fg_before.png")

# 2. Save original foreground window
fg_orig = user32.GetForegroundWindow()
print(f"Original Foreground: {hex(fg_orig)}")

# 3. Bring PoE2 to foreground with Alt-key bypass & AttachThreadInput
cur_tid = kernel32.GetCurrentThreadId()
poe_tid = user32.GetWindowThreadProcessId(hwnd, None)
fg_tid = user32.GetWindowThreadProcessId(fg_orig, None) if fg_orig else 0

if fg_tid and cur_tid != fg_tid:
    user32.AttachThreadInput(cur_tid, fg_tid, True)
if poe_tid and cur_tid != poe_tid:
    user32.AttachThreadInput(cur_tid, poe_tid, True)

user32.keybd_event(VK_MENU, 0, 0, 0)
user32.BringWindowToTop(hwnd)
user32.SetForegroundWindow(hwnd)
user32.SetActiveWindow(hwnd)
user32.SetFocus(hwnd)
user32.keybd_event(VK_MENU, 0, 2, 0)
time.sleep(0.08)

fg_now = user32.GetForegroundWindow()
print(f"Foreground now: {hex(fg_now)} (Expected {hex(hwnd)})")

try:
    if fg_now == hwnd or True:
        # Send W key via SendInput
        inp_down = (INPUT * 2)()
        inp_down[0].type = INPUT_KEYBOARD
        inp_down[0].i.ki.wScan = SC_W
        inp_down[0].i.ki.dwFlags = KEYEVENTF_SCANCODE
        inp_down[1].type = INPUT_KEYBOARD
        inp_down[1].i.ki.wVk = VK_W

        user32.SendInput(2, inp_down, ctypes.sizeof(INPUT))
        print("Holding W for 0.8s...")
        time.sleep(0.8)

        inp_up = (INPUT * 2)()
        inp_up[0].type = INPUT_KEYBOARD
        inp_up[0].i.ki.wScan = SC_W
        inp_up[0].i.ki.dwFlags = KEYEVENTF_SCANCODE | KEYEVENTF_KEYUP
        inp_up[1].type = INPUT_KEYBOARD
        inp_up[1].i.ki.wVk = VK_W
        inp_up[1].i.ki.dwFlags = KEYEVENTF_KEYUP

        user32.SendInput(2, inp_up, ctypes.sizeof(INPUT))
        time.sleep(0.1)
finally:
    # Immediately restore original foreground window
    if fg_orig and fg_orig != hwnd:
        user32.keybd_event(VK_MENU, 0, 0, 0)
        user32.SetForegroundWindow(fg_orig)
        user32.keybd_event(VK_MENU, 0, 2, 0)
    if fg_tid and cur_tid != fg_tid:
        user32.AttachThreadInput(cur_tid, fg_tid, False)
    if poe_tid and cur_tid != poe_tid:
        user32.AttachThreadInput(cur_tid, poe_tid, False)
    print("Restored original foreground window.")

# 4. Capture after
img2 = capture_virtual_display()
img2.save("captures/test_real_fg_after.png")

a1 = np.array(img1, dtype=np.float32)
a2 = np.array(img2, dtype=np.float32)
diff = np.abs(a2 - a1)
mean_diff = np.mean(diff)
player_diff = np.mean(diff[440:640, 860:1060])
print(f"Mean Diff: {mean_diff:.4f}, Player Diff: {player_diff:.4f}")
if player_diff > 10.0 or mean_diff > 5.0:
    print(">>> SUCCESS! CHARACTER ACTUALLY MOVED! <<<")
else:
    print(f"Difference level: {mean_diff:.2f}")
