import os
import sys
import time
import math
import ctypes
from ctypes import wintypes

sys.path.insert(0, r"c:\Projects\AutoPOE2")
from src.common.win32_window import attach_to_default_desktop, find_poe2_window

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

attach_to_default_desktop()
hwnd = find_poe2_window()
if not hwnd:
    hwnd = 0x8db02d4 # known live HWND

log_lines = [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
VK_MENU = 0x12
VK_W = 0x57
SC_W = 0x11
VK_A = 0x41
SC_A = 0x1E

def key_down(vk, sc):
    inp = (INPUT * 2)()
    inp[0].type = INPUT_KEYBOARD
    inp[0].i.ki.wScan = sc
    inp[0].i.ki.dwFlags = KEYEVENTF_SCANCODE
    inp[1].type = INPUT_KEYBOARD
    inp[1].i.ki.wVk = vk
    user32.SendInput(2, inp, ctypes.sizeof(INPUT))

def key_up(vk, sc):
    inp = (INPUT * 2)()
    inp[0].type = INPUT_KEYBOARD
    inp[0].i.ki.wScan = sc
    inp[0].i.ki.dwFlags = KEYEVENTF_SCANCODE | KEYEVENTF_KEYUP
    inp[1].type = INPUT_KEYBOARD
    inp[1].i.ki.wVk = vk
    inp[1].i.ki.dwFlags = KEYEVENTF_KEYUP
    user32.SendInput(2, inp, ctypes.sizeof(INPUT))

# Save original foreground
fg_orig = user32.GetForegroundWindow()
log_lines.append(f"Original FG: {hex(fg_orig)}")

# Attach thread input to current foreground thread
cur_tid = kernel32.GetCurrentThreadId()
poe_pid = wintypes.DWORD()
poe_tid = user32.GetWindowThreadProcessId(hwnd, ctypes.byref(poe_pid))
fg_tid = user32.GetWindowThreadProcessId(fg_orig, None) if fg_orig else 0

attached_fg = False
attached_poe = False
if fg_tid and cur_tid != fg_tid:
    attached_fg = bool(user32.AttachThreadInput(cur_tid, fg_tid, True))
if poe_tid and cur_tid != poe_tid:
    attached_poe = bool(user32.AttachThreadInput(cur_tid, poe_tid, True))

log_lines.append(f"Attached fg={attached_fg}, poe={attached_poe}")

# Alt-bypass
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.1)

fg_now = user32.GetForegroundWindow()
log_lines.append(f"FG now: {hex(fg_now)}")

try:
    log_lines.append("Step 1: Holding W for 1.3s...")
    key_down(VK_W, SC_W)
    time.sleep(1.3)
    key_up(VK_W, SC_W)
    time.sleep(0.2)

    log_lines.append("Step 2: Holding A for 1.3s...")
    key_down(VK_A, SC_A)
    time.sleep(1.3)
    key_up(VK_A, SC_A)
    time.sleep(0.2)
finally:
    # Always restore original FG 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 attached_fg:
        user32.AttachThreadInput(cur_tid, fg_tid, False)
    if attached_poe:
        user32.AttachThreadInput(cur_tid, poe_tid, False)
    log_lines.append("Restored original FG window.")

with open("elevated_approach.log", "w", encoding="utf-8") as f:
    f.write("\n".join(log_lines) + "\n")
