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

public class CampfireSfx : MonoBehaviour {
    public GameState GameState;
    public AudioSource ActiveBurnSource;
    public AudioSource AmbientSource;
    public AudioSource IntenseAmbientSource;
    public Campfire Campfire;
    public float ActiveBurn = 0f;

    [Header("Clips")]
    public AudioClip EndClip;
    public AudioClip[] AmbientClips;
    public AudioClip[] IntenseAmbientClips;
    public AudioClip[] CrackleClips;

    private void Update() {
        ActiveBurn = Mathf.Max(0, ActiveBurn - Time.deltaTime);

        if (Campfire.TimeToEnd <= 0) {
            IntenseAmbientSource.volume = Mathf.Lerp(IntenseAmbientSource.volume, 0, 10f * Time.deltaTime);
            ActiveBurnSource.volume = Mathf.Lerp(ActiveBurnSource.volume, 0, 10f * Time.deltaTime);
            AmbientSource.volume = Mathf.Lerp(AmbientSource.volume, 0, 10f * Time.deltaTime);
            return;
        } else {
            IntenseAmbientSource.volume = Mathf.Max(ActiveBurn, Mathf.Clamp((Campfire.Fuel - Campfire.GoodFuelAmount) / Campfire.GoodFuelAmount, 0, 1) * 0.2f);
            ActiveBurnSource.volume = Mathf.Pow(ActiveBurn, 0.3f);
            AmbientSource.volume = Mathf.Lerp(AmbientSource.volume, 1, 10f * Time.deltaTime);
        }

        bool StartEndClip = Campfire.TimeToEnd <= EndClip.length && AmbientSource.clip != EndClip;
        bool StopEndClip = AmbientSource.clip == EndClip && (Campfire.TimeToEnd > EndClip.length || GameState.Current == State.Paused);
        if (StartEndClip) {
            AmbientSource.clip = EndClip;
            AmbientSource.time = Mathf.Clamp(EndClip.length - Campfire.TimeToEnd, 0, EndClip.length - 0.01f);
            AmbientSource.Play();
        } else if (StopEndClip || NeedsRefresh(AmbientSource)) {
            Refresh(AmbientSource, AmbientClips);
        }

        if (NeedsRefresh(IntenseAmbientSource)) {
            Refresh(IntenseAmbientSource, IntenseAmbientClips);
        }

        if (ActiveBurn > 0 && NeedsRefresh(ActiveBurnSource)) {
            Refresh(ActiveBurnSource, CrackleClips);
        }
    }

    private void Refresh(AudioSource source, AudioClip[] clips) {
        source.clip = RandomClip(clips);
        if (source.clip != null) {
            source.time = 0f;
            source.Play();
        }
    }

    private bool NeedsRefresh(AudioSource source) {
        return !source.isPlaying || source.clip == null || (source.clip.length - source.time) <= Time.deltaTime;
    }

    private AudioClip RandomClip(AudioClip[] clips) {
        if (clips.Length > 0) {
            return clips[Random.Range(0, clips.Length)];
        } else {
            return null;
        }
    }
}
