using System; using System.Collections.ObjectModel; using System.Threading.Tasks; using System.Windows.Input; using Marechai.App.Services; using Uno.Extensions.Navigation; namespace Marechai.App.Presentation.ViewModels; public partial class ConsolesViewModel : ObservableObject { private readonly ConsolesService _consolesService; private readonly IConsolesListFilterContext _filterContext; private readonly IStringLocalizer _localizer; private readonly ILogger _logger; private readonly INavigator _navigator; [ObservableProperty] private int _consoleCount; [ObservableProperty] private string _consoleCountText = string.Empty; [ObservableProperty] private string _errorMessage = string.Empty; [ObservableProperty] private bool _hasError; [ObservableProperty] private bool _isDataLoaded; [ObservableProperty] private bool _isLoading; [ObservableProperty] private ObservableCollection _lettersList = []; [ObservableProperty] private int _maximumYear; [ObservableProperty] private int _minimumYear; [ObservableProperty] private string _yearsGridTitle = string.Empty; [ObservableProperty] private ObservableCollection _yearsList = []; public ConsolesViewModel(ConsolesService consolesService, IStringLocalizer localizer, ILogger logger, INavigator navigator, IConsolesListFilterContext filterContext) { _consolesService = consolesService; _localizer = localizer; _logger = logger; _navigator = navigator; _filterContext = filterContext; LoadData = new AsyncRelayCommand(LoadDataAsync); GoBackCommand = new AsyncRelayCommand(GoBackAsync); NavigateByLetterCommand = new AsyncRelayCommand(NavigateByLetterAsync); NavigateByYearCommand = new AsyncRelayCommand(NavigateByYearAsync); NavigateAllConsolesCommand = new AsyncRelayCommand(NavigateAllConsolesAsync); InitializeLetters(); } public IAsyncRelayCommand LoadData { get; } public ICommand GoBackCommand { get; } public IAsyncRelayCommand NavigateByLetterCommand { get; } public IAsyncRelayCommand NavigateByYearCommand { get; } public IAsyncRelayCommand NavigateAllConsolesCommand { get; } public string Title { get; } = "Consoles"; /// /// Initializes the alphabet list (A-Z) /// private void InitializeLetters() { LettersList.Clear(); for(var c = 'A'; c <= 'Z'; c++) LettersList.Add(c); } /// /// Loads consoles count, minimum and maximum years from the API /// private async Task LoadDataAsync() { try { IsLoading = true; ErrorMessage = string.Empty; HasError = false; IsDataLoaded = false; YearsList.Clear(); // Load all data in parallel for better performance Task countTask = _consolesService.GetConsolesCountAsync(); Task minYearTask = _consolesService.GetMinimumYearAsync(); Task maxYearTask = _consolesService.GetMaximumYearAsync(); await Task.WhenAll(countTask, minYearTask, maxYearTask); ConsoleCount = countTask.Result; MinimumYear = minYearTask.Result; MaximumYear = maxYearTask.Result; // Update display text ConsoleCountText = _localizer["Consoles in the database"]; // Generate years list if(MinimumYear > 0 && MaximumYear > 0) { for(int year = MinimumYear; year <= MaximumYear; year++) YearsList.Add(year); YearsGridTitle = $"Browse by Year ({MinimumYear} - {MaximumYear})"; } if(ConsoleCount == 0) { ErrorMessage = _localizer["No consoles found"].Value; HasError = true; } else IsDataLoaded = true; } catch(Exception ex) { _logger.LogError("Error loading consoles data: {Exception}", ex.Message); ErrorMessage = _localizer["Failed to load consoles data. Please try again later."].Value; HasError = true; } finally { IsLoading = false; } } /// /// Handles back navigation /// private async Task GoBackAsync() { await _navigator.NavigateViewModelAsync(this); } /// /// Navigates to consoles filtered by letter /// private async Task NavigateByLetterAsync(char letter) { try { _logger.LogInformation("Navigating to consoles by letter: {Letter}", letter); _filterContext.FilterType = ConsoleListFilterType.Letter; _filterContext.FilterValue = letter.ToString(); await _navigator.NavigateRouteAsync(this, "list-consoles"); } catch(Exception ex) { _logger.LogError("Error navigating to letter consoles: {Exception}", ex.Message); ErrorMessage = _localizer["Failed to navigate. Please try again."].Value; HasError = true; } } /// /// Navigates to consoles filtered by year /// private async Task NavigateByYearAsync(int year) { try { _logger.LogInformation("Navigating to consoles by year: {Year}", year); _filterContext.FilterType = ConsoleListFilterType.Year; _filterContext.FilterValue = year.ToString(); await _navigator.NavigateRouteAsync(this, "list-consoles"); } catch(Exception ex) { _logger.LogError("Error navigating to year consoles: {Exception}", ex.Message); ErrorMessage = _localizer["Failed to navigate. Please try again."].Value; HasError = true; } } /// /// Navigates to all consoles view /// private async Task NavigateAllConsolesAsync() { try { _logger.LogInformation("Navigating to all consoles"); _filterContext.FilterType = ConsoleListFilterType.All; _filterContext.FilterValue = string.Empty; await _navigator.NavigateRouteAsync(this, "list-consoles"); } catch(Exception ex) { _logger.LogError("Error navigating to all consoles: {Exception}", ex.Message); ErrorMessage = _localizer["Failed to navigate. Please try again."].Value; HasError = true; } } }