extends CharacterBody2D

@onready var collision_shape_2d: CollisionShape2D = $CollisionShape2D
@onready var animated_sprite: AnimatedSprite2D = $AnimatedSprite2D
@onready var player: CharacterBody2D = $"."
@onready var movementlabel: Label = $CanvasLayer/VBoxContainer/MovementType

var hovered = null
var selected = null

var hover_indicator = preload("res://assets/sprites/ui/ui_icons_green_down4.png")
var selected_indicator = preload("res://assets/sprites/ui/ui_icons_blue_down4.png")

var map_renderer = null

@export var move_speed: float = 200.0  # Speed for free movement
@export var tile_size: Vector2 = Vector2(32, 16)
@export var combat_move_time: float = 0.3

enum MovementMode {
    FREE,
    COMBAT
}

var current_mode: MovementMode = MovementMode.FREE
var is_moving: bool = false
var target_position: Vector2 = Vector2.ZERO
var start_position: Vector2 = Vector2.ZERO
var move_progress: float = 0.0
var move_direction: Vector2 = Vector2.ZERO

func set_map_renderer(renderer):
    map_renderer = renderer

func _ready():
    
    var hover_sprite = Sprite2D.new()
    hover_sprite.texture = hover_indicator
    hover_sprite.position.y = -15
    hover_sprite.visible = false
    hover_sprite.name = "HoverIndicator"
    hover_sprite.z_index = 100
    player.add_child(hover_sprite)
    target_position = position

func toggle_selection():
    selected = !selected
    map_renderer.set_unit_selected_state(selected)
    if selected:
        get_node("HoverIndicator").texture = selected_indicator
        # Tell the map renderer to darken everything
        if map_renderer:
            map_renderer.darken_all_except_player(self)
    else:
        get_node("HoverIndicator").texture = hover_indicator
        # Reset darkening
        if map_renderer:
            map_renderer.reset_darkening()
    
    # Keep indicator visible when selected
    get_node("HoverIndicator").visible = selected or hovered == player

var player_data = {
    "stats": {
        "health": 100,
        "mana": 100,
        "speed": 3,
        "attack": 10,
        "defense": 5,
        "actionpoints": 5,
    },
    "inventory": [],
    "name": "Hero"
}
func _input(event):
    if event is InputEventMouseMotion:
        check_hover()
        
func _unhandled_input(event):
    if event is InputEventMouseButton and event.button_index == MOUSE_BUTTON_LEFT and event.pressed:
        # If we're being hovered and clicked
        if hovered == player:
            toggle_selection()
        else:
            selected = false
            
func check_hover():
    var mouse_pos = get_global_mouse_position()
    var was_hovered = hovered != null
    # print("Mouse pos: ", mouse_pos, " Player pos: ", player.position)
    
    if hovered:
        hovered.get_node("HoverIndicator").visible = false
        hovered = null
    
    if player.has_node("CollisionShape2D"):
        var collision = player.get_node("CollisionShape2D")
        var shape = collision.shape
        
        var local_pos = player.to_local(mouse_pos)
        
        if shape is RectangleShape2D:
            var extents = shape.extents
            if local_pos.x >= -extents.x and local_pos.x <= extents.x and \
                local_pos.y >= -extents.y and local_pos.y <= extents.y:
                hovered = player
                player.get_node("HoverIndicator").visible = true
                
        if (was_hovered != (hovered != null)) and map_renderer:
            map_renderer.set_unit_hover_state(hovered != null)
            
                
func set_unit_position(x, y, z):
    var z_layer = z
    var x_position = x + 16
    var y_position = y 
    
    # Update the main node position 
    global_position = Vector2(x_position, y_position)
    
    # Update the visual z-index directly
    animated_sprite.z_index = z_layer
    # Keep sprite centered at node position
    animated_sprite.position = Vector2.ZERO
    
    print("Player Z-Layer: ", z_layer)
    print("Player position updated to: ", global_position)

func get_sprite_size():
    return collision_shape_2d.shape

func _process(delta: float):
    check_hover()
    match current_mode:
        MovementMode.FREE:
            play_player_animation("movement")
            process_free_movement(delta)
        MovementMode.COMBAT:
            play_player_animation("idle")
            #process_combat_movement(delta)
    
func process_free_movement(delta):
    # Get input direction
    var direction = Input.get_vector("ui_left", "ui_right", "ui_up", "ui_down")

    # Convert direction to isometric (optional - depends on your camera setup)
    var iso_direction = Vector2(direction.x, direction.y)

    # Set velocity and move
    velocity = iso_direction.normalized() * move_speed
    move_and_slide()

func process_combat_movement(delta):
    if is_moving:
        # Continue current movement
        move_progress += delta / combat_move_time
        if move_progress >= 1.0:
            # Movement complete
            position = target_position
            is_moving = false
        else:
            # Interpolate position
            position = start_position.lerp(target_position, move_progress)
    else:
    # Check for new movement input
        var direction = Vector2.ZERO
        if Input.is_action_just_pressed("ui_right"):
            direction = Vector2(1, 0)
        elif Input.is_action_just_pressed("ui_left"):
            direction = Vector2(-1, 0)
        elif Input.is_action_just_pressed("ui_down"):
            direction = Vector2(0, 1)
        elif Input.is_action_just_pressed("ui_up"):
            direction = Vector2(0, -1)

        if direction != Vector2.ZERO:
            start_tile_movement(direction)

# Start a new tile movement
func start_tile_movement(direction: Vector2):
    # Convert direction to isometric
    var iso_direction = Vector2(direction.x - direction.y, (direction.x + direction.y) / 2)

    # Calculate target position
    start_position = position
    target_position = position + (iso_direction * tile_size)

    # Start movement
    is_moving = true
    move_progress = 0.0
    move_direction = direction

# Toggle between movement modes
func toggle_movement_mode():
    if current_mode == MovementMode.FREE:
        current_mode = MovementMode.COMBAT
        # Snap to nearest tile when entering combat mode
        position = Vector2(
        round(position.x / tile_size.x) * tile_size.x,
        round(position.y / tile_size.y) * tile_size.y
        )
    else:
        current_mode = MovementMode.FREE

    print("Movement mode switched to: ", "FREE" if current_mode == MovementMode.FREE else "COMBAT")

func play_player_animation(state="idle"):
    if state == "idle":
        animated_sprite.play("down")
    if state == "movement":
        animated_sprite.play("down")
        
        

func _on_toggle_movement_pressed() -> void:
    player.toggle_movement_mode()
    if player.current_mode == player.MovementMode.FREE:
        movementlabel.text = "Mode: Non-Combat (Free)"
    else:
        movementlabel.text = "Mode: Combat (Tile-Based)"
