using UnityEngine;

public class AudioManager : MonoBehaviour
{
    public static AudioManager Instance;

    private AudioSource musicSource;
    private AudioSource sfxSource;

    private void Awake()
    {
        if (Instance != null && Instance != this)
        {
            Destroy(gameObject);
            return;
        }

        Instance = this;
        DontDestroyOnLoad(gameObject);

        musicSource = gameObject.AddComponent<AudioSource>();
        musicSource.loop = true;
        musicSource.volume = 0.12f;

        sfxSource = gameObject.AddComponent<AudioSource>();
        sfxSource.volume = 0.7f;

        PlayBackgroundMusic();
    }

    public void PlayShoot()
    {
        PlayOneShot(CreateToneClip(900f, 0.06f, 0.25f, 0.01f));
    }

    public void PlayExplosion(Vector3 position)
    {
        PlayOneShot(CreateNoiseClip(0.08f, 0.25f, 0.2f));
    }

    public void PlayHit()
    {
        PlayOneShot(CreateToneClip(220f, 0.16f, 0.2f, 0.02f));
    }

    public void PlayGameOver()
    {
        PlayOneShot(CreateToneClip(120f, 0.4f, 0.2f, 0.08f));
    }

    private void PlayBackgroundMusic()
    {
        musicSource.clip = CreateMusicClip();
        musicSource.Play();
    }

    private void PlayOneShot(AudioClip clip)
    {
        if (clip == null) return;
        sfxSource.PlayOneShot(clip);
    }

    private AudioClip CreateToneClip(float frequency, float duration, float volume, float attack)
    {
        int sampleRate = 44100;
        int sampleCount = Mathf.CeilToInt(sampleRate * duration);
        var data = new float[sampleCount];

        for (int i = 0; i < sampleCount; i++)
        {
            float t = i / (float)sampleRate;
            float envelope = Mathf.Clamp01((1f - (t / duration)) * 2f);
            if (t < attack)
            {
                envelope = Mathf.Lerp(0f, envelope, t / attack);
            }

            data[i] = Mathf.Sin(2f * Mathf.PI * frequency * t) * volume * envelope;
        }

        var clip = AudioClip.Create("tone", sampleCount, 1, sampleRate, false);
        clip.SetData(data, 0);
        return clip;
    }

    private AudioClip CreateNoiseClip(float duration, float volume, float lowPass)
    {
        int sampleRate = 44100;
        int sampleCount = Mathf.CeilToInt(sampleRate * duration);
        var data = new float[sampleCount];

        for (int i = 0; i < sampleCount; i++)
        {
            float t = i / (float)sampleRate;
            float baseNoise = Random.value * 2f - 1f;
            float freq = Mathf.Lerp(1500f, 300f, t / duration);
            data[i] = Mathf.Sin(2f * Mathf.PI * freq * t) * volume * 0.4f + baseNoise * volume * 0.6f;
        }

        var clip = AudioClip.Create("noise", sampleCount, 1, sampleRate, false);
        clip.SetData(data, 0);
        return clip;
    }

    private AudioClip CreateMusicClip()
    {
        int sampleRate = 44100;
        int sampleCount = sampleRate * 8;
        var data = new float[sampleCount];

        for (int i = 0; i < sampleCount; i++)
        {
            float t = i / (float)sampleRate;
            float toneA = Mathf.Sin(2f * Mathf.PI * 220f * t) * 0.08f;
            float toneB = Mathf.Sin(2f * Mathf.PI * 330f * t) * 0.05f;
            float envelope = Mathf.Sin(t / 2f) * 0.5f + 0.5f;
            data[i] = (toneA + toneB) * envelope;
        }

        var clip = AudioClip.Create("music", sampleCount, 1, sampleRate, false);
        clip.SetData(data, 0);
        return clip;
    }
}
