#nullable enable using System; using System.Collections.Generic; using System.Collections.ObjectModel; using System.Linq; using System.Threading.Tasks; using System.Windows.Input; using Marechai.App.Presentation.Models; using Marechai.App.Services; using Uno.Extensions.Navigation; namespace Marechai.App.Presentation.ViewModels; /// /// ViewModel for displaying a filtered list of consoles /// public partial class ConsolesListViewModel : ObservableObject { private readonly ConsolesService _consolesService; private readonly IConsolesListFilterContext _filterContext; private readonly IStringLocalizer _localizer; private readonly ILogger _logger; private readonly INavigator _navigator; [ObservableProperty] private ObservableCollection _consolesList = []; [ObservableProperty] private string _errorMessage = string.Empty; [ObservableProperty] private string _filterDescription = string.Empty; [ObservableProperty] private bool _hasError; [ObservableProperty] private bool _isDataLoaded; [ObservableProperty] private bool _isLoading; [ObservableProperty] private string _pageTitle = string.Empty; public ConsolesListViewModel(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); NavigateToConsoleCommand = new AsyncRelayCommand(NavigateToConsoleAsync); } public IAsyncRelayCommand LoadData { get; } public ICommand GoBackCommand { get; } public IAsyncRelayCommand NavigateToConsoleCommand { get; } /// /// Gets or sets the filter type /// public ConsoleListFilterType FilterType { get => _filterContext.FilterType; set => _filterContext.FilterType = value; } /// /// Gets or sets the filter value /// public string FilterValue { get => _filterContext.FilterValue; set => _filterContext.FilterValue = value; } /// /// Loads consoles based on the current filter /// private async Task LoadDataAsync() { try { IsLoading = true; ErrorMessage = string.Empty; HasError = false; IsDataLoaded = false; ConsolesList.Clear(); _logger.LogInformation("LoadDataAsync called. FilterType={FilterType}, FilterValue={FilterValue}", FilterType, FilterValue); // Update title and filter description based on filter type UpdateFilterDescription(); // Load consoles from the API based on the current filter await LoadConsolesFromApiAsync(); _logger.LogInformation("LoadConsolesFromApiAsync completed. ConsolesList.Count={Count}", ConsolesList.Count); if(ConsolesList.Count == 0) { ErrorMessage = _localizer["No consoles found for this filter"].Value; HasError = true; _logger.LogWarning("No consoles found for filter: {FilterType} {FilterValue}", FilterType, FilterValue); } else IsDataLoaded = true; } catch(Exception ex) { _logger.LogError(ex, "Error loading consoles: {Exception}", ex.Message); ErrorMessage = _localizer["Failed to load consoles. Please try again later."].Value; HasError = true; } finally { IsLoading = false; } } /// /// Updates the title and filter description based on the current filter /// private void UpdateFilterDescription() { switch(FilterType) { case ConsoleListFilterType.All: PageTitle = _localizer["All Consoles"]; FilterDescription = _localizer["Browsing all consoles in the database"]; break; case ConsoleListFilterType.Letter: if(!string.IsNullOrEmpty(FilterValue) && FilterValue.Length == 1) { PageTitle = $"{_localizer["Consoles Starting with"]} {FilterValue}"; FilterDescription = $"{_localizer["Showing consoles that start with"]} {FilterValue}"; } break; case ConsoleListFilterType.Year: if(!string.IsNullOrEmpty(FilterValue) && int.TryParse(FilterValue, out int year)) { PageTitle = $"{_localizer["Consoles from"]} {year}"; FilterDescription = $"{_localizer["Showing consoles released in"]} {year}"; } break; } } /// /// Loads consoles from the API based on the current filter /// private async Task LoadConsolesFromApiAsync() { try { List consoles = FilterType switch { ConsoleListFilterType.Letter when FilterValue.Length == 1 => await _consolesService.GetConsolesByLetterAsync(FilterValue[0]), ConsoleListFilterType.Year when int.TryParse(FilterValue, out int year) => await _consolesService.GetConsolesByYearAsync(year), _ => await _consolesService.GetAllConsolesAsync() }; // Add consoles to the list sorted by name foreach(MachineDto console in consoles.OrderBy(c => c.Name)) { int year = console.Introduced?.Year ?? 0; int id = console.Id ?? 0; _logger.LogInformation("Console: {Name}, Introduced: {Introduced}, Year: {Year}, Company: {Company}, ID: {Id}", console.Name, console.Introduced, year, console.Company, id); ConsolesList.Add(new ConsoleListItem { Id = id, Name = console.Name ?? string.Empty, Year = year, Manufacturer = console.Company ?? string.Empty }); } } catch(Exception ex) { _logger.LogError(ex, "Error loading consoles from API"); } } /// /// Navigates back to the consoles main view /// private async Task GoBackAsync() { await _navigator.NavigateViewModelAsync(this); } /// /// Navigates to the console detail view /// private async Task NavigateToConsoleAsync(ConsoleListItem? console) { if(console is null) return; _logger.LogInformation("Navigating to console detail: {ConsoleName} (ID: {ConsoleId})", console.Name, console.Id); var navParam = new MachineViewNavigationParameter { MachineId = console.Id, NavigationSource = this }; await _navigator.NavigateViewModelAsync(this, data: navParam); } } /// /// Data model for a console in the list /// public class ConsoleListItem { public int Id { get; set; } public string Name { get; set; } = string.Empty; public int Year { get; set; } public string Manufacturer { get; set; } = string.Empty; }