//
//  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 levels: Set<TournamentLevel> = Set()
    var categories: Set<TournamentCategory> = Set()
    var ageCategories: Set<FederalTournamentAge> = Set()
    var selectedClubs: Set<String> = Set()
    var id: UUID = UUID()
    
    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? = Store.main.filter(isIncluded: { $0.code == codeClub }).first
            return club?.clubTitle(.short)
        }
        
        labels.append(contentsOf: clubNames)
        return labels.joined(separator: ", ")
    }
    
    func selectedClub() -> Club? {
        if  selectedClubs.isEmpty == false {
            return Store.main.filter(isIncluded: { $0.code == selectedClubs.first! }).first
        } else {
            return nil
        }
    }
    
    func removeFilters() {
        levels.removeAll()
        categories.removeAll()
        ageCategories.removeAll()
        selectedClubs.removeAll()
        id = UUID()
    }
    
    func areFiltersEnabled() -> Bool {
        (levels.isEmpty && categories.isEmpty && ageCategories.isEmpty && selectedClubs.isEmpty) == false
    }
    
    var filteredFederalTournaments: [FederalTournament] {
        federalTournaments.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!))
        })
    }
    
    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))
    
        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!))
    }
                                  
    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)
                }
            }
        }
    }
}

