You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
150 lines
5.7 KiB
150 lines
5.7 KiB
//
|
|
// FederalDataViewModel.swift
|
|
// PadelClub
|
|
//
|
|
// Created by Razmig Sarkissian on 30/04/2024.
|
|
//
|
|
|
|
import SwiftUI
|
|
import LeStorage
|
|
|
|
@Observable
|
|
class FederalDataViewModel {
|
|
static let shared = FederalDataViewModel()
|
|
|
|
var federalTournaments: [FederalTournament] = []
|
|
var searchedFederalTournaments: [FederalTournament] = []
|
|
var levels: Set<TournamentLevel> = Set()
|
|
var categories: Set<TournamentCategory> = Set()
|
|
var ageCategories: Set<FederalTournamentAge> = Set()
|
|
var selectedClubs: Set<String> = Set()
|
|
var id: UUID = UUID()
|
|
var searchAttemptCount: Int = 0
|
|
var dayDuration: Int?
|
|
var dayPeriod: DayPeriod = .all
|
|
|
|
func filterStatus() -> String {
|
|
var labels: [String] = []
|
|
labels.append(contentsOf: levels.map { $0.localizedLabel() })
|
|
labels.append(contentsOf: categories.map { $0.localizedLabel() })
|
|
labels.append(contentsOf: ageCategories.map { $0.localizedLabel() })
|
|
let clubNames = selectedClubs.compactMap { codeClub in
|
|
let club: Club? = DataStore.shared.clubs.first(where: { $0.code == codeClub })
|
|
return club?.clubTitle(.short)
|
|
}
|
|
|
|
labels.append(contentsOf: clubNames)
|
|
if dayPeriod != .all {
|
|
labels.append(dayPeriod.localizedDayPeriodLabel())
|
|
}
|
|
if let dayDuration {
|
|
labels.append("max " + dayDuration.formatted() + " jour" + dayDuration.pluralSuffix)
|
|
}
|
|
return labels.joined(separator: ", ")
|
|
}
|
|
|
|
var searchedClubs: [FederalClub] {
|
|
searchedFederalTournaments.compactMap { ft in
|
|
ft.federalClub
|
|
}.uniqued { fc in
|
|
fc.federalClubCode
|
|
}.sorted(by: \.federalClubName)
|
|
}
|
|
|
|
func selectedClub() -> Club? {
|
|
if selectedClubs.isEmpty == false {
|
|
return DataStore.shared.clubs.first(where: { $0.code == selectedClubs.first! })
|
|
} else {
|
|
return nil
|
|
}
|
|
}
|
|
|
|
func removeFilters() {
|
|
levels.removeAll()
|
|
categories.removeAll()
|
|
ageCategories.removeAll()
|
|
selectedClubs.removeAll()
|
|
dayPeriod = .all
|
|
dayDuration = nil
|
|
id = UUID()
|
|
}
|
|
|
|
func areFiltersEnabled() -> Bool {
|
|
(levels.isEmpty && categories.isEmpty && ageCategories.isEmpty && selectedClubs.isEmpty && dayPeriod == .all && dayDuration == nil) == false
|
|
}
|
|
|
|
var filteredFederalTournaments: [FederalTournamentHolder] {
|
|
filteredFederalTournaments(from: federalTournaments)
|
|
}
|
|
|
|
var filteredSearchedFederalTournaments: [FederalTournamentHolder] {
|
|
filteredFederalTournaments(from: searchedFederalTournaments)
|
|
}
|
|
|
|
func filteredFederalTournaments(from tournaments: [any FederalTournamentHolder]) -> [FederalTournamentHolder] {
|
|
tournaments.filter({ tournament in
|
|
(levels.isEmpty || tournament.tournaments.anySatisfy({ levels.contains($0.level) }))
|
|
&&
|
|
(categories.isEmpty || tournament.tournaments.anySatisfy({ categories.contains($0.category) }))
|
|
&&
|
|
(ageCategories.isEmpty || tournament.tournaments.anySatisfy({ ageCategories.contains($0.age) }))
|
|
&&
|
|
(selectedClubs.isEmpty || selectedClubs.contains(tournament.codeClub!))
|
|
&&
|
|
(dayPeriod == .all || (dayPeriod != .all && dayPeriod == tournament.dayPeriod))
|
|
&&
|
|
(dayDuration == nil || (dayDuration != nil && dayDuration == tournament.dayDuration))
|
|
})
|
|
}
|
|
|
|
func isTournamentValidForFilters(_ tournament: Tournament) -> Bool {
|
|
if tournament.isDeleted { return false }
|
|
let firstPart = (levels.isEmpty || levels.contains(tournament.level))
|
|
&&
|
|
(categories.isEmpty || categories.contains(tournament.category))
|
|
&&
|
|
(ageCategories.isEmpty || ageCategories.contains(tournament.age))
|
|
&&
|
|
(dayPeriod == .all || (dayPeriod != .all && dayPeriod == tournament.dayPeriod))
|
|
&&
|
|
(dayDuration == nil || (dayDuration != nil && dayDuration == tournament.dayDuration))
|
|
|
|
if let codeClub = tournament.club()?.code {
|
|
return firstPart && (selectedClubs.isEmpty || selectedClubs.contains(codeClub))
|
|
} else {
|
|
return firstPart
|
|
}
|
|
}
|
|
|
|
func isFederalTournamentValidForFilters(_ tournament: FederalTournament, build: any TournamentBuildHolder) -> Bool {
|
|
(levels.isEmpty || levels.contains(build.level))
|
|
&&
|
|
(categories.isEmpty || categories.contains(build.category))
|
|
&&
|
|
(ageCategories.isEmpty || ageCategories.contains(build.age))
|
|
&&
|
|
(selectedClubs.isEmpty || selectedClubs.contains(tournament.codeClub!))
|
|
&&
|
|
(dayPeriod == .all || (dayPeriod != .all && dayPeriod == tournament.dayPeriod))
|
|
&&
|
|
(dayDuration == nil || (dayDuration != nil && dayDuration == tournament.dayDuration))
|
|
}
|
|
|
|
func gatherTournaments(clubs: [Club], startDate: Date, endDate: Date? = nil) async throws {
|
|
try await clubs.filter { $0.code != nil }.concurrentForEach { club in
|
|
let newTournaments = try await NetworkFederalService.shared.getClubFederalTournaments(page: 0, tournaments: [], club: club.name, codeClub: club.code!, startDate: startDate, endDate: endDate)
|
|
|
|
newTournaments.forEach { tournament in
|
|
if self.federalTournaments.contains(where: { $0.id == tournament.id }) == false {
|
|
self.federalTournaments.append(tournament)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
struct FederalClub: Identifiable {
|
|
var id: String { federalClubCode }
|
|
var federalClubCode: String
|
|
var federalClubName: String
|
|
}
|
|
|