using RobotNet10.MapEditor.Shared.DTOs.Station; using RobotNet10.MapEditor.Services.API; namespace RobotNet10.MapEditor.Services.State; /// /// State management for Station Manager /// public class StationManagerState { private readonly MapManagerApiService _apiService; // Context public Guid? CurrentLayoutLevelId { get; private set; } // Data public List Stations { get; private set; } = new(); public StationDto? SelectedStation { get; private set; } // Filters & Search public string? SearchQuery { get; set; } // UI State public bool IsLoading { get; private set; } public bool IsSaving { get; private set; } public string? ErrorMessage { get; private set; } // Events public event Action? OnStateChanged; public StationManagerState(MapManagerApiService apiService) { _apiService = apiService; } // ========================================== // PUBLIC METHODS // ========================================== /// /// Initialize or switch to a different layout level /// public async Task InitializeAsync(Guid layoutLevelId) { CurrentLayoutLevelId = layoutLevelId; await LoadStationsAsync(); } /// /// Load all stations for the current layout level /// public async Task LoadStationsAsync() { if (!CurrentLayoutLevelId.HasValue) { ErrorMessage = "No layout level selected"; NotifyStateChanged(); return; } IsLoading = true; ErrorMessage = null; NotifyStateChanged(); try { Stations = await _apiService.GetStationsByLevelAsync(CurrentLayoutLevelId.Value); NotifyStateChanged(); } catch (Exception ex) { ErrorMessage = ex.Message; Stations = new(); NotifyStateChanged(); } finally { IsLoading = false; NotifyStateChanged(); } } /// /// Search stations by StationId or StationName /// public void Search(string? query) { SearchQuery = query; NotifyStateChanged(); } /// /// Select a station for viewing/editing /// public async Task SelectStationAsync(Guid? stationId) { if (!stationId.HasValue) { SelectedStation = null; NotifyStateChanged(); return; } // Try to find in local list first SelectedStation = Stations.FirstOrDefault(s => s.Id == stationId.Value); // If not found or need fresh data, fetch from API if (SelectedStation == null) { try { SelectedStation = await _apiService.GetStationAsync(stationId.Value); } catch { SelectedStation = null; } } NotifyStateChanged(); } /// /// Clear selected station /// public void ClearSelection() { SelectedStation = null; NotifyStateChanged(); } /// /// Create a new station /// public async Task CreateStationAsync(RobotNet10.MapEditor.Shared.DTOs.Requests.CreateStationRequest request) { IsSaving = true; ErrorMessage = null; NotifyStateChanged(); try { var created = await _apiService.CreateStationAsync(request); await LoadStationsAsync(); await SelectStationAsync(created.Id); return created; } catch (Exception ex) { ErrorMessage = ex.Message; NotifyStateChanged(); throw; } finally { IsSaving = false; NotifyStateChanged(); } } /// /// Update an existing station /// public async Task UpdateStationAsync(Guid stationId, RobotNet10.MapEditor.Shared.DTOs.Requests.UpdateStationRequest request) { IsSaving = true; ErrorMessage = null; NotifyStateChanged(); try { var updated = await _apiService.UpdateStationAsync(stationId, request); // Update local cache var index = Stations.FindIndex(s => s.Id == stationId); if (index >= 0) { Stations[index] = updated; } // Update selected if it's the same station if (SelectedStation?.Id == stationId) { SelectedStation = updated; } NotifyStateChanged(); return updated; } catch (Exception ex) { ErrorMessage = ex.Message; NotifyStateChanged(); throw; } finally { IsSaving = false; NotifyStateChanged(); } } /// /// Delete a station /// public async Task DeleteStationAsync(Guid stationId) { try { await _apiService.DeleteStationAsync(stationId); // Remove from local list Stations.RemoveAll(s => s.Id == stationId); // Clear selection if it was the deleted station if (SelectedStation?.Id == stationId) { SelectedStation = null; } NotifyStateChanged(); } catch (Exception ex) { ErrorMessage = ex.Message; NotifyStateChanged(); throw; } } // ========================================== // HELPER METHODS // ========================================== /// /// Get filtered stations based on search query /// public List GetFilteredStations() { var query = Stations.AsQueryable(); if (!string.IsNullOrWhiteSpace(SearchQuery)) { var searchLower = SearchQuery.ToLowerInvariant(); query = query.Where(s => s.StationId.ToLower().Contains(searchLower) || (s.StationName != null && s.StationName.ToLower().Contains(searchLower))); } return query.OrderBy(s => s.StationId).ToList(); } private void NotifyStateChanged() { OnStateChanged?.Invoke(); } }