using AI.Base;
using NUnit.Framework.Internal.Execution;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Xml.Linq;
using UnityEditor.Build;
using UnityEngine;
using UnityEngine.AI;
using static EnemySpawnerData;
using static UnityEngine.RuleTile.TilingRuleOutput;


public class Gobler : Enemy {


  public Gobler(GameObject owner) : base(owner) {
    BaseDamage = 10;
    AttackPreparationTime = 0.5f;
    AttackCooldownDuration = 1;

    BaseHealth = 100;
    CurrentHealth = BaseHealth;
    InvincibilityDuration = 0.11f;
    FrameFreezeDuration = 0.3f;
    IsKnockable = true;

    SetState(State.GoToCrystal);
    SubscribeToEvent();
  }





  protected override void SetPriorityState() {
    if (CurrentState == State.PrepareAttack) return;
    if (CurrentState == State.FinalizeAttack) return;
    if (CurrentState == State.ChasePlayer) return;
    if (CurrentState == State.TakeDamage) return;
    if (CurrentState == State.Die) return;
    if (DistFromPlayer > ChaseDistance) return;
    SetState(State.ChasePlayer);
  }

  protected override void DoUpdate() {
    switch (CurrentState) {
      case State.None:
        SetState(State.GoToCrystal);
        break;


      case State.GoToCrystal:
        if (CanAttackCrystal)
          SetState(State.PrepareAttack);
        break;


      case State.ChasePlayer:
        if (CanAttackPlayer)
          SetState(State.PrepareAttack);
        else if (DistFromPlayer > ChaseDistance + ChaseDistanceBuffer) {
          if (AggroOnPlayer) TextPopUp.SpawnFloatingText("?", Color.red);
          AggroOnPlayer = false;
          SetState(State.None);
        } else
          PathAgent.SetDestination(PlayerPos);
        break;


      case State.TakeDamage:
        if (IsInvincible) {
          var velocity = DirectionOfDamage * Knockback * 10 * InvincibilityLeft;
          var isWalkable = NavMeshUtils.IsWalkable(MyPos, DirectionOfDamage);
          Rigidbody.linearVelocity = isWalkable ? velocity : Vector2.zero;
          //Rigidbody.linearVelocity = velocity;
          MaterialColorOverlay.SetFloat("_FlashAmount", InvincibilityLeft / InvincibilityDuration);
        } else {
          MaterialColorOverlay.SetFloat("_FlashAmount", 0);
          Rigidbody.linearVelocity = Vector2.zero;
        }

        if (!IsFrameFrozen) SetState(State.None);
        break;


      case State.PrepareAttack:
        MaterialColorOverlay.SetFloat("_FlashAmount", AttackPreparationTimeElapsedNormalized);
        if (AttackIsReady) SetState(State.FinalizeAttack);
        break;


      case State.FinalizeAttack:
        SetState(AggroOnPlayer ? State.ChasePlayer : State.GoToCrystal);
        break;
    }
  }



  protected override void DoSetState(State newState) {
    Debug.Log($"New State: {newState.ToString()}");
    CurrentState = newState;
    switch (newState) {
      case State.None:
        PathAgent.isStopped = true;
        break;


      case State.GoToCrystal:
        AggroOnCrystal = true;
        PathAgent.isStopped = false;
        PathAgent.SetDestination(CrystalPos);
        break;


      case State.ChasePlayer:
        if (!AggroOnPlayer) TextPopUp.SpawnFloatingText("!", Color.red);
        PathAgent.isStopped = false;
        AggroOnPlayer = true;
        break;


      case State.TakeDamage:
        AggroOnCrystal = false;
        AggroOnPlayer = false;
        PathAgent.isStopped = true;
        TextPopUp.SpawnFloatingText(DamageTaken.ToString(), Color.white, 3);
        MaterialColorOverlay.SetColor("_FlashColor", Color.white);
        break;


      case State.PrepareAttack:
        PathAgent.isStopped = true;
        StartAttackPreparation();
        MaterialColorOverlay.SetColor("_FlashColor", Color.purple);
        break;


      case State.FinalizeAttack:
        Collider2D[] hits = Physics2D.OverlapCircleAll(MyPos + Vector2.down, 4);
        foreach (var hit in hits) {
          if (hit.CompareTag("PlayerHurtBox"))
            Player.Combat.Damage(BaseDamage, PlayerPos - MyPos, 20);
          else if (hit.CompareTag("SuperSpecialGem"))
            Debug.Log($"{hit.tag} hit");

          //GameObject parent = hit.transform.parent?.gameObject;
          //Vector2 knockbakDirection = ActiveClass.HitBoxDraw.Directional ? PrevDirection : parent.transform.position - transform.position;
          //EnemySpawnerData.EnemyMap[parent].Damage(ActiveClass.HitBoxDraw.Damage, knockbakDirection, ActiveClass.HitBoxDraw.Knockback);
        }

        MaterialColorOverlay.SetFloat("_FlashAmount", 0);
        StartAttackCooldown();
        break;


      case State.Die:
        SpawnableEnemyInfo.DestroyEnemy(Owner, Enemies.Gobler);
        SetState(State.None);
        break;
    }

    if (PrevState != CurrentState) PrevState = CurrentState;
    Debug.Log($"State Done: {newState.ToString()}");
  }



  protected override void OnDrawGizmos() {
    if (Owner == null) return;

    DrawChaseDistance();
    DrawAttackDistance();
    DrawAttackReach();
  }

  private void DrawWireSphere(Color color, Vector2 center, float radius) => EnemyManagers[Enemies.Gobler].DrawWireSphere(color, center, radius);


  private void DrawChaseDistance() {
    DrawWireSphere(Color.green, MyPos, ChaseDistance);
  }

  private void DrawAttackDistance() {
    if (CurrentState != State.PrepareAttack) return;
    Collider2D[] hits = Physics2D.OverlapCircleAll(MyPos + Vector2.down, 4);

    Vector2 center = MyPos + Vector2.down;
    DrawWireSphere(Color.salmon, center, 4);
  }

  private void DrawAttackReach() {
    //if (CurrentState != (IState)AttackState) return;
    //Gizmos.color = Color.red;

    Vector2 direction2D = (PlayerPos - MyPos).normalized;
    Vector2 point2D = MyPos + direction2D * AttackDistance;
    //Gizmos.DrawWireSphere(point2D, AttackMaskDiameter);
    DrawWireSphere(Color.red, point2D, AttackMaskDiameter);
  }
}