#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 computers /// public partial class ComputersListViewModel : ObservableObject { private readonly ComputersService _computersService; private readonly IComputersListFilterContext _filterContext; private readonly IStringLocalizer _localizer; private readonly ILogger _logger; private readonly INavigator _navigator; [ObservableProperty] private ObservableCollection _computersList = []; [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 ComputersListViewModel(ComputersService computersService, IStringLocalizer localizer, ILogger logger, INavigator navigator, IComputersListFilterContext filterContext) { _computersService = computersService; _localizer = localizer; _logger = logger; _navigator = navigator; _filterContext = filterContext; LoadData = new AsyncRelayCommand(LoadDataAsync); GoBackCommand = new AsyncRelayCommand(GoBackAsync); NavigateToComputerCommand = new AsyncRelayCommand(NavigateToComputerAsync); } public IAsyncRelayCommand LoadData { get; } public ICommand GoBackCommand { get; } public IAsyncRelayCommand NavigateToComputerCommand { get; } /// /// Gets or sets the filter type /// public ComputerListFilterType 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 computers based on the current filter /// private async Task LoadDataAsync() { try { IsLoading = true; ErrorMessage = string.Empty; HasError = false; IsDataLoaded = false; ComputersList.Clear(); _logger.LogInformation("LoadDataAsync called. FilterType={FilterType}, FilterValue={FilterValue}", FilterType, FilterValue); // Update title and filter description based on filter type UpdateFilterDescription(); // Load computers from the API based on the current filter await LoadComputersFromApiAsync(); _logger.LogInformation("LoadComputersFromApiAsync completed. ComputersList.Count={Count}", ComputersList.Count); if(ComputersList.Count == 0) { ErrorMessage = _localizer["No computers found for this filter"].Value; HasError = true; _logger.LogWarning("No computers found for filter: {FilterType} {FilterValue}", FilterType, FilterValue); } else IsDataLoaded = true; } catch(Exception ex) { _logger.LogError(ex, "Error loading computers: {Exception}", ex.Message); ErrorMessage = _localizer["Failed to load computers. 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 ComputerListFilterType.All: PageTitle = _localizer["All Computers"]; FilterDescription = _localizer["Browsing all computers in the database"]; break; case ComputerListFilterType.Letter: if(!string.IsNullOrEmpty(FilterValue) && FilterValue.Length == 1) { PageTitle = $"{_localizer["Computers Starting with"]} {FilterValue}"; FilterDescription = $"{_localizer["Showing computers that start with"]} {FilterValue}"; } break; case ComputerListFilterType.Year: if(!string.IsNullOrEmpty(FilterValue) && int.TryParse(FilterValue, out int year)) { PageTitle = $"{_localizer["Computers from"]} {year}"; FilterDescription = $"{_localizer["Showing computers released in"]} {year}"; } break; } } /// /// Loads computers from the API based on the current filter /// private async Task LoadComputersFromApiAsync() { try { List computers = FilterType switch { ComputerListFilterType.Letter when FilterValue.Length == 1 => await _computersService.GetComputersByLetterAsync(FilterValue[0]), ComputerListFilterType.Year when int.TryParse(FilterValue, out int year) => await _computersService.GetComputersByYearAsync(year), _ => await _computersService.GetAllComputersAsync() }; // Add computers to the list sorted by name foreach(MachineDto computer in computers.OrderBy(c => c.Name)) { int year = computer.Introduced?.Year ?? 0; int id = computer.Id ?? 0; _logger.LogInformation("Computer: {Name}, Introduced: {Introduced}, Year: {Year}, Company: {Company}, ID: {Id}", computer.Name, computer.Introduced, year, computer.Company, id); ComputersList.Add(new ComputerListItem { Id = id, Name = computer.Name ?? string.Empty, Year = year, Manufacturer = computer.Company ?? string.Empty }); } } catch(Exception ex) { _logger.LogError(ex, "Error loading computers from API"); } } /// /// Navigates back to the computers main view /// private async Task GoBackAsync() { await _navigator.NavigateViewModelAsync(this); } /// /// Navigates to the computer detail view /// private async Task NavigateToComputerAsync(ComputerListItem? computer) { if(computer is null) return; _logger.LogInformation("Navigating to computer detail: {ComputerName} (ID: {ComputerId})", computer.Name, computer.Id); var navParam = new MachineViewNavigationParameter { MachineId = computer.Id, NavigationSource = this }; await _navigator.NavigateViewModelAsync(this, data: navParam); } } /// /// Data model for a computer in the list /// public class ComputerListItem { public int Id { get; set; } public string Name { get; set; } = string.Empty; public int Year { get; set; } public string Manufacturer { get; set; } = string.Empty; }