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

[RequireComponent(typeof(NavMeshAgent))]
public class EnemyMoveDefault : MonoBehaviour
{
    [Header("Movement Settings")]
    [SerializeField] private Transform _finalTarget;     // 최종 목적지 (Core)
    [SerializeField] private float _updateInterval = 0.2f; // 경로 갱신 간격
    [SerializeField] private float _detectionRange = 1.5f; // 전방 장애물 감지 거리

    private Transform _currentTarget;  // 현재 추적 중인 대상
    private NavMeshAgent _agent;
    private EnemyAttack _attackScript;
    private Coroutine _pathUpdateCoroutine;

    // EnemyAttack 스크립트에서 현재 타겟을 참조하기 위한 프로퍼티
    public Transform Target => _currentTarget;

    void Awake()
    {
        _agent = GetComponent<NavMeshAgent>();
        _attackScript = GetComponent<EnemyAttack>();

        // 인스펙터에서 비어있다면 태그로 자동으로 찾음
        if (_finalTarget == null)
        {
            GameObject core = GameObject.FindWithTag("Core"); // Core 오브젝트에 "Core" 태그를 달아주세요.
            if (core != null) _finalTarget = core.transform;
        }

        _currentTarget = _finalTarget;
    }

    void OnEnable()
    {
        if (_pathUpdateCoroutine != null) StopCoroutine(_pathUpdateCoroutine);
        _pathUpdateCoroutine = StartCoroutine(UpdatePathRoutine());
    }

    void OnDisable()
    {
        if (_pathUpdateCoroutine != null) StopCoroutine(_pathUpdateCoroutine);
    }

    IEnumerator UpdatePathRoutine()
    {
        // Agent가 NavMesh에 배치될 시간을 줌
        yield return null;
        WaitForSeconds delay = new WaitForSeconds(_updateInterval);

        while (true)
        {
            // 1. 타겟 유효성 체크: 타겟이 파괴되었으면 다시 코어로 설정
            if (_currentTarget == null || !_currentTarget.gameObject.activeInHierarchy)
            {
                _currentTarget = _finalTarget;
                _agent.isStopped = false;
            }

            if (_currentTarget != null && _agent.isOnNavMesh)
            {
                float distance = Vector3.Distance(transform.position, _currentTarget.position);

                // 2. 공격 사거리 체크 (EnemyAttack의 사거리 참조)
                if (distance <= _attackScript.attackRange)
                {
                    // 사거리 안이면 멈춤
                    _agent.isStopped = true;
                    _agent.velocity = Vector3.zero;
                }
                else
                {
                    // 3. 사거리 밖이면 전방 장애물(성벽 등) 감지
                    DetectObstacle();

                    // 4. 장애물 때문에 멈춘 게 아니라면 목적지로 전진
                    if (!_agent.isStopped)
                    {
                        _agent.SetDestination(_currentTarget.position);
                    }
                }
            }
            yield return delay;
        }
    }

    /// <summary>
    /// 레이캐스트를 쏴서 전방에 길을 막는 IDamageable(성벽)이 있는지 확인
    /// </summary>
    private void DetectObstacle()
    {
        RaycastHit hit;
        // 적의 위치(발밑)보다 약간 위(가슴 높이)에서 전방으로 레이 발사
        Vector3 rayOrigin = transform.position + Vector3.up * 1.0f;

        // Scene 뷰에서 레이를 시각적으로 확인 (디버깅용)
        Debug.DrawRay(rayOrigin, transform.forward * _detectionRange, Color.yellow);

        if (Physics.Raycast(rayOrigin, transform.forward, out hit, _detectionRange))
        {
            // 부딪힌 대상에게서 IDamageable 인터페이스 확인
            IDamageable damageable = hit.collider.GetComponentInParent<IDamageable>();

            // 대상이 존재하고, 그 대상이 현재 코어가 아닐 때 (즉, 가로막는 성벽일 때)
            if (damageable != null && hit.collider.transform != _finalTarget)
            {
                _currentTarget = hit.collider.transform;

                // 공격 스크립트에도 즉시 새로운 타겟을 알려줌
                _attackScript.SetAttackTarget(_currentTarget);

                // 일단 멈추고 다음 루프에서 사거리 체크를 받도록 함
                _agent.isStopped = true;
                _agent.velocity = Vector3.zero;
            }
        }
    }

    /// <summary>
    /// 외부(스패너 등)에서 최종 목적지를 설정해줄 때 사용
    /// </summary>
    public void SetFinalTarget(Transform target)
    {
        _finalTarget = target;
        _currentTarget = target;
    }
}