import time
import ctypes
from ctypes import wintypes
import struct
import sys

log_fp = open(r"c:\Projects\AutoPOE2\scratch\postmessage.log", "w", encoding="utf-8")
old_print = print
def print(*args, **kwargs):
    old_print(*args, **kwargs)
    old_print(*args, **kwargs, file=log_fp)
    log_fp.flush()

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

WM_KEYDOWN = 0x0100
WM_KEYUP = 0x0101
WM_CHAR = 0x0102

def make_lparam(vk, scan, is_up=False):
    # repeat count = 1
    # scan code = bits 16-23
    # extended = 0
    # transition state = 1 for up, 0 for down
    # previous state = 1 for up, 0 for down
    lparam = 1 | (scan << 16)
    if is_up:
        lparam |= (1 << 30) | (1 << 31)
    return lparam

def main():
    try:
        hwinsta = user32.OpenWindowStationW("WinSta0", False, 0x10000000)
        if hwinsta: user32.SetProcessWindowStation(hwinsta)
        hdesk = user32.OpenDesktopW("Default", 0, False, 0x10000000)
        if hdesk: user32.SetThreadDesktop(hdesk)
    except Exception as e:
        print(f"Desktop error: {e}")

    hwnd = user32.FindWindowW("POEWindowClass", None)
    if not hwnd: hwnd = user32.FindWindowW(None, "Path of Exile 2")
    print(f"HWND: {hwnd}")
    if not hwnd: return

    user32.ShowWindow(hwnd, 9)
    user32.SetForegroundWindow(hwnd)
    time.sleep(0.3)

    pid = 43084
    h_proc = kernel32.OpenProcess(0x0410, False, pid)
    life_addr = 0x2AF791A03E8
    mana_addr = life_addr + 0x420

    def read_mana():
        if not h_proc: return 0
        buf = ctypes.create_string_buffer(4)
        br = ctypes.c_size_t(0)
        kernel32.ReadProcessMemory(h_proc, ctypes.c_void_p(mana_addr), buf, 4, ctypes.byref(br))
        return struct.unpack('I', buf.raw)[0] if br.value == 4 else 0

    mana_start = read_mana()
    print(f"Mana before test: {mana_start}")

    # Test PostMessage 'Q' (VK 0x51, scan 0x10)
    print("Testing PostMessage WM_KEYDOWN 'Q'...")
    lp_down = make_lparam(0x51, 0x10, False)
    lp_up = make_lparam(0x51, 0x10, True)
    
    r1 = user32.PostMessageW(hwnd, WM_KEYDOWN, 0x51, lp_down)
    time.sleep(0.1)
    r2 = user32.PostMessageW(hwnd, WM_KEYUP, 0x51, lp_up)
    
    time.sleep(0.5)
    mana_end = read_mana()
    print(f"PostMessage res=({r1},{r2}) | Mana after: {mana_end} (Delta: {mana_end - mana_start})")

    if h_proc: kernel32.CloseHandle(h_proc)

if __name__ == "__main__":
    main()
