using System;
using System.Threading;
using UnityEngine;

// ============================================================================
// BossSkill
// ----------------------------------------------------------------------------
// 보스 "특별 스킬"의 베이스 클래스. 스킬 하나 = 자기완결적 프리팹 하나.
//
//   [스킬 프리팹] = BossSkill(상속) 컴포넌트 + 자체 Animator + HazardHitbox 자식들
//
// 동작 흐름:
//   - BossAI._skillPrefabs에 프리팹을 등록 (씬 인스턴스가 아닌 에셋 참조)
//   - 시전 시 BossAI가 프리팹을 Instantiate → Begin() 호출
//   - 스킬은 시퀀스가 끝나면 스스로 Destroy
//   - 취소(페이즈 전환·사망)는 BossAI가 인스턴스를 Destroy → 콜라이더도 함께 사라짐
//
// MinPhase/Range/Cooldown은 BossAI가 프리팹에서 직접 읽어 사용 가능 여부를 판단.
// 쿨다운 "타이머"는 보스별 상태라 BossAI가 추적한다.
//
// 새 스킬 추가: BossSkill을 상속한 컴포넌트로 프리팹을 만들고 RunSkill만 구현.
// ============================================================================
public abstract class BossSkill : MonoBehaviour
{
    [Header("BossSkill")]
    [SerializeField] private int _minPhase;          // 이 페이즈(0부터) 이상에서만 사용 가능
    [SerializeField] private float _range = 4f;      // 타겟이 이 X거리 안일 때만 사용
    [SerializeField] private float _cooldown = 8f;   // 재사용 대기 (타이머는 BossAI가 보스별로 추적)
    [SerializeField] private string _casterAnimationState = "BossCast";  // 시전 중 보스가 재생할 애니메이션

    [Header("Audio")]
    [SerializeField] private AudioClip _castSound;   // 시전(발동) 사운드. 명중 여부와 무관하게 스킬 시작 시 항상 재생 (null이면 없음)
    [SerializeField, Range(0f, 1f)] private float _castSoundVolume = 1f;  // 시전 사운드 볼륨

    public int MinPhase => _minPhase;
    public float Range => _range;
    public float Cooldown => _cooldown;
    public string CasterAnimationState => _casterAnimationState;

    // BossAI가 인스턴스를 만든 직후 호출. 시퀀스를 끝까지 실행하고 스스로 파괴한다.
    // destroyCancellationToken: BossAI가 이 인스턴스를 Destroy하면 시퀀스가 취소된다.
    public async void Begin()
    {
        PlayCastSound();

        try
        {
            await RunSkill(destroyCancellationToken);
        }
        catch (OperationCanceledException)
        {
            return;  // 외부에서 Destroy됨 → GameObject 이미 파괴 중이므로 그대로 종료
        }
        catch (Exception e)
        {
            
        }

        Destroy(gameObject);
    }

    // 시전(발동) 사운드 재생. 명중 여부와 무관하게 스킬 시작 시 항상 1회 재생.
    // AudioManager의 SFX 풀을 통해 믹서로 라우팅된다.
    private void PlayCastSound()
    {
        if (_castSound == null || AudioManager.Instance == null) return;
        AudioManager.Instance.PlaySfx(_castSound, _castSoundVolume);
    }

    // 서브클래스가 실제 스킬 시퀀스를 구현. token이 취소되면 finally에서 정리할 것.
    protected abstract Awaitable RunSkill(CancellationToken token);
}
