using DeepDrftModels.DTOs;

namespace DeepDrftManager.Services;

/// <summary>The browse dimensions for the /tracks page.</summary>
public enum BrowseMode
{
    Tracks,
    Albums,
    Archive,
    Genres,
}

/// <summary>
/// Holds the /tracks browser's current mode plus the album- and genre-mode datasets. Scoped per
/// circuit. Album and genre lists are fetched lazily on first switch into their mode and cached for
/// the circuit's lifetime; Track mode owns its own paging inside <c>CmsTrackGrid</c> and needs no
/// state here.
/// </summary>
public class CmsTrackBrowserViewModel
{
    private readonly ICmsTrackService _trackService;

    public CmsTrackBrowserViewModel(ICmsTrackService trackService)
    {
        _trackService = trackService;
    }

    public BrowseMode Mode { get; private set; } = BrowseMode.Tracks;

    // Album mode.
    public IReadOnlyList<ReleaseDto> Albums { get; private set; } = Array.Empty<ReleaseDto>();
    public bool AlbumsLoading { get; private set; }

    // Genre mode.
    public IReadOnlyList<GenreSummaryDto> Genres { get; private set; } = Array.Empty<GenreSummaryDto>();
    public bool GenresLoading { get; private set; }
    public string? ExpandedGenre { get; private set; }

    /// <summary>
    /// Switch the active mode, lazily loading the album or genre dataset on first entry. Collapses
    /// any expanded genre row. The grid in Track mode owns its own data, so no fetch happens there.
    /// </summary>
    public async Task SwitchModeAsync(BrowseMode mode)
    {
        Mode = mode;
        ExpandedGenre = null; // collapse on mode switch

        if (mode == BrowseMode.Albums && Albums.Count == 0 && !AlbumsLoading)
        {
            AlbumsLoading = true;
            var result = await _trackService.GetReleasesAsync();
            Albums = result.Success && result.Value is not null
                ? result.Value
                : Array.Empty<ReleaseDto>();
            AlbumsLoading = false;
        }
        else if (mode == BrowseMode.Genres && Genres.Count == 0 && !GenresLoading)
        {
            GenresLoading = true;
            var result = await _trackService.GetGenreSummariesAsync();
            Genres = result.Success && result.Value is not null
                ? result.Value
                : Array.Empty<GenreSummaryDto>();
            GenresLoading = false;
        }
    }

    /// <summary>Toggle the expanded genre row. Selecting the already-expanded genre collapses it.</summary>
    public void SetExpandedGenre(string? genre)
    {
        ExpandedGenre = ExpandedGenre == genre ? null : genre;
    }

    /// <summary>
    /// Drop the cached album and genre datasets so the next <see cref="SwitchModeAsync"/> into
    /// either mode re-fetches from the API. Call after a track or release mutation (edit, delete)
    /// since both datasets are derived from the catalogue and go stale on any such change.
    /// </summary>
    public void Invalidate()
    {
        Albums = Array.Empty<ReleaseDto>();
        Genres = Array.Empty<GenreSummaryDto>();
    }
}
