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

public class BassEffect
{
	public AudioSource source;

	public int range = 128;
	public int sensitivity = 9;
	public float bassDesensitivity = 0.4f;

	public float[] SpectrumData { get; set; }

	public float bassThreshhold = 0.1f;
	
	public Queue<float> bassHistory = new(5);

	List<float> bassData = new();


	// No sensitivity and bass reduction
	public float[] UnprocessedSpectrumData { get; set; }

	// Raw data from GetSpectrumData
	private float[] RawSpectrumData;

	public BassEffect(AudioSource source)
	{
		this.source = source;

		SpectrumData = new float[range];
		RawSpectrumData = new float[4 * range];
	}

	public float[] UpdateSpectrumData()
	{
		source.GetSpectrumData(RawSpectrumData, 0, FFTWindow.Blackman);

		float[] res = new float[range];

		// Smooth the spectrum data using a moving average
		for (int i = 0; i < range; i++)
		{
			float result = Mathf.Lerp(SpectrumData[i], RawSpectrumData[i], 0.1f);
			SpectrumData[i] = result;

			if (i < (range / 14))
			{
				result *= bassDesensitivity;
			}

			res[i] = sensitivity * result;
		}
		IsBassOn();

		return res;
	}

	public float[] GetBass()
	{
		return SpectrumData.Take(3).ToArray();
	}

	public float GetBassStrength()
	{
		float[] bass = GetBass();

		float sum = bass.Sum() * 5f;

		return (float) Math.Pow(sum, 2) / 10f;
	}

	public bool IsBassOn()
	{
		float[] bass = GetBass();

		float level = bass.Sum() / bass.Length;

		bassData.Add(level);
		
		return level > bassThreshhold;
	}

	public void WriteData()
	{
		string res = "";

		foreach (var bass in bassData)
		{
			res += bass + ", ";
		}
		
		System.IO.File.WriteAllText("/home/thastertyn/bass-data.txt", res);
	}
}
