//
//  GroupStageSettingsView.swift
//  PadelClub
//
//  Created by Razmig Sarkissian on 16/07/2024.
//

import SwiftUI
import LeStorage

struct GroupStageSettingsView: View {

    @Environment(\.dismiss) private var dismiss
    @Environment(Tournament.self) private var tournament
    
    @EnvironmentObject var dataStore: DataStore
    
    @Bindable var groupStage: GroupStage
    @State private var groupStageName: String
    @State private var presentConfirmationButton: Bool = false
    @State private var size: Int
    @State private var courtIndex: Int
    @FocusState var focusedField: GroupStage.CodingKeys?

    init(groupStage: GroupStage) {
        _groupStage = Bindable(groupStage)
        _groupStageName = .init(wrappedValue: groupStage.name ?? "")
        _size = .init(wrappedValue: groupStage.size)
        _courtIndex = .init(wrappedValue: groupStage._matches().first?.courtIndex ?? 0)
    }
    
    var tournamentStore: TournamentStore? {
        return self.tournament.tournamentStore
    }
    
    var body: some View {
        Form {
            Section {
                TextField("Nom de la poule", text: $groupStageName)
                    .keyboardType(.alphabet)
                    .focused($focusedField, equals: ._name)
                    .submitLabel(.done)
                    .frame(maxWidth: .infinity)
                    .onSubmit {
                        groupStageName = groupStageName.prefixTrimmed(200)
                        if groupStageName.isEmpty == false {
                            groupStage.name = groupStageName
                            _save()
                            dismiss()
                        }
                    }
            } footer: {
                if groupStage.name != nil {
                    HStack {
                        Spacer()
                        FooterButtonView("retirer le nom") {
                            groupStage.name = nil
                            groupStageName = ""
                            _save()
                        }
                    }
                }
            }
            
            Section {
                CourtPicker(title: "Terrain dédié", selection: $courtIndex, maxCourt: tournament.courtCount)
                RowButtonView("Confirmer", role: .destructive) {
                    groupStage._matches().forEach { match in
                        match.setCourt(courtIndex)
                    }
                    
                    do {
                        try tournamentStore?.matches.addOrUpdate(contentOfs: groupStage._matches())
                    } catch {
                        Logger.error(error)
                    }
                }
            }
            
            Section {
                LabeledContent {
                    StepperView(count: $size, minimum: minimumSize(), maximum: maximumSize())
                } label: {
                    Text("Taille de la poule")
                }
                
                if presentConfirmationButton {
                    RowButtonView("Confirmer", role: .destructive, confirmationMessage: "Tous les matchs et les équipes de cette poule seront ré-initialisés") {
                        let teams = groupStage.teams()
                        teams.forEach { team in
                            team.groupStagePosition = nil
                            team.groupStage = nil
                            groupStage._matches().forEach({ $0.updateTeamScores() })
                        }
                        do {
                            try tournamentStore?.teamRegistrations.addOrUpdate(contentOfs: teams)
                        } catch {
                            Logger.error(error)
                        }
                        groupStage.size = size
                        groupStage.buildMatches()
                        tournament.shouldVerifyGroupStage = true
                        _save()
                        presentConfirmationButton = false
                    }
                }
            } footer: {
                Text("Une poule ne peut pas avoir moins de 3 équipes et plus d'une équipe de différence par rapport aux autres poules.")
            }
            
            Section {
                RowButtonView("Retirer tous les horaires", role: .destructive) {
                    groupStage._matches().forEach { match in
                        match.startDate = nil
                        match.endDate = nil
                    }
                    
                    do {
                        try tournamentStore?.matches.addOrUpdate(contentOfs: groupStage._matches())
                    } catch {
                        Logger.error(error)
                    }
                }
            }
            
            Section {
                RowButtonView("Retirer tout le monde", role: .destructive) {
                    let teams = groupStage.teams()
                    teams.forEach { team in
                        team.groupStagePosition = nil
                        team.groupStage = nil
                        groupStage._matches().forEach({ $0.updateTeamScores() })
                    }
                    do {
                        try tournamentStore?.teamRegistrations.addOrUpdate(contentOfs: teams)
                    } catch {
                        Logger.error(error)
                    }
                }
            } footer: {
                Text("Toutes les équipes seront retirées et les scores des matchs seront perdus.")
            }
            
            Section {
                RowButtonView("Recommencer tous les matchs", role: .destructive) {
                    let isReturnMatchesEnabled = groupStage.isReturnMatchEnabled()
                    groupStage.buildMatches()
                    if isReturnMatchesEnabled {
                        groupStage.addReturnMatches()
                    }
                }
            } footer: {
                Text("Tous les matchs seront recronstruits, les données des matchs seront perdus.")
            }
            
            Section {
                if groupStage.matchPhaseCount > 2 {
                    RowButtonView("Effacer la dernière vague", role: .destructive) {
                        groupStage.removeReturnMatches(onlyLast: true)
                    }
                } else if groupStage.isReturnMatchEnabled() {
                    RowButtonView("Effacer les matchs retours", role: .destructive) {
                        groupStage.removeReturnMatches()
                    }
                }
            }
            
            Section {
                if groupStage.isReturnMatchEnabled() == false {
                    RowButtonView("Rajouter les matchs retours", role: .destructive) {
                        groupStage.addReturnMatches()
                    }
                } else {
                    RowButtonView("Rajouter une vague de matchs", role: .destructive) {
                        groupStage.addReturnMatches()
                    }
                }
            }
            
            Section {
                RowButtonView("Rafraichir", role: .destructive) {
                    let playedMatches = groupStage.playedMatches()
                    playedMatches.forEach { match in
                        match.updateTeamScores()
                    }
                }
            } footer: {
                Text("Mets à jour les équipes de la poule si jamais une erreur est persistante.")
            }
        }
        .onChange(of: size) {
            if size != groupStage.size {
                presentConfirmationButton = true
            }
        }
        .onChange(of: groupStage.matchFormat) {
            _save()
            groupStage.updateAllMatchesFormat()
        }
        .navigationBarBackButtonHidden(focusedField != nil)
        .toolbar(content: {
            if focusedField != nil {
                ToolbarItem(placement: .topBarLeading) {
                    Button("Annuler", role: .cancel) {
                        focusedField = nil
                    }
                }
            }
            
            ToolbarItem(placement: .topBarTrailing) {
                MatchTypeSelectionView(selectedFormat: $groupStage.matchFormat, additionalEstimationDuration: tournament.additionalEstimationDuration, displayStyle: .short)
            }
        })
        .navigationTitle("Paramètres")
        .toolbarBackground(.visible, for: .navigationBar)
    }
    
    private func maximumSize() -> Int {
        return 10
//        if groupStage.index == 0 {
//            return tournament.teamsPerGroupStage + 1
//        }
//
//        if let previousGroupStage = tournament.groupStages().first(where: { $0.index == groupStage.index - 1 }), previousGroupStage.size > groupStage.size {
//            return tournament.teamsPerGroupStage + 1
//        }
//
//        return tournament.teamsPerGroupStage
    }

    private func minimumSize() -> Int {
        return 3
//        if groupStage.index == tournament.groupStageCount - 1 {
//            return max(3, tournament.teamsPerGroupStage - 1)
//        }
//
//        if let nextGroupStage = tournament.groupStages().first(where: { $0.index == groupStage.index + 1 }), nextGroupStage.size < groupStage.size {
//            return max(3, tournament.teamsPerGroupStage - 1)
//        }
//
//        return tournament.teamsPerGroupStage
    }

    private func _save() {
        do {
            try tournamentStore?.groupStages.addOrUpdate(instance: groupStage)
        } catch {
            Logger.error(error)
        }
    }
}
