using System;
using UnityEngine;
using UnityEngine.AI;
using Random = UnityEngine.Random;

public class EnemyStateFlee :IEnemyState
{
    private EnemyController _enemyController;
    private Transform _playerTransform;
    private float _fleeDistance = 5f;   // 도망치는 거리
    private float _safeRange = 7f;    // 공격 범위

    // 경로 탐색 주기 조절용
    private float _fleeSearchTimer = 0;
    private const float FleeThresholdTime = 0.2f;

    // 막다른길 검사용
    private Vector3 _lastPosition;
    private float _stuckTimer = 0f;
    private const float StuckThresholdTime = 1f;   // 1초 동안 거의 못 움직이면 막힌 걸로 간주
    private const float StuckMoveThreshold = 0.1f; // 이내 이동은 “제자리”로 본다
    private int _stuckCount = 0;

    public void Enter(EnemyController enemyController)
    {
        _enemyController = enemyController;
        Debug.Log("## Flee 상태 진입");

        _playerTransform = _enemyController.TraceTargetTransform;
        _lastPosition = _enemyController.transform.position;
        _enemyController.Agent.ResetPath();
        _enemyController.Agent.isStopped = false;
        _stuckTimer = 0f;
        _fleeSearchTimer = 0;

        _enemyController.SetAnimation(CasterDemonController.Flee, true);
    }

    public void Update()
    {
        if (!_playerTransform)
        {
            _enemyController.SetState(EnemyState.Idle);
            return;
        }

        float currentDist = Vector3.Distance(
            _enemyController.transform.position,
            _playerTransform.position
        );
        if (currentDist >= _safeRange)
        {
            // 목적지 리셋 후 전투 시작
            _enemyController.Agent.isStopped = true;
            _enemyController.Agent.ResetPath();
            _enemyController.BattleSequence();
            return;
        }

        FindPositionFlee();

        if (!_enemyController.Agent.pathPending &&
            _enemyController.Agent.pathStatus == NavMeshPathStatus.PathInvalid)
        {
            Debug.Log("## 길을 못찾음");
            HandleDeadEnd();
        }

        // 막힘 감지 (실제 이동 체크)
        CheckPath();

        _lastPosition = _enemyController.transform.position;
    }

    private void CheckPath()
    {
        float moved = Vector3.Distance(_enemyController.transform.position, _lastPosition);
        if (moved < StuckMoveThreshold)
        {
            _stuckTimer += Time.deltaTime;
            if (_stuckTimer >= StuckThresholdTime)
            {
                HandleDeadEnd();
                _stuckTimer = 0f;
            }
        }
        else
        {
            _stuckTimer = 0f;
        }
    }

    private void FindPositionFlee()
    {
        _fleeSearchTimer += Time.deltaTime;
        if (_fleeSearchTimer <= FleeThresholdTime) return;

        // 1) 목표 도망 위치 계산
        Vector3 fleeDirection = (_enemyController.transform.position - _playerTransform.position).normalized;
        Vector3 fleeTarget = _enemyController.transform.position + fleeDirection * _fleeDistance;

        // 2) 경로 계산해 보기
        _enemyController.Agent.SetDestination(fleeTarget);

        // 3) 이동
        _enemyController.Agent.isStopped = false;
        _fleeSearchTimer = 0;
    }

    private void HandleDeadEnd()
    {
        if (_stuckCount >= 4)
        {
            _enemyController.OnCannotFleeBehaviour(() => { _stuckCount = 0;});
            return;
        }
        // 무작위 도망 지점 샘플링 시도
        Vector3 randomDirection = Random.insideUnitSphere * (_fleeDistance * 2);
        randomDirection += _playerTransform.position;

        if (NavMesh.SamplePosition(randomDirection, out var hit, (_fleeDistance * 2), NavMesh.AllAreas))
        {
            // 샘플링에 성공했으면 일단 그 위치로 가 보도록 세팅
            Debug.Log("## 일단 가봄");
            _stuckCount++;
            _enemyController.Agent.SetDestination(hit.position);
            // _enemyController.OnCannotFleeBehaviour();
        }
    }


    public void Exit()
    {
        _enemyController.SetAnimation(CasterDemonController.Flee, false);
        _enemyController.Agent.isStopped = true;
        _enemyController.Agent.ResetPath();
        _playerTransform = null;
        _enemyController = null;
    }
}