using System.Collections.Generic;
using UnityEngine;

// ============================================================================
// EnemySpawner
// ----------------------------------------------------------------------------
// 단순한 적 스폰 컨트롤러 (웨이브 없이 자동 스폰/리스폰).
// WaveManager가 시간 제한 스폰이라면, 이건 무한/제한 스폰의 일반 패턴.
//
// 사용 예시:
//   - 테스트 씬: Max Alive 1 + Respawn 켜기 → 한 마리씩 무한 등장
//   - 아레나: Max Alive 5 + Total Limit 20 + Respawn 켜기 → 총 20마리, 동시 5
//   - 일회성 매복: Spawn On Start 끄고 외부에서 SpawnNow() 호출
// ============================================================================
public class EnemySpawner : MonoBehaviour
{
    // ─── 스폰 설정 ───────────────────────────────────────────────────────
    [Header("Spawn Configuration")]
    [SerializeField] private Enemy _enemyPrefab;     // 스폰할 적 프리팹
    [SerializeField] private int _maxAliveCount = 3; // 동시에 살아있을 수 있는 최대 수
    [SerializeField] private float _spawnInterval = 2f; // 스폰 간격 (초)
    [SerializeField] private float _initialDelay = 0f;  // 첫 스폰 전 대기 시간

    // ─── 위치 설정 ───────────────────────────────────────────────────────
    [Header("Spawn Position")]
    [SerializeField] private Transform[] _spawnPoints; // 비워두면 자기 위치, 여러 개면 랜덤 선택
    [SerializeField] private float _spawnRadius = 0f;   // 0보다 크면 spawn point 주변 무작위 분산
    [SerializeField] private Transform _enemyParent;    // 스폰된 적을 묶을 부모 (Hierarchy 정리용)

    // ─── 동작 옵션 ───────────────────────────────────────────────────────
    [Header("Behavior")]
    [SerializeField] private bool _spawnOnStart = true;   // Start에서 자동 스폰 시작
    [SerializeField] private bool _respawnOnDeath = true; // 죽으면 자동 리스폰 (false면 일회성)
    [SerializeField] private int _totalSpawnLimit = 0;    // 누적 스폰 한도 (0이면 무제한)

    private readonly List<Enemy> _aliveEnemies = new();   // 현재 살아있는 적들 (자동 정리됨)
    private float _nextSpawnTime;                          // 다음 스폰 가능 시각
    private int _totalSpawned;                             // 지금까지 누적 스폰 수
    private bool _active;                                  // 스폰 활성 상태

    private void Start()
    {
        if (_spawnOnStart) BeginSpawning();
    }

    // 외부 트리거에서 스폰 시작 (예: 플레이어가 영역 진입).
    public void BeginSpawning()
    {
        _active = true;
        _nextSpawnTime = Time.time + _initialDelay;
    }

    // 스폰 일시 중지. 살아있는 적은 그대로 유지.
    public void StopSpawning() => _active = false;

    // 스폰 + 살아있는 적 모두 제거 + 카운터 초기화. 재시작용.
    public void ResetSpawner()
    {
        for (int i = _aliveEnemies.Count - 1; i >= 0; i--)
        {
            if (_aliveEnemies[i] != null)
                Destroy(_aliveEnemies[i].gameObject);
        }
        _aliveEnemies.Clear();
        _totalSpawned = 0;
        _nextSpawnTime = Time.time + _initialDelay;
    }

    private void Update()
    {
        if (!_active) return;

        // Destroy된 적 참조는 null이 됨. 자동 정리.
        _aliveEnemies.RemoveAll(e => e == null);

        // 조기 종료 조건들:
        if (!_respawnOnDeath && _aliveEnemies.Count == 0 && _totalSpawned > 0) return;  // 일회성이고 다 죽었으면 끝
        if (_totalSpawnLimit > 0 && _totalSpawned >= _totalSpawnLimit) return;          // 누적 한도 도달
        if (_aliveEnemies.Count >= _maxAliveCount) return;                              // 동시 최대치 도달
        if (Time.time < _nextSpawnTime) return;                                         // 다음 스폰 시간 안 됨
        if (_enemyPrefab == null) return;

        SpawnOne();
        _nextSpawnTime = Time.time + _spawnInterval;
    }

    // 1마리 즉시 스폰. 외부에서 직접 호출 가능 (예: 이벤트 트리거).
    public Enemy SpawnOne()
    {
        if (_enemyPrefab == null) return null;

        Vector3 spawnPos = GetSpawnPosition();
        Enemy enemy = Instantiate(_enemyPrefab, spawnPos, Quaternion.identity, _enemyParent);
        _aliveEnemies.Add(enemy);
        _totalSpawned++;
        return enemy;
    }

    // 스폰 위치 결정:
    //   1) Spawn Points 있으면 그중 랜덤 선택
    //   2) 없으면 자기 위치
    //   3) Spawn Radius > 0이면 위 위치에서 ±radius 무작위 오프셋 추가
    private Vector3 GetSpawnPosition()
    {
        Vector3 basePos;
        if (_spawnPoints != null && _spawnPoints.Length > 0)
        {
            Transform pick = _spawnPoints[Random.Range(0, _spawnPoints.Length)];
            basePos = pick != null ? pick.position : transform.position;
        }
        else
        {
            basePos = transform.position;
        }

        if (_spawnRadius > 0f)
        {
            Vector2 offset = Random.insideUnitCircle * _spawnRadius;
            basePos.x += offset.x;
            basePos.y += offset.y;
        }

        return basePos;
    }

    // Scene 뷰에서 스폰 위치/반경 시각화.
    // 각 spawn point마다 시안색 원(위치)과 반경 원(분산) 표시.
    private void OnDrawGizmosSelected()
    {
        Color pointColor = Color.cyan;
        Color radiusColor = new Color(0f, 1f, 1f, 0.25f);

        if (_spawnPoints != null && _spawnPoints.Length > 0)
        {
            foreach (var p in _spawnPoints)
            {
                if (p == null) continue;
                Gizmos.color = pointColor;
                Gizmos.DrawWireSphere(p.position, 0.3f);
                if (_spawnRadius > 0f)
                {
                    Gizmos.color = radiusColor;
                    Gizmos.DrawWireSphere(p.position, _spawnRadius);
                }
            }
        }
        else
        {
            Gizmos.color = pointColor;
            Gizmos.DrawWireSphere(transform.position, 0.3f);
            if (_spawnRadius > 0f)
            {
                Gizmos.color = radiusColor;
                Gizmos.DrawWireSphere(transform.position, _spawnRadius);
            }
        }
    }
}
