using UnityEngine;

namespace IndianOceanAssets.Engine2_5D
{
    /// <summary>
    /// 敌人AI v2 —— 双重寻敌机制（视觉检测 + 铃铛响应）
    ///
    /// 状态流程：
    /// - Idle：待机。射线检测到玩家 → ChasingPlayer；收到铃铛信号 → ChasingBell
    /// - ChasingPlayer：追击玩家。持续看到玩家则追击；脱离视线3秒后 → Idle
    /// - ChasingBell：追击铃铛。追击过程中看到玩家 → ChasingPlayer；到达铃铛位置 → PatrollingBell
    /// - PatrollingBell：铃铛位置巡逻。巡逻过程中看到玩家 → ChasingPlayer；巡逻时间结束 → Idle
    ///
    /// 挂载位置：敌人预制体上
    /// 需要：场景中有 EchoSystem（用于摇铃事件）、玩家物体带 "Player" 标签
    ///       （或手动把玩家拖到 playerTarget 字段）
    /// </summary>
    public class EnemyAI : MonoBehaviour
    {
        [Header("目标")]
        [Tooltip("玩家目标（留空则自动查找 Player 标签）")]
        [SerializeField] private Transform playerTarget;

        [Header("检测与追击")]
        [Tooltip("靠近主角到此距离时停下")]
        [SerializeField] private float stopDistance = 1.2f;

        [Tooltip("追击速度")]
        [SerializeField] private float chaseSpeed = 3f;

        [Header("视觉检测")]
        [Tooltip("射线检测层（哪些物体会阻挡视线）")]
        [SerializeField] private LayerMask obstacleLayers;

        [Tooltip("射线起点偏移（避免从地面发射）")]
        [SerializeField] private float rayOffsetY = 0.5f;

        [Header("脱离计时")]
        [Tooltip("玩家脱离视线后，继续追击的时间（秒）")]
        [SerializeField] private float loseSightTime = 3f;

        [Header("聆听（摇铃响应）")]
        [Tooltip("聆听范围：主角在此范围内按E摇铃时，敌人会朝铃铛位置移动")]
        [SerializeField] private float listenRange = 15f;

        [Header("铃铛追击")]
        [Tooltip("到达铃铛位置后的容差距离")]
        [SerializeField] private float bellArriveDistance = 1f;

        [Tooltip("追击铃铛的最大时间（超时则放弃）")]
        [SerializeField] private float bellChaseTimeout = 10f;

        [Header("铃铛巡逻")]
        [Tooltip("到达铃铛位置后的巡逻时间")]
        [SerializeField] private float bellPatrolTime = 5f;

        [Tooltip("巡逻半径")]
        [SerializeField] private float bellPatrolRadius = 3f;

        // 状态枚举
        private enum State 
        { 
            Idle,              // 待机
            ChasingPlayer,     // 追击玩家
            ChasingBell,       // 追击铃铛
            PatrollingBell     // 铃铛位置巡逻
        }

        private State _state = State.Idle;
        
        // 脱离视线计时器
        private float _loseSightTimer;
        
        // 铃铛相关
        private Vector3 _bellTargetPosition;     // 铃铛目标位置
        private float _bellChaseTimer;           // 铃铛追击计时器
        
        // 巡逻相关
        private Vector3 _patrolCenter;           // 巡逻中心点
        private float _patrolTimer;              // 巡逻计时器
        private Vector3 _patrolTarget;           // 当前巡逻目标点

        private void Start()
        {
            if (playerTarget == null)
            {
                var player = GameObject.FindWithTag("Player");
                if (player != null)
                    playerTarget = player.transform;
            }
        }

        private void OnEnable()
        {
            EchoSystem.OnEchoReleased += OnBell;
        }

        private void OnDisable()
        {
            EchoSystem.OnEchoReleased -= OnBell;
        }

        private void Update()
        {
            switch (_state)
            {
                case State.Idle:              UpdateIdle();              break;
                case State.ChasingPlayer:     UpdateChasingPlayer();     break;
                case State.ChasingBell:       UpdateChasingBell();       break;
                case State.PatrollingBell:    UpdatePatrollingBell();    break;
            }
        }

        // ===== Idle：待机，等待检测 =====
        private void UpdateIdle()
        {
            // 检测是否看到玩家
            if (CanSeePlayer())
            {
                _state = State.ChasingPlayer;
                _loseSightTimer = 0f;
                return;
            }
        }

        // ===== ChasingPlayer：追击玩家 =====
        private void UpdateChasingPlayer()
        {
            // 检测是否看到玩家
            if (CanSeePlayer())
            {
                _loseSightTimer = 0f;  // 重置计时器
                
                // 追击玩家
                float dist = XZDistance(transform.position, playerTarget.position);
                if (dist > stopDistance)
                {
                    MoveToward(playerTarget.position, chaseSpeed);
                }
            }
            else
            {
                // 玩家脱离视线，开始计时
                _loseSightTimer += Time.deltaTime;
                
                // 继续朝玩家最后已知位置移动
                if (playerTarget != null)
                {
                    float dist = XZDistance(transform.position, playerTarget.position);
                    if (dist > stopDistance)
                    {
                        MoveToward(playerTarget.position, chaseSpeed);
                    }
                }
                
                // 超过设定时间，停止追击
                if (_loseSightTimer >= loseSightTime)
                {
                    _state = State.Idle;
                }
            }
        }

        // ===== ChasingBell：追击铃铛 =====
        private void UpdateChasingBell()
        {
            // 追击过程中检测是否看到玩家
            if (CanSeePlayer())
            {
                _state = State.ChasingPlayer;
                _loseSightTimer = 0f;
                return;
            }
            
            // 追击计时
            _bellChaseTimer += Time.deltaTime;
            if (_bellChaseTimer >= bellChaseTimeout)
            {
                _state = State.Idle;
                return;
            }
            
            // 检测是否到达铃铛位置
            float dist = XZDistance(transform.position, _bellTargetPosition);
            if (dist <= bellArriveDistance)
            {
                // 到达铃铛位置，开始巡逻
                _state = State.PatrollingBell;
                _patrolCenter = _bellTargetPosition;
                _patrolTimer = 0f;
                PickNewPatrolPoint();
                return;
            }
            
            // 朝铃铛位置移动
            MoveToward(_bellTargetPosition, chaseSpeed);
        }

        // ===== PatrollingBell：铃铛位置巡逻 =====
        private void UpdatePatrollingBell()
        {
            // 巡逻过程中检测是否看到玩家
            if (CanSeePlayer())
            {
                _state = State.ChasingPlayer;
                _loseSightTimer = 0f;
                return;
            }
            
            // 巡逻计时
            _patrolTimer += Time.deltaTime;
            if (_patrolTimer >= bellPatrolTime)
            {
                _state = State.Idle;
                return;
            }
            
            // 朝巡逻点移动
            float dist = XZDistance(transform.position, _patrolTarget);
            if (dist <= 0.5f)
            {
                // 到达巡逻点，选择新的巡逻点
                PickNewPatrolPoint();
            }
            else
            {
                MoveToward(_patrolTarget, chaseSpeed * 0.7f);  // 巡逻时速度稍慢
            }
        }

        // ===== 摇铃事件回调（由 EchoSystem.OnEchoReleased 触发）=====
        private void OnBell(Vector3 bellPos)
        {
            if (playerTarget == null) return;
            
            // 只有在聆听范围内才响应
            if (XZDistance(transform.position, bellPos) > listenRange) return;
            
            // 设置铃铛目标位置
            _bellTargetPosition = bellPos;
            _bellChaseTimer = 0f;
            
            // 切换到追击铃铛状态（可以打断任何状态）
            _state = State.ChasingBell;
        }

        /// <summary>
        /// 选择新的巡逻点
        /// </summary>
        private void PickNewPatrolPoint()
        {
            // 在巡逻中心周围随机选择一个点
            Vector2 randomDir = Random.insideUnitCircle * bellPatrolRadius;
            _patrolTarget = _patrolCenter + new Vector3(randomDir.x, 0f, randomDir.y);
        }

        /// <summary>
        /// 检测是否能看到玩家（射线检测）
        /// </summary>
        private bool CanSeePlayer()
        {
            if (playerTarget == null) return false;
            
            // 射线起点（稍微抬高，避免从地面发射）
            Vector3 rayStart = transform.position + Vector3.up * rayOffsetY;
            Vector3 rayEnd = playerTarget.position + Vector3.up * rayOffsetY;
            Vector3 dir = rayEnd - rayStart;
            float dist = dir.magnitude;
            
            // 调试：在Scene视图中绘制射线
            Debug.DrawLine(rayStart, rayEnd, CanSeePlayerDebugColor());
            
            // 发射射线，只检测障碍物层
            if (Physics.Raycast(rayStart, dir.normalized, out RaycastHit hit, dist, obstacleLayers))
            {
                // 击中了物体
                Debug.DrawLine(rayStart, hit.point, Color.red);
                
                // 如果击中的是玩家，说明可以看到
                if (hit.transform == playerTarget)
                {
                    return true;
                }
                
                // 击中了其他物体（被遮挡）
                return false;
            }
            
            // 没有击中任何物体 = 没有遮挡 = 可以看到玩家
            return true;
        }
        
        /// <summary>
        /// 调试用：根据是否能看到玩家返回不同颜色
        /// </summary>
        private Color CanSeePlayerDebugColor()
        {
            if (playerTarget == null) return Color.gray;
            
            Vector3 rayStart = transform.position + Vector3.up * rayOffsetY;
            Vector3 rayEnd = playerTarget.position + Vector3.up * rayOffsetY;
            Vector3 dir = rayEnd - rayStart;
            float dist = dir.magnitude;
            
            if (Physics.Raycast(rayStart, dir.normalized, out RaycastHit hit, dist, obstacleLayers))
            {
                return hit.transform == playerTarget ? Color.green : Color.red;
            }
            return Color.green;  // 没有遮挡
        }

        // ===== 工具方法 =====

        private void MoveToward(Vector3 target, float speed)
        {
            Vector3 dir = new Vector3(
                target.x - transform.position.x,
                0f,
                target.z - transform.position.z
            );
            float dist = dir.magnitude;
            if (dist < 0.01f) return;

            dir /= dist;
            Vector3 move = dir * speed * Time.deltaTime;
            if (move.magnitude > dist) move = dir * dist; // 不越过目标
            transform.position += new Vector3(move.x, 0f, move.z);
        }

        private float XZDistance(Vector3 a, Vector3 b)
        {
            float dx = a.x - b.x;
            float dz = a.z - b.z;
            return Mathf.Sqrt(dx * dx + dz * dz);
        }

        // ===== 编辑器可视化 =====
        private void OnDrawGizmosSelected()
        {
            // 根据状态显示不同颜色
            Color stateColor = Color.white;
            switch (_state)
            {
                case State.Idle: stateColor = Color.gray; break;
                case State.ChasingPlayer: stateColor = Color.red; break;
                case State.ChasingBell: stateColor = Color.yellow; break;
                case State.PatrollingBell: stateColor = Color.cyan; break;
            }
            
            // 绘制当前状态指示
            Gizmos.color = stateColor;
            Gizmos.DrawWireSphere(transform.position, 0.5f);
            
            // 绘制聆听范围
            Gizmos.color = new Color(0f, 0.85f, 1f, 0.3f);
            Gizmos.DrawWireSphere(transform.position, listenRange);
            
            // 绘制停止距离
            Gizmos.color = new Color(1f, 0.3f, 0.3f, 0.3f);
            Gizmos.DrawWireSphere(transform.position, stopDistance);
            
            // 绘制铃铛目标（如果在追击铃铛或巡逻）
            if (_state == State.ChasingBell || _state == State.PatrollingBell)
            {
                Gizmos.color = Color.yellow;
                Gizmos.DrawWireSphere(_bellTargetPosition, bellArriveDistance);
                
                // 绘制到铃铛的连线
                Gizmos.DrawLine(transform.position, _bellTargetPosition);
            }
            
            // 绘制巡逻范围（如果在巡逻）
            if (_state == State.PatrollingBell)
            {
                Gizmos.color = Color.cyan;
                Gizmos.DrawWireSphere(_patrolCenter, bellPatrolRadius);
                
                // 绘制当前巡逻目标
                Gizmos.color = Color.green;
                Gizmos.DrawWireSphere(_patrolTarget, 0.3f);
            }
        }

        /// <summary>当前状态（调试用）</summary>
        public string CurrentState => _state.ToString();
    }
}
