using System.Collections;
using System.Collections.Generic;
using System.Threading.Tasks;
using UnityEngine;

namespace TFramework
{
    /// <summary>
    /// 音频管理器
    /// </summary>
    public class AudioManager : BaseManager
    {
        [SerializeField]
        private AudioSource _backgroundSource;

        [SerializeField]
        private AudioSource _otherSource;

        private IEnumerator _playOver;

        /// <summary>
        /// 是否静音
        /// </summary>
        public bool Mute 
        { 
            get { return _backgroundSource.mute && _otherSource.mute; }
            set
            {
                _backgroundSource.mute = value;
                _otherSource.mute = value;
            }
        }
       
        /// <summary>
        /// 背景音乐音量
        /// </summary>
        public float BackgroundVolme 
        {
            get => _backgroundSource.volume;
            set => _backgroundSource.volume = value;
               
        }

        /// <summary>
        /// 其它音效音量
        /// </summary>
        public float OtherVolme
        {
            get => _otherSource.volume;
            set => _otherSource.volume = value;
        }

        /// <summary>
        /// 播放背景音乐
        /// </summary>
        /// <param name="clip">音频资源</param>
        /// <param name="isLoop">是否循环</param>
        /// <param name="speed">播放速度</param>
        /// /// <param name="action">播放完事件</param>
        public void PlayBackgroundMusic(AudioClip clip,bool isLoop=true,float speed=1,TAction action=null)
        {
            _backgroundSource.volume = BackgroundVolme;
            PlayMusic(AudioSourceType.BackgroundSource, clip, isLoop, speed, action);
        }

        /// <summary>
        /// 暂停播放背景音乐
        /// </summary>
        public void PauseBackgroundMusic() => PauseMusic(AudioSourceType.BackgroundSource);

        /// <summary>
        /// 恢复播放背景音乐
        /// </summary>
        public void ResumeBackgroundMusic() => ResumeMusic(AudioSourceType.BackgroundSource);

        /// <summary>
        /// 停止播放背景音乐
        /// </summary>
        public void StopBackgroundMusic() => StopMusic(AudioSourceType.BackgroundSource);

        /// <summary>
        /// 播放其它音乐
        /// </summary>
        /// <param name="clip">音频资源</param>
        /// <param name="isLoop">是否循环</param>
        /// <param name="speed">播放速度</param>
        /// /// <param name="action">播放完事件</param>
        public void PlayOtherMusic(AudioClip clip, bool isLoop = false, float speed = 1,TAction action=null)
        {
            _otherSource.volume = OtherVolme;
            PlayMusic(AudioSourceType.OtherSource, clip, isLoop, speed, action);
        }

        public async Task PlayOtherMusicAsync(AudioClip clip, bool isLoop = false, float speed = 1)
        {
            _otherSource.volume = OtherVolme;
            await PlayMusic(AudioSourceType.OtherSource, clip, isLoop, speed);
        }

        /// <summary>
        /// 暂停播放其它音乐
        /// </summary>
        public void PauseOtherMusic() => PauseMusic(AudioSourceType.OtherSource);

        /// <summary>
        /// 恢复播放其它音乐
        /// </summary>
        public void ResumeOtherMusic() => ResumeMusic(AudioSourceType.OtherSource);

        /// <summary>
        /// 停止播放其它音乐
        /// </summary>
        public void StopOtherMusic() => StopMusic(AudioSourceType.OtherSource);

        /// <summary>
        /// 播放音乐
        /// </summary>
        /// <param name="type">音源类型</param>
        /// <param name="clip">音源</param>
        /// <param name="isLoop">是否循环</param>
        /// <param name="speed">播放速度</param>
        /// <param name="action">播放完事件</param>
        public void PlayMusic(AudioSourceType type, AudioClip clip, bool isLoop = true, float speed = 1,TAction action=null)
        {
            AudioSource source = GetAudioSource(type);
            if (clip == null||source==null) return;

            if (source.isPlaying)
                source.Stop();

            source.clip = clip;
            source.loop = isLoop;
            source.pitch = speed;
            source.Play();
            if(action!=null)
            {
                float time = clip.length / speed;
                if(_playOver!=null)
                {
                    StopCoroutine(_playOver);
                    _playOver = null;
                }
                _playOver = PlayOver(time,action);
                StartCoroutine(_playOver);
            }
        }

        public async Task PlayMusic(AudioSourceType type, AudioClip clip, bool isLoop = true, float speed = 1)
        {
            AudioSource source = GetAudioSource(type);
            if (clip == null || source == null) return;

            if (source.isPlaying)
                source.Stop();

            source.clip = clip;
            source.loop = isLoop;
            source.pitch = speed;
            source.Play();
            float time = clip.length / speed;
            await Task.Delay((int)time*1000);
        }

        private IEnumerator PlayOver(float time,TAction action)
        {
            yield return YieldWaitTool.YieldWaitForSeconds(time);
            action?.Invoke();
        }

        /// <summary>
        /// 停止播放音乐
        /// </summary>
        /// <param name="type">音源类型</param>
        public void StopMusic(AudioSourceType type)
        {
            AudioSource source = GetAudioSource(type);
            if (source&&source.isPlaying)
                source.Stop();
            if (_playOver != null)
            {
                StopCoroutine(_playOver);
                _playOver = null;
            }
        }

        /// <summary>
        /// 暂停播放音乐
        /// </summary>
        /// <param name="type">音源类型</param>
        public void PauseMusic(AudioSourceType type)
        {
            AudioSource source = GetAudioSource(type);
            source?.Pause();
        }

        /// <summary>
        /// 恢复播放音乐
        /// </summary>
        /// <param name="type">音源类型</param>
        public void ResumeMusic(AudioSourceType type)
        {
            AudioSource source = GetAudioSource(type);
            source?.UnPause();
        }

        private AudioSource GetAudioSource(AudioSourceType type)
        {
            switch(type)
            {
                case AudioSourceType.BackgroundSource:
                    return _backgroundSource;
                case AudioSourceType.OtherSource:
                    return _otherSource;
                default:
                    return null;
            }
        }

        public enum AudioSourceType
        {
            BackgroundSource,
            OtherSource
        }
    }
}
