import Foundation import SwiftUI @MainActor class RaceDiscoveryViewModel: ObservableObject { @Published var races: [Race] = [] @Published var savedRaces: [Race] = [] @Published var selectedRace: Race? @Published var isLoading: Bool = false @Published var error: RaceError? @Published var filter: RaceFilter = RaceFilter() private let service: RaceServiceProtocol init(service: RaceServiceProtocol = RaceService()) { self.service = service } func fetchRaces() async { isLoading = true error = nil defer { isLoading = false } do { races = try await service.listRaces(filter: filter) } catch let error as RaceError { self.error = error } catch { print("Failed to fetch races: \(error)") } } func selectRace(id: String) async { isLoading = true error = nil defer { isLoading = false } do { let race = try await service.getRace(id: id) selectedRace = race if let index = races.firstIndex(where: { $0.id == id }) { races[index] = race objectWillChange.send() } } catch let error as RaceError { self.error = error } catch { print("Failed to get race: \(error)") } } func toggleSaveRace(id: String) async { guard let race = races.first(where: { $0.id == id }) else { return } let newSavedState = !race.isSaved do { try await service.saveRace(id: id, isSaved: newSavedState) if let index = races.firstIndex(where: { $0.id == id }) { races[index].isSaved = newSavedState objectWillChange.send() } if newSavedState { savedRaces.append(races.first(where: { $0.id == id }) ?? race) } else { savedRaces.removeAll { $0.id == id } } objectWillChange.send() } catch { print("Failed to toggle save race: \(error)") } } func registerForRace(id: String) async { do { try await service.registerForRace(id: id) if let index = races.firstIndex(where: { $0.id == id }) { races[index].isRegistered = true objectWillChange.send() } } catch { print("Failed to register for race: \(error)") } } func fetchSavedRaces() async { isLoading = true error = nil defer { isLoading = false } do { savedRaces = try await service.listRaces(filter: RaceFilter(limit: 50, offset: 0)) .filter { $0.isSaved } } catch let error as RaceError { self.error = error } catch { print("Failed to fetch saved races: \(error)") } } var upcomingRaces: [Race] { races.filter { $0.isUpcoming }.sorted { $0.raceDate < $1.raceDate } } var raceTypes: [RaceType] { RaceType.allCases } var terrainTypes: [TerrainType] { TerrainType.allCases } }