import ctypes, time, sys, os
from PIL import ImageGrab
import win32gui, win32process, psutil

sys.stdout.reconfigure(encoding='utf-8')
user32 = ctypes.windll.user32
shell32 = ctypes.windll.shell32
hdesk = user32.OpenInputDesktop(0, False, 0x01FF)
if hdesk: user32.SetThreadDesktop(hdesk)

print("=== STARTING FULL AUTO-LOGIN TEST ===")

# 1. Launch Game.exe
existing_hwnds = set()
def cb_exist(h, _):
    if win32gui.GetClassName(h) == "Sword3 Class":
        existing_hwnds.add(h)
win32gui.EnumWindows(cb_exist, None)

print("Launching Game.exe with runas...")
res = shell32.ShellExecuteW(None, "runas", r"C:\JXVCTK\JxVoCongTruyenKy\Game.exe", None, r"C:\JXVCTK\JxVoCongTruyenKy", 1)
print(f"ShellExecuteW returned: {res}")

target_hwnd = None
start_t = time.time()
while time.time() - start_t < 25:
    time.sleep(1.0)
    current_hwnds = []
    def cb(h, _):
        if win32gui.GetClassName(h) == "Sword3 Class":
            current_hwnds.append(h)
    win32gui.EnumWindows(cb, None)
    diff = set(current_hwnds) - existing_hwnds
    if diff:
        target_hwnd = list(diff)[0]
        print(f"[{time.time()-start_t:.1f}s] Found new game window: {hex(target_hwnd)}")
        break

if not target_hwnd:
    print("FAILED: Could not find new Sword3 window!")
    sys.exit(1)

# Helper functions
def make_lparam(x, y):
    return ((y & 0xFFFF) << 16) | (x & 0xFFFF)

def click(x, y, delay=0.05):
    lp = make_lparam(x, y)
    user32.PostMessageW(target_hwnd, 0x0200, 0, lp) # WM_MOUSEMOVE
    time.sleep(0.03)
    user32.PostMessageW(target_hwnd, 0x0201, 1, lp) # WM_LBUTTONDOWN
    time.sleep(0.06)
    user32.PostMessageW(target_hwnd, 0x0202, 0, lp) # WM_LBUTTONUP
    time.sleep(delay)

def dblclick(x, y, delay=0.05):
    lp = make_lparam(x, y)
    user32.PostMessageW(target_hwnd, 0x0200, 0, lp)
    time.sleep(0.03)
    user32.PostMessageW(target_hwnd, 0x0201, 1, lp)
    time.sleep(0.04)
    user32.PostMessageW(target_hwnd, 0x0202, 0, lp)
    time.sleep(0.04)
    user32.PostMessageW(target_hwnd, 0x0203, 1, lp)
    time.sleep(0.04)
    user32.PostMessageW(target_hwnd, 0x0202, 0, lp)
    time.sleep(delay)

def send_key(vk, delay=0.04):
    sc = user32.MapVirtualKeyW(vk, 0)
    lp_down = 1 | (sc << 16)
    lp_up = 1 | (sc << 16) | (3 << 30)
    user32.PostMessageW(target_hwnd, 0x0100, vk, lp_down)
    time.sleep(0.04)
    user32.PostMessageW(target_hwnd, 0x0101, vk, lp_up)
    time.sleep(delay)

def send_char(c, delay=0.03):
    vk_scan = user32.VkKeyScanW(ord(c))
    vk = vk_scan & 0xFF
    sc = user32.MapVirtualKeyW(vk, 0)
    lp = 1 | (sc << 16)
    user32.PostMessageW(target_hwnd, 0x0102, ord(c), lp)
    time.sleep(delay)

def capture(step_name):
    if win32gui.IsWindow(target_hwnd):
        rect = win32gui.GetWindowRect(target_hwnd)
        if rect[2] > rect[0] and rect[3] > rect[1]:
            img = ImageGrab.grab(bbox=rect, all_screens=True)
            path = rf"c:\Projects\JX\logs\autologin_{step_name}.png"
            img.save(path)
            print(f"  [Capture] Saved {path}")

# Bring to foreground
user32.SetForegroundWindow(target_hwnd)
print("Waiting 4.0s for game engine and title screen assets to fully load...")
time.sleep(4.0)
capture("0_initial")

# Bước 1: Màn hình Chào -> Bắt đầu trò chơi
print("Bước 1: Click 'Bắt đầu trò chơi'...")
click(400, 385)
time.sleep(0.1)
send_key(0x0D) # Enter
time.sleep(2.0)
capture("1_after_start")

# Bước 2: Hộp thoại Nhắc nhở (nếu có)
print("Bước 2: Xác nhận popup Nhắc nhở (nếu có)...")
click(400, 440)
time.sleep(0.1)
send_key(0x0D) # Enter
time.sleep(1.5)
capture("2_after_notice")

# Bước 3: Lựa chọn máy chủ
print("Bước 3: Chọn máy chủ 'Trọn Vẹn Chữ Tình'...")
# KHÔNG gửi VK_UP! Võ Công Truyền Kỳ đã được chọn sẵn ở tab bên trái.
# Đảm bảo click cụm bên trái
click(208, 195)
time.sleep(0.2)
# Click và double-click 'Trọn Vẹn Chữ Tình' bên phải
click(610, 209)
time.sleep(0.2)
dblclick(610, 209)
time.sleep(0.3)
# Click 'Xác định'
click(260, 503)
time.sleep(0.1)
send_key(0x0D)
time.sleep(2.0)
capture("3_after_server")

# Bước 4: Nhập tài khoản và mật khẩu
print("Bước 4: Nhập tài khoản 'nguvansi' và mật khẩu...")
# Click ô tài khoản tại (400, 302)
click(400, 302)
time.sleep(0.1)
send_key(0x23) # VK_END
for _ in range(25): send_key(0x08, delay=0.01) # Backspace
send_key(0x24) # VK_HOME
for _ in range(25): send_key(0x2E, delay=0.01) # Delete
time.sleep(0.1)
for c in "nguvansi":
    send_char(c)
time.sleep(0.15)

# Click ô mật khẩu tại (400, 340)
click(400, 340)
time.sleep(0.1)
send_key(0x23) # VK_END
for _ in range(25): send_key(0x08, delay=0.01)
send_key(0x24) # VK_HOME
for _ in range(25): send_key(0x2E, delay=0.01)
time.sleep(0.1)
for c in "Ngu123@@":
    send_char(c)
time.sleep(0.15)
capture("4_typed_credentials")

# Click 'Xác định' đăng nhập tại (320, 418)
print("Gửi lệnh xác nhận đăng nhập...")
click(320, 418)
time.sleep(0.1)
send_key(0x0D)
time.sleep(3.5)
capture("5_after_submit_login")

# Bước 5: Chọn nhân vật Slot 1 (BoCuaCacCon)
print("Bước 5: Chọn nhân vật Slot 1 và vào game...")
click(250, 350)
time.sleep(0.2)
dblclick(250, 350)
time.sleep(0.3)
# Click nút 'Xác định' / 'Vào trò chơi' tại (92, 561)
click(92, 561)
time.sleep(0.1)
send_key(0x0D)
time.sleep(4.5)
capture("6_in_game_world")

# Dismiss popup hoạt động nếu có
print("Dismissing any popup...")
click(300, 570)
time.sleep(0.2)
send_key(0x1B) # ESC
time.sleep(1.0)
capture("7_final_in_game")

print("=== AUTO-LOGIN TEST SEQUENCE COMPLETED ===")
