//
//  RoundSettingsView.swift
//  PadelClub
//
//  Created by Razmig Sarkissian on 31/03/2024.
//

import SwiftUI
import LeStorage

struct RoundSettingsView: View {
    @EnvironmentObject var dataStore: DataStore
    
    @Environment(\.isEditingTournamentSeed) private var isEditingTournamentSeed
    @Environment(Tournament.self) var tournament: Tournament
    
    var tournamentStore: TournamentStore {
        return self.tournament.tournamentStore
    }
    
    var body: some View {
        List {
            if tournament.shouldVerifyBracket {
                Section {
                    let issues = tournament.bracketTeamPlacementIssue()
                    DisclosureGroup {
                        ForEach(issues.shouldBeInIt, id: \.self) { id in
                            if let team: TeamRegistration = self.tournamentStore.teamRegistrations.findById(id) {
                                TeamRowView(team: team)
                            }
                        }
                    } label: {
                        LabeledContent {
                            Text(issues.shouldBeInIt.count.formatted())
                        } label: {
                            Text("Équipes à mettre dans le tableau")
                        }
                    }
                    DisclosureGroup {
                        ForEach(issues.shouldNotBeInIt, id: \.self) { id in
                            if let team = self.tournamentStore.teamRegistrations.findById(id) {
                                Menu {
                                    Button("Retirer du tableau") {
                                        team.resetBracketPosition()
                                        do {
                                            try self.tournamentStore.teamRegistrations.addOrUpdate(instance: team)
                                        } catch {
                                            Logger.error(error)
                                        }
                                    }
                                } label: {
                                    TeamRowView(team: team)
                                }
                            }
                        }
                    } label: {
                        LabeledContent {
                            Text(issues.shouldNotBeInIt.count.formatted())
                        } label: {
                            Text("Équipes à retirer du tableau")
                        }
                    }

                    RowButtonView("Valider l'état du tableau", role: .destructive) {
                        tournament.shouldVerifyBracket = false
                        do {
                            try dataStore.tournaments.addOrUpdate(instance: tournament)
                        } catch {
                            Logger.error(error)
                        }
                    }
                } footer: {
                    Text("Suite à un changement dans votre liste d'inscrits, veuillez vérifier l'intégrité de votre tableau et valider que tout est ok.")
                }
            }
                        
//            Section {
//                RowButtonView("Enabled", role: .destructive) {
//                    let allMatches = tournament._allMatchesIncludingDisabled()
//                    allMatches.forEach({ 
//                        $0.disabled = false
//                        $0.byeState = false
//                    })
//                    try? dataStore.matches.addOrUpdate(contentOfs: allMatches)
//                }
//            }
            Section {
                RowButtonView("Retirer toutes les têtes de séries", role: .destructive) {
                    await _removeAllSeeds()
                }
            }
            
            Section {
                let roundIndex = tournament.rounds().count
                RowButtonView("Ajouter " + RoundRule.roundName(fromRoundIndex: roundIndex)) {
                    let round = Round(tournament: tournament.id, index: roundIndex, matchFormat: tournament.matchFormat)
                    let matchCount = RoundRule.numberOfMatches(forRoundIndex: roundIndex)
                    let matchStartIndex = RoundRule.matchIndex(fromRoundIndex: roundIndex)
                    let nextRound = round.nextRound()
                    var currentIndex = 0
                    let matches = (0..<matchCount).map { index in //0 is final match
                        let computedIndex = index + matchStartIndex
                        let match = Match(round: round.id, index: computedIndex, matchFormat: round.matchFormat)
                        if let nextRound, let followingMatch = self.tournament.tournamentStore.matches.first(where: { $0.round == nextRound.id && $0.index == (computedIndex - 1) / 2 }) {
                            if followingMatch.disabled {
                                match.disabled = true
                            } else if computedIndex%2 == 1 && followingMatch.team(.one) != nil {
                                //index du match courant impair = position haut du prochain match
                                match.disabled = true
                            } else if computedIndex%2 == 0 && followingMatch.team(.two) != nil {
                                //index du match courant pair = position basse du prochain match
                                match.disabled = true
                            } else {
                                match.name = Match.setServerTitle(upperRound: round, matchIndex: currentIndex)
                                currentIndex += 1
                            }
                        } else {
                            match.name = Match.setServerTitle(upperRound: round, matchIndex: currentIndex)
                            currentIndex += 1
                        }
                        
                        return match
                    }
                    do {
                        try tournamentStore.rounds.addOrUpdate(instance: round)
                    } catch {
                        Logger.error(error)
                    }
                    do {
                        try tournamentStore.matches.addOrUpdate(contentOfs: matches)
                    } catch {
                        Logger.error(error)
                    }
                    round.buildLoserBracket()
                    matches.filter { $0.disabled }.forEach {                             $0._toggleLoserMatchDisableState(true)
                    }
                }
            }
            
            Section {
                if let lastRound = tournament.rounds().first { // first is final, last round
                    RowButtonView("Supprimer " + lastRound.roundTitle(), role: .destructive) {
                        do {
                            let teams = lastRound.seeds()
                            teams.forEach { team in
                                team.resetBracketPosition()
                            }
                            try tournamentStore.teamRegistrations.addOrUpdate(contentOfs: teams)
                            try tournamentStore.rounds.delete(instance: lastRound)
                        } catch {
                            Logger.error(error)
                        }
                    }
                }
            }
        }
        .toolbar {
            ToolbarItem(placement: .topBarTrailing) {
                ShareLink(item: tournament.rounds().compactMap { $0.pasteData() }.joined(separator: "\n\n"))
            }
        }
    }
    
    private func _removeAllSeeds() async {
        tournament.unsortedTeams().forEach({ team in
            team.bracketPosition = nil
        })
        let ts = tournament.allRoundMatches().flatMap { match in
            match.teamScores
        }
        
        do {
            try tournamentStore.teamScores.delete(contentOfs: ts)
        } catch {
            Logger.error(error)
        }
        do {
            try tournamentStore.teamRegistrations.addOrUpdate(contentOfs: tournament.unsortedTeams())
        } catch {
            Logger.error(error)
        }
        tournament.allRounds().forEach({ round in
            round.enableRound()
        })
        self.isEditingTournamentSeed.wrappedValue = true
    }
}

//#Preview {
//    RoundSettingsView()
//        .environment(Tournament.mock())
//        .environmentObject(DataStore.shared)
//}
