using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class AudioServices : MonoBehaviour
{
    public AudioSource bgmSource;
    //public List<AudioSource> activeSource = new List<AudioSource>();
    //public List<AudioSource> inActiveSouce = new List<AudioSource>();

    Stack<AudioSource> m_audioSourceStack = new Stack<AudioSource>();
    List<AudioSource> m_lstaudioSource = new List<AudioSource>();

    static AudioServices m_Instance;
    public static AudioServices instance
    {
        get {
            if (m_Instance == null)
            {
                m_Instance = Create(null);
            }

            return m_Instance;
        }
    }

    private void Awake()
    {
        m_Instance = this;
    }

    public static AudioServices Create(Transform parent)
    {
        return new GameObject("AudioServices").AddComponent<AudioServices>();
    }

    private AudioSource GetSource()
    {
        AudioSource source = null;
        if (m_audioSourceStack.Count > 0)
        {
            source = m_audioSourceStack.Pop();
        }
        else
        {
            source = transform.gameObject.AddComponent<AudioSource>();
            source.playOnAwake = false;
            m_lstaudioSource.Add(source);
        }
        if (source)
        {
            source.volume = GlobalConfig.isEnableSound ? 1 : 0; //根据全局配置设置音量
        }
        return source;
        //AudioSource source = null;
        //if (inActiveSouce.Count > 0)
        //{
        //    source = inActiveSouce[0];
        //    inActiveSouce.RemoveAt(0);
        //    activeSource.Add(source);
        //}
        //else
        //{
        //    source = transform.gameObject.AddComponent<AudioSource>();
        //    source.playOnAwake = false;
        //    activeSource.Add(source);
        //}

        //source.volume = GlobalConfig.isEnableSound ? 1 : 0; //根据全局配置设置音量

        //return source;
    }

    private void RecycleSource(AudioSource source)
    {
        //activeSource.Remove(source);
        //inActiveSouce.Add(source);
        if (source)
        {
            m_audioSourceStack.Push(source);
            source.Stop();
            source.clip = null;
        }
    }

    public void PlayBgm(AudioClip clip)
    {
        if(!LocalRecord.HasKey(GlobalConfig.BgmKey) || LocalRecord.GetIntRecord(GlobalConfig.BgmKey) == 0)
        {
            return;
        }
        if (bgmSource == null)
        {
            bgmSource = GetSource();
        }

        bgmSource.clip = clip;
        bgmSource.loop = true;

        bgmSource.volume = GlobalConfig.isEnableBgm ? 1 : 0;  //根据全局配置设置音量

        bgmSource.Play();
    }
    //释放背景音乐
    public void RecycleBgm()
    {
        if(bgmSource)
        {
            RecycleSource(bgmSource);
            bgmSource = null;
        }
    }

    public void PlayAudio(AudioClip clip, bool isLoop = false, Action onPlayEnd = null)
    {
        if (LocalRecord.HasKey(GlobalConfig.SoundKey) && LocalRecord.GetIntRecord(GlobalConfig.SoundKey) == 0)
        {
            return;
        }
        AudioSource source = GetSource();
        source.clip = clip;
        source.loop = isLoop;
        source.volume = GlobalConfig.isEnableSound ? 1 : 0; //根据全局配置设置音量
        
        source.Play();
        GameServices.timerServices.Push(this, source.clip.length, delegate {
            RecycleSource(source);
            onPlayEnd?.Invoke();
        });
    }
    public AudioSource GetPlayAudioSource(AudioClip clip)
    {
        if (LocalRecord.HasKey(GlobalConfig.SoundKey) && LocalRecord.GetIntRecord(GlobalConfig.SoundKey) == 0)
        {
            return null;
        }
        AudioSource source = GetSource();
        source.clip = clip;
        source.loop = true;
        source.volume = GlobalConfig.isEnableSound ? 1 : 0; //根据全局配置设置音量
        source.Play();
        return source;
    }

    public void AudioPlayFinished(AudioSource source)
    {
        if (LocalRecord.HasKey(GlobalConfig.SoundKey) && LocalRecord.GetIntRecord(GlobalConfig.SoundKey) == 0)
        {
            return;
        }
        RecycleSource(source);
    }

    private IEnumerator AudioPlayFinished(AudioSource source, float time, Action callback)
    {
        yield return new WaitForSeconds(time);
        RecycleSource(source);
        callback?.Invoke();
    }

    private void OnDestroy()
    {
        //activeSource.Clear();
        //inActiveSouce.Clear();
        //activeSource = null;
        //inActiveSouce = null;
        bgmSource = null;
        m_lstaudioSource.Clear();
        m_lstaudioSource = null;
        m_audioSourceStack = null;
    }
}