//
//  Patcher.swift
//  PadelClub
//
//  Created by Laurent Morvillier on 21/06/2024.
//

import Foundation
import LeStorage

enum Patch: String, CaseIterable {
    case alexisLeDu
    case importDataFromDev
    
    var id: String {
        return "padelclub.app.patch.\(self.rawValue)"
    }
}

class Patcher {
    
    static func applyAllWhenApplicable() {
        for patch in Patch.allCases {
            self.patchIfPossible(patch)
        }
    }
    
    static func patchIfPossible(_ patch: Patch) {
        if UserDefaults.standard.value(forKey: patch.id) == nil {
            self._applyPatch(patch)
            UserDefaults.standard.setValue(true, forKey: patch.id)
        }
    }
    
    fileprivate static func _applyPatch(_ patch: Patch) {
        switch patch {
        case .alexisLeDu: self._patchAlexisLeDu()
        case .importDataFromDev: self._importDataFromDev()
        }
    }
    
    fileprivate static func _patchAlexisLeDu() {
        guard StoreCenter.main.userId == "94f45ed2-8938-4c32-a4b6-e4525073dd33" else { return }
        
        Logger.log(">>> Start patch...")
        
        let clubs = DataStore.shared.clubs
        StoreCenter.main.resetApiCalls(collection: clubs)
//        clubs.resetApiCalls()
        
        for club in clubs.filter({ $0.creator == "d5060b89-e979-4c19-bf78-e459a6ed5318"}) {
            club.creator = StoreCenter.main.userId
            clubs.writeChangeAndInsertOnServer(instance: club)
        }
        
    }
    
    fileprivate static func _importDataFromDev() {
        
        guard let userId = StoreCenter.main.userId else {
            return
        }
        
//        return // TODO review
        
        let services = Services(url: "https://xlr.alwaysdata.net/roads/")
        if services.hasToken() {
            
            Task {
                
                let clubs: [Club] = try await services.get()
                let events: [Event] = try await services.get()
                let tournaments: [Tournament] = try await services.get()
                let courts: [Court] = try await services.get()
                let dateIntervals: [DateInterval] = try await services.get()

                let clubIds = Set(events.compactMap { $0.club })
                let myClubs: [Club] = clubIds.compactMap { clubId in
                    clubs.first { $0.id == clubId }
                }
                myClubs.forEach { $0.creator = userId }
                
                try DataStore.shared.clubs.addOrUpdate(contentOfs: myClubs)
                for club in myClubs {
                    let courts = courts.filter { $0.club == club.id }
                    try DataStore.shared.courts.addOrUpdate(contentOfs: courts)
                }
                
                DataStore.shared.user.clubs.append(contentsOf: clubIds)
                DataStore.shared.saveUser()
                
                events.forEach { $0.creator = userId }
                
                try DataStore.shared.events.addOrUpdate(contentOfs: events)
                try DataStore.shared.tournaments.addOrUpdate(contentOfs: tournaments)
                try DataStore.shared.dateIntervals.addOrUpdate(contentOfs: dateIntervals)

                for tournament in DataStore.shared.tournaments {
                    let store = tournament.tournamentStore
                    let identifier = StoreIdentifier(value: tournament.id, parameterName: "tournament")
                    
                    let rounds: [Round] = try await services.get(identifier: identifier)
                    let groupStages: [GroupStage] = try await services.get(identifier: identifier)
                    let matches: [Match] = try await services.get(identifier: identifier)
                    let teamRegistrations: [TeamRegistration] = try await services.get(identifier: identifier)
                    let teamScores: [TeamScore] = try await services.get(identifier: identifier)
                    let playerRegistrations: [PlayerRegistration] = try await services.get(identifier: identifier)
                    
                    try store.teamRegistrations.addOrUpdate(contentOfs: teamRegistrations)
                    try store.rounds.addOrUpdate(contentOfs: rounds)
                    try store.groupStages.addOrUpdate(contentOfs: groupStages)
                    try store.matches.addOrUpdate(contentOfs: matches)
                    try store.playerRegistrations.addOrUpdate(contentOfs: playerRegistrations)
                    try store.teamScores.addOrUpdate(contentOfs: teamScores)
                }
                
            }
            
        } else {
            Logger.log("no token for import")
        }
        
    }
    
}
