//
//  LoserBracketFromGroupStageView.swift
//  PadelClub
//
//  Created by razmig on 07/09/2024.
//

import SwiftUI
import LeStorage

struct LoserBracketFromGroupStageView: View {
    
    @Environment(Tournament.self) var tournament: Tournament
    @EnvironmentObject var dataStore: DataStore
    @Environment(NavigationViewModel.self) private var navigation: NavigationViewModel
    @State var loserBracket: Round
    @State private var isEditingLoserBracketGroupStage: Bool

    init(loserBracket: Round) {
        self.loserBracket = loserBracket
        _isEditingLoserBracketGroupStage = .init(wrappedValue: loserBracket._matches().isEmpty)
    }
    
    var tournamentStore: TournamentStore? {
        return self.tournament.tournamentStore
    }

    var displayableMatches: [Match] {
        loserBracket.playedMatches().sorted(by: \.index)
    }

    var body: some View {
        List {
            if isEditingLoserBracketGroupStage == true && displayableMatches.isEmpty == false {
                Section {
                    _addButton()
                }
                
                Section {
                    _smartGenerationButton()
                } footer: {
                    Text("La génération intelligente ajoutera un match par rang entre 2 poules. Si vos poules sont terminées, Padel Club placera les équipes automatiquement.")
                }
            }
            
            ForEach(displayableMatches) { match in
                Section {
                    MatchRowView(match: match)
                        .matchViewStyle(.sectionedStandardStyle)
                        .environment(\.isEditingTournamentSeed, $isEditingLoserBracketGroupStage)
                } header: {
                    let tournamentTeamCount = tournament.teamCount
                    let seedIntervalPointRange = tournament.tournamentLevel.pointsRange(first: match.index, last: match.index + displayableMatches.filter({ $0.index == match.index }).count, teamsCount: tournamentTeamCount)
                    HStack {
                        Text(match.matchTitle(.wide))
                        Spacer()
                        Text(seedIntervalPointRange)
                            .font(.caption)
                    }
                } footer: {
                    if isEditingLoserBracketGroupStage == true {
                        GroupStageLoserBracketMatchFooterView(match: match, samePlaceThanAboveOption: displayableMatches.count > 1)
                    }
                }
            }
            Section {
                if displayableMatches.count > 1 && isEditingLoserBracketGroupStage == true {
                    Section {
                        RowButtonView("Effacer tous les matchs", role: .destructive) {
                            _deleteAllMatches()
                        }
                    } footer: {
                        Text("Efface tous les matchs de classement de poules ci-dessus.")
                    }
                }
            }
        }
        .overlay {
            if displayableMatches.isEmpty {
                ContentUnavailableView {
                    Label("Aucun match de classement", systemImage: "figure.tennis")
                } description: {
                    Text("Vous n'avez créé aucun match de classement entre les perdants de poules. La génération intelligente ajoutera un match par rang entre 2 poules")
                } actions: {
                    _addButton()
                    _smartGenerationButton()
                }
            }
        }
        .headerProminence(.increased)
        .navigationTitle("Classement de poules")
        .toolbar {
            ToolbarItem(placement: .topBarTrailing) {
                if displayableMatches.isEmpty == false {
                    Button(isEditingLoserBracketGroupStage == true ? "Valider" : "Modifier") {
                        if isEditingLoserBracketGroupStage == true {
                            isEditingLoserBracketGroupStage = false
                        } else {
                            isEditingLoserBracketGroupStage = true
                        }
                    }
                }
            }
        }
    }
    
    private func _addNewMatch() {
        let currentGroupStageLoserBracketsInitialPlace = tournament.groupStageLoserBracketsInitialPlace()
        let placeCount = displayableMatches.isEmpty ? currentGroupStageLoserBracketsInitialPlace : max(currentGroupStageLoserBracketsInitialPlace, displayableMatches.map({ $0.index }).max()! + 2)

        let match = Match(round: loserBracket.id, index: placeCount, format: loserBracket.matchFormat)
        match.setMatchName("\(placeCount)\(placeCount.ordinalFormattedSuffix()) place")
        tournamentStore?.matches.addOrUpdate(instance: match)
    }
    
    private func _deleteAllMatches() {
        let displayableMatches = loserBracket.playedMatches().sorted(by: \.index)

        tournamentStore?.matches.delete(contentOfs: displayableMatches)

    }
    
    private func _smartGenerationButton() -> some View {
        RowButtonView("Génération intelligente", role: .destructive, confirmationMessage: displayableMatches.isEmpty ? nil : "Les matchs de classement de poules déjà existants seront supprimés") {
            isEditingLoserBracketGroupStage = true
            _deleteAllMatches()
            tournament.generateSmartLoserGroupStageBracket()
        }
    }
    
    private func _addButton() -> some View {
        RowButtonView("Ajouter un match") {
            isEditingLoserBracketGroupStage = true
            _addNewMatch()
        }
    }

}

struct GroupStageLoserBracketMatchFooterView: View {
    @Environment(Tournament.self) var tournament: Tournament
    @Bindable var match: Match
    let samePlaceThanAboveOption: Bool
    @State private var selectPlacePlayed: Bool = false
    @State private var index: Int = 0
    
    var body: some View {
        HStack {
            Menu {
                if samePlaceThanAboveOption {
                    Button("Même place qu'au-dessus") {
                        _updateIndex(match.index-2)
                    }
                }
                Button("Choisir la place") {
                    index = match.index
                    selectPlacePlayed = true
                }
            } label: {
                Text("Éditer la place jouée")
                    .underline()
            }
            
            Spacer()
            FooterButtonView("Effacer", role: .destructive) {
                do {
                    try match.tournamentStore?.matches.delete(instance: match)
                } catch {
                    Logger.error(error)
                }
            }
        }
        .alert("Place jouée", isPresented: $selectPlacePlayed) {
            TextField("Place jouée", value: $index, format: .number)
                .keyboardType(.numberPad)
                .multilineTextAlignment(.trailing)
                .onSubmit {
                    _updateIndex(index)
                }
            Button("Confirmer") {
                _updateIndex(index)
            }
            Button("Annuler", role: .cancel) {
            }
        }
    }
    
    private func _updateIndex(_ newIndex: Int) {
        let newIndexValidated = max(1,abs(newIndex))
        let teamScores = match.teamScores
        teamScores.forEach { ts in
            if let luckyLoser = ts.luckyLoser {
                ts.luckyLoser = (luckyLoser - match.index * 2) % 2 + newIndexValidated * 2
            }
        }
        
        match.index = newIndexValidated
        
        match.setMatchName("\(newIndexValidated)\(newIndexValidated.ordinalFormattedSuffix()) place")

        
        match.tournamentStore?.teamScores.addOrUpdate(contentOfs: teamScores)
        match.tournamentStore?.matches.addOrUpdate(instance: match)
    }
}
