using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

[System.Serializable]
public class ClassBase {
  [HideInInspector] public float TimeElapsed;
  [HideInInspector] public int MaxHealth;
  [HideInInspector] public int MaxMana;
  [HideInInspector] public float AttackPower;
  [HideInInspector] public float MagicPower;

  protected Player Player;
  protected Transform PlayerTransform { get { return Player.transform; } }
  protected Vector2 PlayerPos { get { return PlayerTransform.position; } }
  protected Animator Animator;
  protected float PlayerOriginalSpeed;
  protected FloatingTextSpawner TextPopUp;
  public string AnimationToPlay = "";
  public Dictionary<Enum, ClassSkill> Skills = new Dictionary<Enum, ClassSkill>();
  [SerializeField] private List<ClassSkill> AvailableSkills = new List<ClassSkill>();

  public ClassBase(Player player) {
    Player = player;
    Animator = Player.Animator;
    TextPopUp = new FloatingTextSpawner(player.transform, 0.5f);
  }

  virtual public void Tick() {
    TimeElapsed = Time.time;
    ClassSkill.TimeElapsed = TimeElapsed;
    AvailableSkills.ForEach((x) => x.UpdateCooldown());
    foreach (var skill in Skills.Values) { skill.UpdateCooldown(); }
  }

  virtual public void HandlePrimaryAttack() { }
  virtual public void HandleSecondaryAttack() { }


  public void GenerateAvailableSkillsList() => AvailableSkills.AddRange(Skills.Values);


  [Serializable]
  public class ClassSkill {
    public static float TimeElapsed;
    public string Name { get; private set; }
    public float CooldownTime { get; private set; }
    public float CooldownTimeElapsed { get; private set; }
    public float CooldownRef { get; private set; }
    public int SkillCountMax { get; private set; }
    public int SkillCount { get; private set; } = 0;
    public bool IsPaused { get; set; }
    public bool IsNotReady { get { return SkillCount == 0; } }
    protected bool SkillCountMaxed { get { return SkillCount == SkillCountMax; } }
    protected float CooldownLeftInRatio { get { return SkillCountMaxed ? 1 : (CooldownTimeElapsed / CooldownTime); } }


    public ClassSkill(string skillName, float cooldownTime, int skillCount) {
      Name = skillName;
      CooldownTime = cooldownTime;
      SkillCountMax = skillCount;
    }

    public bool IsReady(bool useSkill = true) {
      if (SkillCount == 0) return false;
      if (useSkill) {
        if (SkillCountMaxed) CooldownRef = Time.time;
        SkillCount--;
        Debug.Log($"[{Name}] Using skill [{SkillCount}/{SkillCountMax}]");
      }
      return true;
    }


    public void UpdateCooldown() {
      if (SkillCount == SkillCountMax) return;
      CooldownTimeElapsed = TimeElapsed - CooldownRef;
      if (CooldownTimeElapsed < CooldownTime) return;
      SkillCount++;
      CooldownRef = Time.time;
      Debug.Log($"[{Name}] Updating skill count [{SkillCount}/{SkillCountMax}]");
    }
  }



  protected Coroutine AttackCoroutine;
  protected void CreateHitBoxOffset(float centerOffset, float radius, float hitDelay, float hitDuration, int damage, int knockback) {
    if (AttackCoroutine != null)
      Player.Instance.StopCoroutine(AttackCoroutine);
    var center = PlayerPos + Player.PrevDirection * centerOffset;
    hitDelay = 0;
    HitBoxDraw.Knockback = knockback;
    HitBoxDraw.Directional = centerOffset != 0;
    HitBoxDraw.Damage = damage;
    AttackCoroutine = Player.Instance.StartCoroutine(CreateHitBoxHelper(center, radius, hitDelay, hitDuration));
  }

  protected IEnumerator CreateHitBoxHelper(Vector2 center, float radius, float hitDelay, float hitDuration) {
    HitBoxDraw.Center = center;
    Debug.Log(PlayerPos);
    HitBoxDraw.Center += Vector2.down;
    HitBoxDraw.Radius = radius;
    HitBoxDraw.Color = Color.green;
    HitBoxDraw.Draw = true;

    yield return new WaitForSeconds(hitDelay);
    HitBoxDraw.Active = true;
    HitBoxDraw.Color = Color.red;

    yield return new WaitForSeconds(hitDuration);
    HitBoxDraw.Active = false;
    HitBoxDraw.Draw = false;
  }

  public HitBoxDrawClass HitBoxDraw = new HitBoxDrawClass();
  public class HitBoxDrawClass {
    public bool Draw;
    public bool Active;
    public bool Directional;
    public Vector2 Center;
    public float Radius;
    public Color Color;
    public int Knockback;
    public int Damage;
  }
}
