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 find_poe2_window
from src.common.virtual_display_manager import capture_virtual_display

user32 = ctypes.windll.user32
kernel32 = ctypes.windll.kernel32

hwnd = find_poe2_window()
print(f"Testing SendInput with temporary foreground on HWND: {hex(hwnd)}")

# Define SendInput structures
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

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

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

# 3. Bring PoE2 to foreground
cur_tid = kernel32.GetCurrentThreadId()
poe_tid = user32.GetWindowThreadProcessId(hwnd, None)
user32.AttachThreadInput(cur_tid, poe_tid, True)
user32.SetForegroundWindow(hwnd)
user32.SetActiveWindow(hwnd)
user32.SetFocus(hwnd)
time.sleep(0.05)

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

try:
    # Key down W (both scancode and vk)
    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)

    # Key up W
    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:
    # 4. Restore original foreground window immediately
    if fg_orig and fg_orig != hwnd:
        user32.SetForegroundWindow(fg_orig)
    user32.AttachThreadInput(cur_tid, poe_tid, False)
    print("Restored original foreground window.")

# 5. Capture after
img2 = capture_virtual_display()
img2.save("captures/test_sendinput_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 MOVED WITH SENDINPUT! <<<")
else:
    print(f"Difference level: {mean_diff:.2f}")
