extends Area2D


signal damage_taken
# signal shield_damage
# signal shield_ui

@export var speed: int = 150
@export var cooldown: float = 1
@export var bullet_scene : PackedScene
@export var max_shield: int = 10
var shield: int = 0:
    set = _on_set_shield

var pause: bool = false
var can_shoot = false
var can_win = false
var shader_active: bool = false:
  set(value):
    if value == true:
      print_debug("Shader active!", get_stack())
    else:
      print_debug("Shader inactive!", get_stack())

var clamp_shield = clamp(shield, 0, max_shield)

@onready var screensize = get_viewport_rect().size
@onready var explosion = $Explosion
@onready var wait_time = $GunCooldown
@onready var ship = $Ship
@onready var game_status = get_node("/root/Main")

func _ready():
    set_process(false)
    print(shield)
    EventBus.set_shield.connect(_on_set_shield)
    EventBus.player_victory.connect(_on_player_victory)
    # start()

func start():
    print(shield)
    
    if game_status.playing == false:
      shader_active = false
      $Ship.frame = 0
      # $Ship/Boosters/BoosterBurst.hide()
      # $Ship/Boosters.hide()
      $Ship.show()
      position = Vector2(screensize.x / 2, screensize.y)
      var tween = create_tween()
      tween.tween_property(self, "position:y",  120   * -1, 1).as_relative()
      await tween.finished
      $GunCooldown.wait_time = cooldown
      _on_set_shield(max_shield)
      print(shield)
      await get_tree().create_timer(1).timeout
      set_process(true)
      # $Ship/Boosters.show()
      can_shoot = true
      # EventBus.shield_changed.emit(max_shield, old_value, shield)

func _process(delta):
    if pause == true: return
    
    var input = Input.get_vector("left", "right", "up", "down")
    if input.x > 0:
        $Ship.frame = 2
        $Ship/Head.frame = 2
        # $Ship/Boosters.animation = "right"
    elif input.x < 0:
        $Ship.frame = 1
        $Ship/Head.frame = 1
        # $Ship/Boosters.animation = "left"
    else:
        $Ship.frame = 0
        $Ship/Boosters.animation = "forward"
        $Ship/Head.frame = 0
    position += input * speed * delta
    position = position.clamp(Vector2(8, 8), screensize - Vector2(8, 8))
    if Input.is_action_pressed("shoot"):
        shoot()

func shoot():
    if not can_shoot:
      return
    can_shoot = false
    $GunCooldown.start()
    $Ship/Head.hide()
    var b = bullet_scene.instantiate()
    get_tree().root.add_child(b)
    b.start(position + ship.position + Vector2(0, -10))
    var tween = create_tween().set_parallel(false)
    tween.tween_property(ship, "position:y", 1, 0.1)
    tween.tween_property(ship, "position:y", 0, 0.05)

func _on_set_shield(value: int):
  
  var old_value = shield
  # shield = clamp(value, 0, max_shield)
  shield = min(max_shield, value)
  EventBus.shield_changed.emit(max_shield, old_value, shield)
  print("Shield set to:", shield)
  if shield <= 0:
    set_process(false)
    $Ship.hide()
    shader_active = false
    $Explosion.show()
    $Explosion/AnimationPlayer.play("explosion-one-shot")
    await $Explosion/AnimationPlayer.animation_finished
    EventBus.player_died.emit()


func _on_gun_cooldown_timeout() -> void:
            $HeadInflate.play()
            #tween.tween_property($Ship/Head, "scale", 4, 0.25)
            #await tween.finished
            await get_tree().create_timer(0.25).timeout
            var tween = create_tween().set_parallel(false)
            $Ship/Head.show()
            tween.tween_property($Ship/Head, "scale", Vector2(.25,2.5), .15).set_trans
            tween.tween_property($Ship/Head, "scale", Vector2(1,1), .10).set_trans(Tween.TRANS_BOUNCE)
            can_shoot = true

func _on_area_entered(area):
    if area.is_in_group("enemies"):
        shield -= int(max_shield / 2)
        _on_damage_taken()
        area.hit_detection()
    
    if area.is_in_group("enemy_bullets") and self.monitoring == true:
        damage_taken.emit()
        
    if area.is_in_group("horse"):
        print("Entered horse!")
        #shield -= int(max_shield / 2)
        #_on_damage_taken()
        
    if area.is_in_group("boss"):
        print("Entered boss!")
        
        if can_win == true:
          print("You can win!")
          EventBus.heart_beat.emit(2.5)
          area.reparent(self)
          EventBus.win_game.emit(1)
        
        elif can_win == false:
          shield -= int(max_shield / 2)
          _on_damage_taken()
        
    if area.is_in_group("heart"):
      print("Got the heart!")
      #pause = true
      area.reparent(self)
      EventBus.heart_beat.emit(2.0)
      ship.frame = 0
      can_win = true
      EventBus.ending.emit(1)
      
    #if area.is_in_group("boss") and can_win == true:
      print("You can win!")
      self.monitoring = false
      
      

func _on_damage_taken():

  if shield == 0 and game_status.playing == false:
    #shader_active = false
    return

  else:
    shader_active = true
    $Ship.material.set_shader_parameter("toggle", 1.0)
    await get_tree().create_timer(1).timeout
    $Ship.material.set_shader_parameter("toggle", 0.0)
    shader_active = false

func _on_player_victory(ending: int) -> void:
  
  if ending == 1: # Heart Taken
    print("Victory!")
    # get_node("EnemyBullet").monitoring = false #TODO make sure bullets stop monitoring!
    set_process(false)
    #$Ship.frame = 1
    self.monitorable = false
    self.monitoring = false
    await get_tree().create_timer(4).timeout
    # $Ship/Boosters/BoosterBurst.show()
    var tween = create_tween()
    tween.tween_property(self, "position:y",  60 * -1, .25).set_ease(tween.EASE_IN)
    await tween.finished
    queue_free()
    
  if ending == 2:
    print("Victory!")
    # get_node("EnemyBullet").monitoring = false #TODO make sure bullets stop monitoring!
    set_process(false)
    $Ship.frame = 0
    self.monitorable = false
    self.monitoring = false
    await get_tree().create_timer(4).timeout
    # $Ship/Boosters/BoosterBurst.show()
    var tween = create_tween()
    tween.tween_property(self, "position:y",  60 * -1, .25).set_ease(tween.EASE_IN)
    await tween.finished
    queue_free()
