using System;
using System.Threading;
using System.Threading.Tasks;

namespace SortVisualizer;

public class BeadSort : ISortAlgorithm
{
    public string Name => "Bead Sort";
    public BeadSort() { }

    public async Task Sort(int[] array, Action refresh, int delay, Action<int> playSound, CancellationToken token)
    {
        try
        {
            int n = array.Length;
            if (n == 0) return;

            int max = 0;
            for (int i = 0; i < n; i++)
            {
                token.ThrowIfCancellationRequested();
                if (array[i] > max) max = array[i];
            }

            bool[,] beads = new bool[n, max];
            for (int i = 0; i < n; i++)
            {
                token.ThrowIfCancellationRequested();
                for (int j = 0; j < array[i]; j++)
                    beads[i, j] = true;
            }

            for (int j = 0; j < max; j++)
            {
                token.ThrowIfCancellationRequested();
                int sum = 0;
                for (int i = 0; i < n; i++)
                    if (beads[i, j]) sum++;

                for (int i = 0; i < n; i++)
                    beads[i, j] = i >= n - sum;

                for (int i = 0; i < n; i++)
                {
                    array[i] = 0;
                    for (int k = 0; k < max; k++)
                        if (beads[i, k]) array[i]++;
                    playSound?.Invoke(array[i]);
                }

                refresh?.Invoke();
                await Task.Delay(delay, token);
            }

            for (int i = 0; i < n; i++)
            {
                token.ThrowIfCancellationRequested();
                int count = 0;
                for (int j = 0; j < max; j++)
                    if (beads[i, j]) count++;
                array[i] = count;

                playSound?.Invoke(array[i]);
                refresh?.Invoke();
                await Task.Delay(delay, token);
            }
        }
        catch (TaskCanceledException)
        {
            // Safe cancellation, just exit
        }
    }
}
