using System.Collections;
using UnityEngine;
using UnityEngine.AI;

public class EnemyMovement : MonoBehaviour
{
    [Header("Navigation")]
    public NavMeshAgent agent;
    public Transform player;
    public float updatePathInterval = 0.5f;
    public float roomCheckInterval = 2f;

    [Header("Combat")]
    public float sightRange = 20f;
    public float patrolRange = 5f;

    [Header("References")]
    public EnemyAttack enemyAttack;

    private enum EnemyState { Patrolling, Chasing, Attacking }
    private EnemyState currentState = EnemyState.Patrolling;
    private Vector3 patrolCenter;
    private Vector3 patrolTarget;
    private float lastStateChangeTime;
    private float minAttackStateDuration = 1.0f;
    private float attackRange;

    [Header("Animation")]
    public Animator animator;

    private void Start()
    {
        // Najdi hráče
        GameObject playerObject = GameObject.FindWithTag("Player");
        attackRange = enemyAttack.GetAttackRange();

        if (playerObject != null)
        {
            player = playerObject.transform;
        }

        // Najdi EnemyAttack komponentu
        if (enemyAttack == null)
        {
            enemyAttack = GetComponent<EnemyAttack>();
        }

        // Nastav výchozí pozice
        patrolCenter = transform.position;
        GenerateNewPatrolTarget();
        lastStateChangeTime = Time.time;

        // Spustit coroutines
        if (agent != null)
        {
            agent.stoppingDistance = attackRange - 0.2f;
            StartCoroutine(UpdatePath());
            StartCoroutine(CheckPlayerInRange());
            StartCoroutine(CheckCurrentRoom());
        }
    }

    private void Update()
    {
        if (agent == null) return;

        // Update animací
        if (animator != null)
        {
            animator.SetFloat("Speed", agent.velocity.magnitude);
        }

        // Stavové chování
        switch (currentState)
        {
            case EnemyState.Patrolling:
                PatrolBehavior();
                break;
            case EnemyState.Chasing:
                ChaseBehavior();
                break;
            case EnemyState.Attacking:
                AttackBehavior();
                break;
        }
    }

    private void PatrolBehavior()
    {
        // Pokud je cíl patrolování dosažen, vyber nový cíl
        if (!agent.pathPending && agent.remainingDistance <= agent.stoppingDistance)
        {
            GenerateNewPatrolTarget();
        }

        // Kontrola, zda hráč není v dohledu i během patrolování
        if (player != null && enemyAttack != null && enemyAttack.IsPlayerInAttackRange())
        {
            ChangeState(EnemyState.Attacking);
        }
    }

    private void ChaseBehavior()
    {
        if (player == null)
        {
            ChangeState(EnemyState.Patrolling);
            return;
        }

        float distanceToPlayer = Vector3.Distance(transform.position, player.position);

        // Přepni do attack stavu pouze pokud může útočit a je v dosahu
        if (enemyAttack != null && enemyAttack.IsPlayerInAttackRange() && enemyAttack.CanAttack())
        {
            ChangeState(EnemyState.Attacking);
            return;
        }

        if (distanceToPlayer > sightRange * 1.5f)
        {
            ChangeState(EnemyState.Patrolling);
            GenerateNewPatrolTarget();
        }
    }

    private void AttackBehavior()
    {
        if (player == null || enemyAttack == null)
        {
            ChangeState(EnemyState.Chasing);
            return;
        }

        // RYCHLEJŠÍ a PŘESNĚJŠÍ otáčení k hráči
        Vector3 directionToPlayer = (player.position - transform.position).normalized;

        // Ignoruj Y osu pro rotaci
        directionToPlayer.y = 0;

        if (directionToPlayer != Vector3.zero)
        {
            Quaternion targetRotation = Quaternion.LookRotation(directionToPlayer);
            transform.rotation = Quaternion.Slerp(transform.rotation, targetRotation, 15f * Time.deltaTime); // Zvýšená rychlost otáčení
        }

        // Zkus zaútočit
        bool attackAttempted = enemyAttack.TryAttack();

        float distanceToPlayer = Vector3.Distance(transform.position, player.position);

        // Zůstaň v attack stavu pokud může útočit nebo se otáčí k hráči
        if (attackAttempted && enemyAttack.CanAttack())
        {
            return;
        }

        // Pokud je hráč příliš daleko, pokračuj v pronásledování
        if (distanceToPlayer > attackRange && !enemyAttack.IsAttacking())
        {
            ChangeState(EnemyState.Chasing);
        }
    }

    private IEnumerator CheckPlayerInRange()
    {
        while (true)
        {
            if (player != null && !enemyAttack.IsAttacking())
            {
                float distanceToPlayer = Vector3.Distance(transform.position, player.position);

                if (currentState == EnemyState.Patrolling && distanceToPlayer <= sightRange)
                {
                    ChangeState(EnemyState.Chasing);
                }
                else if (currentState == EnemyState.Chasing && distanceToPlayer > sightRange * 1.5f)
                {
                    ChangeState(EnemyState.Patrolling);
                }
                else if (currentState == EnemyState.Chasing && distanceToPlayer <= attackRange && enemyAttack.CanAttack())
                {
                    ChangeState(EnemyState.Attacking);
                }
            }

            yield return new WaitForSeconds(0.1f);
        }
    }

    private void ChangeState(EnemyState newState)
    {
        if (currentState == newState) return;

        currentState = newState;
        lastStateChangeTime = Time.time;

        // Specifické akce při změně stavu
        switch (newState)
        {
            case EnemyState.Chasing:
                agent.isStopped = false;
                break;
            case EnemyState.Patrolling:
                agent.isStopped = false;
                GenerateNewPatrolTarget();
                break;
        }
    }

    private IEnumerator UpdatePath()
    {
        while (true)
        {
            if (currentState == EnemyState.Chasing && player != null && !enemyAttack.IsAttacking())
            {
                agent.SetDestination(player.position);
            }
            else if (currentState == EnemyState.Patrolling && !enemyAttack.IsAttacking())
            {
                agent.SetDestination(patrolTarget);
            }

            yield return new WaitForSeconds(updatePathInterval);
        }
    }

    private IEnumerator CheckCurrentRoom()
    {
        while (true)
        {
            if (!agent.isOnNavMesh && !enemyAttack.IsAttacking())
            {
                agent.Warp(transform.position);
            }

            yield return new WaitForSeconds(roomCheckInterval);
        }
    }

    /* ========= PATROLLING IN CASE PLAYER IS FAR ========== */
    private void GenerateNewPatrolTarget()
    {
        Vector2 randomCircle = Random.insideUnitCircle * patrolRange;
        patrolTarget = patrolCenter + new Vector3(randomCircle.x, 0, randomCircle.y);

        NavMeshHit hit;
        if (NavMesh.SamplePosition(patrolTarget, out hit, patrolRange, NavMesh.AllAreas))
        {
            patrolTarget = hit.position;
        }
    }

    // Voláno při smrti nepřítele
    public void Die()
    {
        StopAllCoroutines();

        if (agent != null)
        {
            agent.isStopped = true;
        }

        if (enemyAttack != null)
        {
            enemyAttack.SetAttackState(false);
        }

        Destroy(gameObject, 2f);
    }


    /*====== FOR DEBUGGING PURPOSES ONLY ========== */
    //private void OnDrawGizmosSelected()
    //{
    //    Gizmos.color = Color.red;
    //    Gizmos.DrawWireSphere(transform.position, attackRange);

    //    Gizmos.color = Color.yellow;
    //    Gizmos.DrawWireSphere(transform.position, sightRange);

    //    Gizmos.color = Color.blue;
    //    Gizmos.DrawWireSphere(patrolCenter, patrolRange);

    //    if (Application.isPlaying)
    //    {
    //        Gizmos.color = Color.green;
    //        Gizmos.DrawSphere(patrolTarget, 0.3f);
    //        Gizmos.DrawLine(transform.position, patrolTarget);
    //    }
    //}

    //private void OnGUI()
    //{
    //    if (Application.isPlaying && enemyAttack != null)
    //    {
    //        GUI.Label(new Rect(10, 30, 300, 20), $"State: {currentState}");
    //        GUI.Label(new Rect(10, 50, 300, 20), $"CanAttack: {enemyAttack.CanAttack()}");
    //        GUI.Label(new Rect(10, 70, 300, 20), $"IsAttacking: {enemyAttack.IsAttacking()}");
    //        GUI.Label(new Rect(10, 90, 300, 20), $"Cooldown: {enemyAttack.GetCooldownProgress():P0}");

    //        if (player != null)
    //        {
    //            float distance = Vector3.Distance(transform.position, player.position);
    //            GUI.Label(new Rect(10, 110, 300, 20), $"Distance: {distance:F2}");
    //        }
    //    }
    //}
}