import pygame
import math
import time

import DataTypes as dt

def normalize(x, y, deadzone=0.15):
    if abs(x) < deadzone:
        x = 0.0
    if abs(y) < deadzone:
        y = 0.0

    mag = math.hypot(x, y)
    if mag > 1.0:
        x /= mag
        y /= mag

    return x, y


def controller_loop(shared_intent: dt.ControlIntent, lock):
    pygame.init()
    pygame.joystick.init()

    joysticks = {}
    prev_buttons = {}

    clock = pygame.time.Clock()

    while True:
        # 🔑 REQUIRED: keeps joystick state updating
        pygame.event.pump()

        for event in pygame.event.get():
            if event.type == pygame.JOYDEVICEADDED:
                joy = pygame.joystick.Joystick(event.device_index)
                joysticks[joy.get_instance_id()] = joy
                prev_buttons[joy.get_instance_id()] = [0] * joy.get_numbuttons()
                print(f"[Controller] Joystick connected: {joy.get_name()}")

            elif event.type == pygame.JOYDEVICEREMOVED:
                joysticks.pop(event.instance_id, None)
                prev_buttons.pop(event.instance_id, None)
                print("[Controller] Joystick disconnected")

        if not joysticks:
            time.sleep(0.1)
            continue

        # Use first joystick
        joy = next(iter(joysticks.values()))
        jid = joy.get_instance_id()

        # ---- AXES ----
        forward = -joy.get_axis(1)   # usually inverted
        sideways = joy.get_axis(0)

        forward, sideways = normalize(forward, sideways)

        walk = abs(forward) > 0 or abs(sideways) > 0

        # ---- BUTTONS ----
        buttons = joy.get_numbuttons()
        current_buttons = [joy.get_button(i) for i in range(buttons)]

        emote = None
        quit_flag = False

        for i in range(buttons):
            if current_buttons[i] and not prev_buttons[jid][i]:
                # Button DOWN (edge)
                if i == 0:
                    emote = "HELLO"
                elif i == 1:
                    emote = "SAD"
                elif i == 9:
                    quit_flag = True

        prev_buttons[jid] = current_buttons

        # ---- UPDATE INTENT (atomic) ----
        with lock:
            shared_intent.move_x = forward
            shared_intent.move_y = sideways
            shared_intent.walk = walk

            if emote:
                shared_intent.emote = emote

            if quit_flag:
                shared_intent.quit = True

        clock.tick(60)
