using Microsoft.Xna.Framework.Audio;
using System;

namespace AlienAttack.MonoGame.Audio;

public sealed class VariantSoundPool
{
    private readonly SoundPool[] _variantPools;
    private readonly Random _rng;
    private int _lastIndex = -1;

    public VariantSoundPool(SoundEffect[] variants, int voicesPerVariant, Random rng)
    {
        if (variants == null || variants.Length == 0)
            throw new ArgumentException("At least one variant is required.", nameof(variants));

        ArgumentOutOfRangeException.ThrowIfLessThan(voicesPerVariant, 1);

        _rng = rng ?? throw new ArgumentNullException(nameof(rng));

        _variantPools = new SoundPool[variants.Length];

        for (int i = 0; i < variants.Length; i++)
            _variantPools[i] = new SoundPool(variants[i], voicesPerVariant);
    }

    public void Play(float volume = 1f, float pitch = 0f, float pan = 0f, bool avoidImmediateRepeat = true)
    {
        int idx = PickVariantIndex(avoidImmediateRepeat);
        _variantPools[idx].Play(volume, pitch, pan);
    }

    private int PickVariantIndex(bool avoidImmediateRepeat)
    {
        if (_variantPools.Length == 1)
            return 0;

        int idx = _rng.Next(_variantPools.Length);
        if (!avoidImmediateRepeat) { _lastIndex = idx; return idx; }

        // Avoid playing the exact same sample twice in a row (nice polish)
        if (idx == _lastIndex)
            idx = (idx + 1 + _rng.Next(_variantPools.Length - 1)) % _variantPools.Length;

        _lastIndex = idx;
        return idx;
    }
}