using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using UnityEngine;
using FMOD;
using FMODUnity;
using EventInstance = FMOD.Studio.EventInstance;

[RequireComponent(typeof(FMODUnity.StudioBankLoader))]
public class AudioManager : MonoBehaviour
{
    [System.Serializable]
    private struct AdjustableAudioBus
    {
        public string BusName;
        public PlayerPrefValue PlayerPref;

        public void Initialise()
        {
            var bus = FMODUnity.RuntimeManager.GetBus( $"bus:/{BusName}" );
            PlayerPref.OnFloatSet.AddListener( (vol) => bus.setVolume(vol) );
            bus.setVolume( PlayerPref.GetFloat( 1.0f ) );
        }
    }
    
    [SerializeField]
    [EventRef]
    private string _musicId;

    [SerializeField]
    private float _trackDeltaPerSecond;

    private const string TRACK_PARAM = "Track";
    
    private float _currentTrack = 1f;
    private int _targetTrack = 1;

    [SerializeField]
    private AdjustableAudioBus _musicBus;
    
    [SerializeField]
    private AdjustableAudioBus _sfxBus;
    
    [SerializeField]
    private AdjustableAudioBus _voBus;
    
    [SerializeField]
    private AdjustableAudioBus _uiBus;

    private static AudioManager _instance;
    
    private EventInstance _musicInstance;

    public static void SetTrack( int track, bool forceLower = false )
    {
        if ( forceLower || track > _instance._targetTrack )
        {
            _instance._targetTrack = track;
        }
    }

    void Update()
    {
        float dt = Time.deltaTime;
        float maxDelta = dt * _trackDeltaPerSecond;
        _currentTrack = Mathf.MoveTowards( _currentTrack, (float) _targetTrack, maxDelta );
        _musicInstance.setParameterByName( TRACK_PARAM, _currentTrack );
    }

    void Awake()
    {
        if ( _instance != null )
        {
            Destroy( gameObject );
            return;
        }

        _instance = this;

        GetComponent<StudioBankLoader>().enabled = true;
        
        _musicInstance = RuntimeManager.CreateInstance( _musicId );
        _musicInstance.start();
        
        _musicBus.Initialise();
        _sfxBus.Initialise();
        _voBus.Initialise();
        _uiBus.Initialise();
    }
}