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

namespace SortVisualizer;

public class StoogeSort : ISortAlgorithm
{
    public string Name => "Stooge Sort";
    public StoogeSort() { }

    public async Task Sort(int[] array, Action refresh, int delay, Action<int> playSound, CancellationToken token)
    {
        try
        {
            await StoogeSortRecursive(array, 0, array.Length - 1, refresh, delay, playSound, token);
        }
        catch (TaskCanceledException)
        {
            // Sorting was cancelled – handle gracefully
            // Optionally, reset UI or log here
        }
        catch (Exception ex)
        {
            // Unexpected exception – optional logging
            Console.WriteLine($"StoogeSort error: {ex}");
        }
    }

    private async Task StoogeSortRecursive(int[] array, int i, int j, Action refresh, int delay, Action<int> playSound, CancellationToken token)
    {
        if (token.IsCancellationRequested) return; // graceful early exit

        // Swap if first element is greater than last
        if (array[i] > array[j])
        {
            int temp = array[i];
            array[i] = array[j];
            array[j] = temp;

            playSound?.Invoke(array[i]);
            playSound?.Invoke(array[j]);
            refresh?.Invoke();

            try { await Task.Delay(delay, token); }
            catch (TaskCanceledException) { return; } // exit silently if cancelled
        }

        if (j - i + 1 > 2)
        {
            int t = (j - i + 1) / 3;

            await StoogeSortRecursive(array, i, j - t, refresh, delay, playSound, token);
            await StoogeSortRecursive(array, i + t, j, refresh, delay, playSound, token);
            await StoogeSortRecursive(array, i, j - t, refresh, delay, playSound, token);
        }
    }
}
