using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Audio;
using UnityEngine.Pool;
using UnityEngine.EventSystems;
using UnityEngine.UI;

public enum SoundType
{
    None,
    UIClick,
    Click,
    Notification,
    GameOver
}

namespace Sound
{
    [System.Serializable]
    public class SoundData
    {
        public SoundType type;
        public List<AudioClip> clips = new List<AudioClip>();
        [Range(0f, 1f)]
        public float volume = 1f;

        public AudioClip GetClip()
        {
            clips.Shuffle();
            return clips[0];
        }
    }

    public class SoundController : MonoBehaviour
    {
        public static SoundController Instance;

        [SerializeField] private List<SoundData> _sounds = new List<SoundData>();

        [SerializeField] private GameObject _soundPrefab;

        [SerializeField] private AudioMixer _mixer;
        [SerializeField] private AudioSource _musicSource;
        [SerializeField] private List<AudioClip> musicClips = new List<AudioClip>();

        ObjectPool<SoundEffect> _pool;

        private void Awake()
        {
            if (Instance != null && Instance != this)
            {
                Destroy(gameObject);
                return;
            }

            _pool = new ObjectPool<SoundEffect>(CreatePoolItem, GetPoolItem, ReleasePoolItem, null, true, _sounds.Count * 2);

            DontDestroyOnLoad(gameObject);

            Instance = this;
        }

        private void Start()
        {
            LoadAudioSettings();

            PlayMusic();
        }

        private void LateUpdate()
        {
            if (Input.GetMouseButtonDown(0))
            {
                Play(SoundType.Click);
            }
        }

        private void LoadAudioSettings()
        {
            _mixer.SetFloat("musicVolume", PlayerPrefs.GetInt("musicEnabled", 1) == 1 ? 0f : -80f);
            _mixer.SetFloat("soundVolume", PlayerPrefs.GetInt("soundEnabled", 1) == 1 ? 0f : -80f);
        }

        public void Play(SoundType type)
        {
            var currentSound = _sounds.Find(x => x.type == type);
            var go = _pool.Get();
            go.Play(currentSound.GetClip(), currentSound.volume);
        }

        public void PlayMusic()
        {
            musicClips.Shuffle();

            _musicSource.clip = musicClips[0];
            _musicSource.Play();
        }

        public void StopGameMusic()
        {
            _musicSource.Stop();
        }

        #region Pool Funcs

        private SoundEffect CreatePoolItem()
        {
            var go = Instantiate(_soundPrefab, transform);
            go.SetActive(false);

            var soundEffect = go.GetComponent<SoundEffect>();
            soundEffect.SetDestroyCallback(_pool.Release);
            return soundEffect;
        }

        private void GetPoolItem(SoundEffect item)
        {
            item.gameObject.SetActive(true);
        }

        private void ReleasePoolItem(SoundEffect item)
        {
            item.gameObject.SetActive(false);
        }

        #endregion
    }
}