using System;
using System.Collections;
using System.Collections.Generic;
using System.Runtime.CompilerServices;
using Unity.VisualScripting;
using UnityEngine;
using static UnityEngine.RuleTile.TilingRuleOutput;

[System.Serializable]
public class MeleeFighterClass : ClassBase {
  [SerializeField] private MeleeFighterAttackAnimator AttackAnimator;

  private readonly int BladeVortex = Animator.StringToHash("BladeVortex");
  private float BladeVortexSpeed = 0.4f;
  public float ComboResetTime;
  public float LastComboTime;
  public bool ChargingAnAttack;
  public float ChargeValue;
  public bool AllowBladeVortex;
  public int ChargeTick;
  public float ComboTimeElapsed;
  public float Cooldown;
  public bool TimesUp;

  public int DamageMultiplier = 1;
  public int DamageOffset = 0;


  public VfxHandlerBase VfxKineticSurgeHandler { get { return Player.VfxKineticSurgeHandler; } }


  public MeleeFighterClass(Player player) : base(player) {
    AttackAnimator = player.AttackAnimator;
    AttackAnimator.Player = player;
    Skills.Add(AttackState.PhaseCleave, new ClassSkill("PhaseCleave", 2f, 3));
    Skills.Add(AttackState.BladeVortex, new ClassSkill("BladeVortex", 2f, 3));
    Skills.Add(AttackState.Shockwave, new ClassSkill("Shockwave", 2f, 3));
    GenerateAvailableSkillsList();
    Player.GizmoTick += GizmoTick;
  }



  public AttackState CurrentState;
  public enum AttackState {
    None,
    PhaseCleave,
    DrainEdge,
    Shockwave,
    BladeVortex,
    PrepareBasicAttack1,
    BasicAttack1,
    BasicAttack2,
    BasicAttack3,
    KineticSurgeRelease,
    ChargeSurgeA,
    ChargeSurgeB,
    KineticSurgeA,
    KineticSurgeB,
  }


  override public void Tick() {
    base.Tick();

    ComboTimeElapsed = Time.time - LastComboTime;
    TimesUp = ComboTimeElapsed > ComboResetTime;

    switch (CurrentState) {
      case AttackState.None:
        Player.SkillInUse = false;
        return;


      case AttackState.PrepareBasicAttack1:
        AllowBladeVortex = ComboTimeElapsed <= 0.1f;
        if (!AllowBladeVortex)
          ChangeState(AttackState.BasicAttack1, 0.35f);
        break;


      case AttackState.BasicAttack3:
        if (ComboTimeElapsed <= 0.1) break;
        ChangeState(AttackState.KineticSurgeRelease, -1, -1, -1);
        break;


        //case AttackState.ChargeSurgeA:
        //  ChargingAnAttack = Input.GetMouseButton(0);
        //  HandleCharging(TimeElapsed);
        //  if (!ChargingAnAttack) ChangeState(AttackState.KineticSurgeA);
        //  break;


        //case AttackState.ChargeSurgeB:
        //  ChargingAnAttack = Input.GetMouseButton(1);
        //  HandleCharging(TimeElapsed);
        //  if (!ChargingAnAttack) ChangeState(AttackState.KineticSurgeB);
        //  break;
    }


    if (!ChargingAnAttack && TimesUp || Player.Jump.Active) {
      Player.MoveSpeedDampener = 1;
      ChangeState(AttackState.None);
      AttackAnimator?.MeleeResetKineticCharge();
      Player.SkillInUse = false;
    }
  }

  private void HandleCharging(float timeElapsed) {
    ChargeValue = timeElapsed * 60;
    if (ChargeValue > 100) ChargeValue = 100;
    if (ChargeTick++ > 10) {
      ChargeTick = 0;
      TextPopUp.SpawnFloatingText($"Charging {ChargeValue:0.0}", GetChargeColor(), 3);
    }
  }

  private Color GetChargeColor() {
    ChargeValue = Mathf.Clamp01(ChargeValue / 100f); // Normalize to 0–1

    if (ChargeValue < 0.5f) {
      return Color.Lerp(Color.red, Color.yellow, ChargeValue / 0.5f);
    } else {
      return Color.Lerp(Color.yellow, Color.green, (ChargeValue - 0.5f) / 0.5f);
    }
  }



  override public void HandlePrimaryAttack() {
    Player.SkillInUse = true;

    switch (CurrentState) {
      case AttackState.None:
        //PlayerOriginalSpeed = Player.MoveSpeed;

        if ((Time.time - Player.DashTime) <= 0.1f)
          ChangeState(AttackState.PhaseCleave, 1.5f);
        else if (Player.Jump.Active) {
          if (Player.Jump.IsNonBlocking)
            ChangeState(AttackState.Shockwave, 0);
        } else
          ChangeState(AttackState.PrepareBasicAttack1, 0.35f);
        break;


      case AttackState.BasicAttack1:
        ChangeState(AttackState.BasicAttack2, 0.35f);
        break;


      case AttackState.BasicAttack2:
        ChangeState(AttackState.BasicAttack3, 0.15f);
        break;
    }

  }



  override public void HandleSecondaryAttack() {
    Player.SkillInUse = true;

    switch (CurrentState) {
      case AttackState.None:
        /*PlayerOriginalSpeed = Player.MoveSpeed*/


        if (Player.IsDashing)
          ChangeState(AttackState.None);
        else if (Player.Jump.Active)
          ChangeState(AttackState.None);
        else
          ChangeState(AttackState.DrainEdge);
        break;


      case AttackState.PrepareBasicAttack1:
        if (!AllowBladeVortex) return;
        if (!Skills[AttackState.BladeVortex].IsReady()) {
          ChangeState(AttackState.None);
          return;
        }
        Cooldown = 0;
        ChangeState(AttackState.BladeVortex, 0.4f, 1.5f);
        break;


      case AttackState.BasicAttack3:
        //ChangeState(AttackState.ChargeSurgeB);
        break;


      case AttackState.BladeVortex:
        ChangeState(AttackState.None);
        //ChangeState(AttackState.ChargeSurgeB);
        break;
    }
  }


  private void ChangeState(
      AttackState state,
      float decreasedSpeed = 0.2f,
      float resetTime = 0.3f,
      float cooldown = 0.05f) {

    if (ComboTimeElapsed < Cooldown) return;
    CurrentState = state;
    if (decreasedSpeed != -1) Player.MoveSpeedDampener = (state == AttackState.None) ? 1 : 1 / decreasedSpeed;
    if (state == AttackState.None) return;
    if (resetTime != -1) ComboResetTime = resetTime;
    if (cooldown != -1) Cooldown = cooldown;
    LastComboTime = Time.time;

    RotateTowardsMouse();
    AttackAnimator?.MeleeBasic(CurrentState);

    switch (CurrentState) {
      case AttackState.None:
        if (Player.IsDashing) {
        } else if (Player.Jump.Active) {
        } else { }
        break;

      case AttackState.Shockwave:
        AnimationToPlay = "Shockwave";
        Player.VfxShockwavePool.Get(Player.transform.position);
        CreateHitBoxOffset(0, 5, 0.1f, 0.1f, (20 * DamageMultiplier) + DamageOffset, 20);
        Player.Jump.Stop();
        break;

      case AttackState.BladeVortex:
        AttackAnimator?.Stop();
        AnimationToPlay = "BladeVortex_";
        break;

      case AttackState.BasicAttack1:
        AnimationToPlay = "Attack1";
        CreateHitBoxOffset(4, 4, 0.1f, 0.1f, (2 * DamageMultiplier) + DamageOffset, 20);
        break;

      case AttackState.BasicAttack2:
        AnimationToPlay = "Attack2";
        CreateHitBoxOffset(4, 4, 0.1f, 0.1f, (4 * DamageMultiplier) + DamageOffset, 20);
        break;

      case AttackState.BasicAttack3:
        AnimationToPlay = "Attack1";
        CreateHitBoxOffset(4, 4, 0.1f, 0.1f, (6 * DamageMultiplier) + DamageOffset, 20);
        break;

      case AttackState.KineticSurgeRelease:
        AttackAnimator?.MeleeResetKineticCharge();
        AttackAnimator?.MeleeKineticSurge();
        VfxKineticSurgeHandler.PlayAll(Player.transform.position);
        CreateHitBoxOffset(0, 5, 0.1f, 0.1f, (10 * DamageMultiplier) + DamageOffset, 20);
        break;
    }
  }



  private void GizmoTick() {
    if (HitBoxDraw == null) return;
    if (!HitBoxDraw.Draw) return;

    Player.DrawWireSphere(HitBoxDraw.Color, HitBoxDraw.Center, HitBoxDraw.Radius);
  }

  public void RotateTowardsMouse() {
    return;
    Vector3 mouseWorldPos = Camera.main.ScreenToWorldPoint(Input.mousePosition);
    Vector2 direction = mouseWorldPos - Player.transform.position;
    if (Mathf.Abs(direction.x) > Mathf.Abs(direction.y)) {
      Player.LastDirection = (direction.x > 0) ? Player.Direction.Right : Player.Direction.Left;
    } else {
      Player.LastDirection = (direction.y > 0) ? Player.Direction.Up : Player.Direction.Down;
    }
  }


}
