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

namespace WS
{
    [ObjectSystem]
    public class VoiceManagerAwakeSystem : AwakeSystem<VoiceManager>
    {
        public override void Awake(VoiceManager self)
        {
            self.Awake();
        }
    }

    ///<summary>Voice管理器</summary>
    public class VoiceManager : SingleComponent<VoiceManager>
    {
        ///<summary>现在所有在播放的Audio</summary>
        private Dictionary<VoiceType, List<VoiceEntity>> NowAudio = new Dictionary<VoiceType, List<VoiceEntity>>();
        ///<summary>Voice配置</summary>
        private List<ResourcePath> Config;
        ///<summary>回收后对象的父节点</summary>
        private Transform VoiceRootParent;

        private float _volume = 1;
        /// <summary>音量</summary> 
        public float Volume
        {
            get { return _volume; }
            set
            {
                _volume = value;
                foreach (var item in NowAudio)
                {
                    List<VoiceEntity> list = item.Value;
                    for (int i = 0; i < list.Count; i++)
                    {
                        list[i].SourceVolume = _volume;
                    }
                }
            }
        }

        private bool _ismute = false;
        /// <summary>静音</summary> 
        public bool IsMute
        {
            get { return _ismute; }
            set
            {
                _ismute = value;
                foreach (var item in NowAudio)
                {
                    List<VoiceEntity> list = item.Value;
                    for (int i = 0; i < list.Count; i++)
                    {
                        list[i].SourceVolume = _ismute ? 0 : Volume;
                    }
                }
            }
        }

        ///<summary>暂停</summary>
        private bool IsPause = false;

        public void Awake()
        {
            if (PlayerPrefs.HasKey("Volume"))
                _volume = PlayerPrefs.GetFloat("Volume");
            VoiceRootParent = new GameObject("VoiceRootParent").transform;
            VoiceRootParent.SetParent(Game.Init);

            Config = ConfigHelper.LoadConfig<List<ResourcePath>>("Config/Framework/VoiceConfig");
            string[] array = Enum.GetNames(typeof(VoiceType));
            for (int i = 0; i < array.Length; i++)
            {
                NowAudio.Add((VoiceType)i, new List<VoiceEntity>());
            }
        }

        ///<summary>保存音量</summary>
        public void SaveVolume()
        {
            PlayerPrefs.SetFloat("Volume", _volume);
        }

        /// <summary>获取空的Voice</summary>
        public VoiceEntity GetNullVoice()
        {
            GameObject obj = GamePoolManager.Instance.CreateObject("NullAudioSource");
            AudioSource source = obj.GetComponent<AudioSource>();
            source.volume = Volume;
            VoiceEntity entity = ComponentFactory.CreateWithParent<VoiceEntity>(this);
            entity.StartDate(VoiceType.BGM, source);
            NowAudio[VoiceType.BGM].Add(entity);
            return entity;
        }

        /// <summary>播放</summary>
        /// <param name="type">播放类型</param>
        /// <param name="name">Audio名称</param>
        /// <param name="oncallback">回调</param>
        public VoiceEntity Play(VoiceType type, string name, Action oncallback)
        {
            return Play(type, name, 0, false, oncallback);
        }

        /// <summary>播放</summary>
        /// <param name="type">播放类型</param>
        /// <param name="name">Audio名称</param>
        /// <param name="loop">是否重复播放</param>
        /// <param name="oncallback">回调</param>
        public VoiceEntity Play(VoiceType type, string name, bool loop, Action oncallback)
        {
            return Play(type, name, 0, loop, oncallback);
        }

        /// <summary>播放</summary>
        /// <param name="type">播放类型</param>
        /// <param name="name">Audio名称</param>
        /// <param name="volume">音量</param>
        /// <param name="playtime">播放时间(如果对于0 ，会在时间到时自动停止，并且调用回调)</param>
        /// <param name="loop">是否重复播放</param>
        public VoiceEntity Play(VoiceType type, string name, float playtime = 0, bool loop = false, Action oncallback = null)
        {
            ResourcePath path = Config.Find(v => v.Name == name);
            if (path != null)
            {
                GameObject obj = GamePoolManager.Instance.CreateObject(path.Path);
                obj.name = name;
                obj.transform.SetParent(VoiceRootParent, false);
                AudioSource source = obj.GetComponent<AudioSource>();
                if (type == VoiceType.BGM) loop = true;
                source.loop = loop;
                source.volume = Volume;
                VoiceEntity entity = ComponentFactory.CreateWithParent<VoiceEntity>(this);
                entity.StartDate(type, source, playtime, oncallback);
                entity.Play();
                NowAudio[type].Add(entity);
                return entity;
            }
            else
            {
                Log.LogError($"音频：{name}为空");
                return null;
            }
        }

        ///<summary>暂停/暂停后继续</summary>
        public void Pause()
        {
            IsPause = !IsPause;
            foreach (var item in NowAudio)
            {
                List<VoiceEntity> list = item.Value;
                for (int i = 0; i < list.Count; i++)
                {
                    if (IsPause)
                        list[i].Pause();
                    else
                        list[i].Play();
                }
            }
        }

        ///<summary>停止并释放</summary>
        public void Stop(VoiceEntity audio)
        {
            if (audio != null)
            {
                List<VoiceEntity> audios = NowAudio[audio.Type];
                VoiceEntity entity = audios.Find(a => a == audio);
                if (entity != null)
                {
                    audios.Remove(audio);
                    audio.Stop();
                    audio.Dispose();
                }
            }
            else
            {
                Log.LogError($"音频Stop失败,值为空");
            }
        }

        ///<summary>停止并释放所有的Audio</summary>
        public void StopAll()
        {
            foreach (var item in NowAudio)
            {
                List<VoiceEntity> list = item.Value;
                for (int i = 0; i < list.Count; i++)
                {
                    list[i].Stop();
                    list[i].Dispose();
                }
                list.Clear();
            }
        }

        public override void Dispose()
        {
            base.Dispose();
            StopAll();
        }
    }
}