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

public class AudioManager : S_MonoSingleton<AudioManager>
{
    [SerializeField] AudioListener mAudioListener;
    [SerializeField] AudioSource mMusicPlayer;
    [SerializeField] AudioSource mSoundPlayer;

    public SoundPack[] soundPacks;

    private Dictionary<SoundType, List<AudioClip>> mSoundDic = new Dictionary<SoundType, List<AudioClip>>();
    private bool mIsSoundOn = true;

    protected override void Initialize()
    {
        for (int i = 0; i < soundPacks.Length; i++)
        {
            SoundPack tPack = soundPacks[i];
            if (!mSoundDic.ContainsKey(tPack.myType))
            {
                mSoundDic[tPack.myType] = new List<AudioClip>();
            }

            mSoundDic[tPack.myType] = tPack.myClips;
        }

        CheckAudioListner();
        CheckMusicPlayer();
        CheckSoundPlayer();
    }

    //private void Update()
    //{
    //    if (AudioListener.pause && mIsSoundOn)
    //    {
    //        AudioListener.pause = false;
    //    }
    //    else if (!AudioListener.pause && !mIsSoundOn)
    //    {
    //        AudioListener.pause = true;
    //    }
    //}

    public void SetSoundOn(bool pIsOn)
    {
        mIsSoundOn = pIsOn;
        AudioListener.pause = !pIsOn;
    }

    public void PlayBGMusic(SoundType pType, float pVolumeScale = 1)
    {
        if (!mIsSoundOn)
            return;

        CheckMusicPlayer();

        AudioClip tClip = GetClip(pType);
        if (tClip == null)
            return;

        mMusicPlayer.clip = tClip;
        mMusicPlayer.loop = true;
        mMusicPlayer.volume *= pVolumeScale;
        mMusicPlayer.Play();
    }

    public void StopBGMusic()
    {
        CheckMusicPlayer();

        mMusicPlayer.Stop();
        mMusicPlayer.clip = null;
    }

    public void PlaySound(SoundType pType, float pVolumeScale = 1)
    {
        if (!mIsSoundOn)
            return;

        CheckSoundPlayer();

        AudioClip tClip = GetClip(pType);
        if (tClip == null)
            return;

        mSoundPlayer.PlayOneShot(tClip, pVolumeScale);
    }

    public AudioSource PlaySoundLoop(SoundType pType, float pVolumeScale = 1)
    {
        if (!mIsSoundOn)
            return null;

        AudioClip tClip = GetClip(pType);
        if (tClip == null)
            return null;

        AudioSource tLoopAudio = gameObject.AddComponent<AudioSource>();
        tLoopAudio.clip = tClip;
        tLoopAudio.loop = true;
        tLoopAudio.volume *= pVolumeScale;
        tLoopAudio.Play();

        return tLoopAudio;
    }

    public void StopSoundLoop(AudioSource pAudioSrc)
    {
        if (pAudioSrc == null)
            return;

        pAudioSrc.Stop();
        Destroy(pAudioSrc);
    }

    public void PlaySound3D(AudioSource pAudioSrc, SoundType pType)
    {
        if (!mIsSoundOn)
            return;

        AudioClip tClip = GetClip(pType);
        if (tClip == null)
            return;

        pAudioSrc.PlayOneShot(tClip);
    }

    private AudioClip GetClip(SoundType pType)
    {
        if (!mSoundDic.ContainsKey(pType) || mSoundDic[pType].Count == 0)
            return null;

        List<AudioClip> tClips = mSoundDic[pType];
        int tRandomPlayIndex = UnityEngine.Random.Range(0, tClips.Count);

        return tClips[tRandomPlayIndex];
    }

    private void CheckAudioListner()
    {
        if (mAudioListener == null)
            mAudioListener = gameObject.AddComponent<AudioListener>();
    }

    private void CheckMusicPlayer()
    {
        if (mMusicPlayer == null)
            mMusicPlayer = gameObject.AddComponent<AudioSource>();
    }

    private void CheckSoundPlayer()
    {
        if (mSoundPlayer == null)
            mSoundPlayer = gameObject.AddComponent<AudioSource>();
    }
}

[Serializable]
public class SoundPack
{
    public SoundType myType;
    public List<AudioClip> myClips;
}

public enum SoundType
{
    None = -1,

    Kick_Normal,
    Kick_Door,
    Enemy_Die,

    Crumble_Wood,
    Crumble_Pot,
    Crumble_Wall,

    Fall_Water,
    Bomb_Explode
}