using System.Collections;
using UnityEngine;

public class SoundManager : MonoBehaviour
{
    public static SoundManager Instance { get; private set; }

    [Header("Sound Settings")] 
    [Range(0f,1f)] public float masterVolume;
    [Range(0f,1f)] public float musicVolume;
    [Range(0f,1f)] public float sfxVolume;
    [SerializeField] private float fadeTime;

    [Header("Music")]
    [SerializeField] private AudioSource baseMusic;
    [SerializeField] private AudioSource[] dimensionMusicLayer;

    [Header("Debug Values")]
    [SerializeField, ReadOnly] private int dimensionMusicID;
    
    private void Awake()
    {
        if (Instance != null && Instance != this)
        {
            Destroy(gameObject);
        }
        else
        {
            Instance = this;
            baseMusic.volume = masterVolume * musicVolume;
            foreach (var layer in dimensionMusicLayer)
            {
                layer.volume = 0;
            }

            dimensionMusicID = -1;
            DontDestroyOnLoad(gameObject);
        }
    }

    public void SwitchMusicLayer(int dimensionID)
    {
        if (dimensionMusicID != -1) StartCoroutine(FadeOut(dimensionMusicID));
        if (dimensionID != -1) StartCoroutine(FadeIn(dimensionID));
        dimensionMusicID = dimensionID;
    }

    public void PlaySfx(AudioSource audioSource)
    {
        audioSource.volume = masterVolume * sfxVolume;
        audioSource.Play();
    }

    public void PlaySfx(AudioSource audioSource, AudioClip audioClip)
    {
        audioSource.clip = audioClip;
        audioSource.volume = masterVolume * sfxVolume;
        audioSource.Play();
    }

    private IEnumerator FadeIn(int dimensionID)
    {
        float time = 0;
        while (time < fadeTime)
        {
            time += 0.05f;
            dimensionMusicLayer[dimensionID].volume = Mathf.Lerp(0, masterVolume * musicVolume, time / fadeTime);
            yield return new WaitForSeconds(0.05f);
        }
    }

    private IEnumerator FadeOut(int dimensionID)
    {
        float time = 0;
        while (time < fadeTime)
        {
            time += 0.05f;
            dimensionMusicLayer[dimensionID].volume = Mathf.Lerp(masterVolume * musicVolume, 0, time / fadeTime);
            yield return new WaitForSeconds(0.05f);
        }
    }

    public void OnMasterVolumeChanged(float value)
    {
        masterVolume = value;
        SetAllSoundsVolume();
    }

    public void OnMusicVolumeChanged(float value)
    {
        musicVolume = value;
        SetAllSoundsVolume();
    }

    public void OnSfxVolumeChanged(float value)
    {
        sfxVolume = value;
        SetAllSoundsVolume();
    }

    private void SetAllSoundsVolume()
    {
        var trueMusicVolume = masterVolume * musicVolume;
        baseMusic.volume = trueMusicVolume;
        if (dimensionMusicID != -1) dimensionMusicLayer[dimensionMusicID].volume = trueMusicVolume;
    }
}
