//
//  InscriptionManagerView.swift
//  PadelClub
//
//  Created by Razmig Sarkissian on 29/02/2024.
//

import SwiftUI
import TipKit
import LeStorage

//let slideToDeleteTip = SlideToDeleteTip()
let inscriptionManagerWomanRankTip = InscriptionManagerWomanRankTip()
//let fileTip = InscriptionManagerFileInputTip()
//let pasteTip = InscriptionManagerPasteInputTip()
//let searchTip = InscriptionManagerSearchInputTip()
//let createTip = InscriptionManagerCreateInputTip()
let rankUpdateTip = InscriptionManagerRankUpdateTip()
let padelBeachExportTip = PadelBeachExportTip()
let padelBeachImportTip = PadelBeachImportTip()
let teamsExportTip = TeamsExportTip()

struct InscriptionManagerView: View {
    
    @EnvironmentObject var dataStore: DataStore
    
    @EnvironmentObject var networkMonitor: NetworkMonitor
    @Environment(\.dismiss) var dismiss

    var tournament: Tournament
    var cancelShouldDismiss: Bool = false

    @State private var searchField: String = ""
    @State private var presentSearch: Bool = false
    @State private var presentPlayerSearch: Bool = false
    @State private var presentPlayerCreation: Bool = false
    @State private var presentImportView: Bool = false
    @State private var isLearningMore: Bool = false
    @State private var editedTeam: TeamRegistration?
    @State private var currentRankSourceDate: Date?
    @State private var confirmUpdateRank = false
    @State private var selectionSearchField: String?
    @State private var teamsHash: Int?
    @State private var presentationCount: Int = 0
    @State private var filterMode: FilterMode = .all
    @State private var sortingMode: SortingMode = .teamWeight
    @State private var byDecreasingOrdering: Bool = false
    @State private var contactType: ContactType? = nil
    @State private var sentError: ContactManagerError? = nil
    @State private var showSubscriptionView: Bool = false
    @State private var confirmDuplicate: Bool = false
    @State private var presentAddTeamView: Bool = false
    @State private var compactMode: Bool = true
    @State private var pasteString: String?
    
    var tournamentStore: TournamentStore {
        return self.tournament.tournamentStore
    }
    
    var messageSentFailed: Binding<Bool> {
        Binding {
            sentError != nil
        } set: { newValue in
            if newValue == false {
                sentError = nil
            }
        }
    }


    enum SortingMode: Int, Identifiable, CaseIterable {
        var id: Int { self.rawValue }
        case registrationDate
        case teamWeight
        
        func localizedLabel() -> String {
            switch self {
            case .registrationDate:
                return "Date d'inscription"
            case .teamWeight:
                return "Poids d'équipe"
            }
        }
    }

    enum FilterMode: Int, Identifiable, CaseIterable {
        var id: Int { self.rawValue }
        case all
        case walkOut
        case waiting
        case bracket
        case groupStage
        case wildcardGroupStage
        case wildcardBracket
        
        func emptyLocalizedLabelDescription() -> String {
            switch self {
            case .wildcardBracket:
                return "Vous n'avez aucune wildcard en tableau."
            case .wildcardGroupStage:
                return "Vous n'avez aucune wildcard en poule."
            case .all:
                return "Vous n'avez encore aucune équipe inscrite."
            case .walkOut:
                return "Vous n'avez aucune équipe forfait."
            case .waiting:
                return "Vous n'avez aucune équipe en liste d'attente."
            case .bracket:
                return "Vous n'avez placé aucune équipe dans le tableau."
            case .groupStage:
                return "Vous n'avez placé aucune équipe en poule."
            }
        }

        func emptyLocalizedLabelTitle() -> String {
            switch self {
            case .wildcardBracket:
                return "Aucune wildcard en tableau"
            case .wildcardGroupStage:
                return "Aucune wildcard en poule"
            case .all:
                return "Aucune équipe inscrite"
            case .walkOut:
                return "Aucune équipe forfait"
            case .waiting:
                return "Aucune équipe en attente"
            case .bracket:
                return "Aucune équipe dans le tableau"
            case .groupStage:
                return "Aucune équipe en poule"
            }
        }

        func localizedLabel(_ displayStyle: DisplayStyle = .wide) -> String {
            switch self {
            case .wildcardBracket:
                return displayStyle == .wide ? "Wildcard Tableau" : "wc tableau"
            case .wildcardGroupStage:
                return displayStyle == .wide ? "Wildcard Poule" : "wc poule"
            case .all:
                return displayStyle == .wide ? "Équipes inscrites" : "inscris"
            case .bracket:
                return displayStyle == .wide ? "En Tableau" : "tableau"
            case .groupStage:
                return displayStyle == .wide ? "En Poule" : "poule"
            case .walkOut:
                return displayStyle == .wide ? "Forfaits" : "forfait"
            case .waiting:
                return displayStyle == .wide ? "Liste d'attente" : "attente"
            }
        }
    }

    init(tournament: Tournament) {
        self.tournament = tournament
        _currentRankSourceDate = State(wrappedValue: tournament.rankSourceDate)
    }
        
    // Function to create a simple hash from a list of IDs
    private func _simpleHash(ids: [String]) -> Int {
        // Combine the hash values of each string
        return ids.reduce(0) { $0 ^ $1.hashValue }
    }

    // Function to check if two lists of IDs produce different hashes
    private func _areDifferent(ids1: [String], ids2: [String]) -> Bool {
        return _simpleHash(ids: ids1) != _simpleHash(ids: ids2)
    }

    private func _setHash() {
        #if _DEBUG_TIME //DEBUGING TIME
        let start = Date()
        defer {
            let duration = Duration.milliseconds(Date().timeIntervalSince(start) * 1_000)
            print("func _setHash", duration.formatted(.units(allowed: [.seconds, .milliseconds])))
        }
        #endif
        let selectedSortedTeams = tournament.selectedSortedTeams()
        if self.teamsHash == nil, selectedSortedTeams.isEmpty == false {
            self.teamsHash = _simpleHash(ids: selectedSortedTeams.map { $0.id })
        }
    }
    
    private func _handleHashDiff() {
        let selectedSortedTeams = tournament.selectedSortedTeams()
        let newHash = _simpleHash(ids: selectedSortedTeams.map { $0.id })
        if (self.teamsHash != nil && newHash != teamsHash!) || (self.teamsHash == nil && selectedSortedTeams.isEmpty == false) {
            self.teamsHash = newHash
            if self.tournament.shouldVerifyBracket == false || self.tournament.shouldVerifyGroupStage == false {
                self.tournament.shouldVerifyBracket = true
                self.tournament.shouldVerifyGroupStage = true
                
                let waitingList = self.tournament.waitingListTeams(in: selectedSortedTeams, includingWalkOuts: true)
                waitingList.forEach { team in
                    if team.bracketPosition != nil || team.groupStagePosition != nil {
                        team.resetPositions()
                    }
                }
                                    
                do {
                    try tournamentStore.teamRegistrations.addOrUpdate(contentOfs: waitingList)
                    try dataStore.tournaments.addOrUpdate(instance: tournament)
                } catch {
                    Logger.error(error)
                }
            }
        }
    }
    
    var body: some View {
        Group {
            if tournament.unsortedTeams().isEmpty == false {
                _teamRegisteredView()
            } else {
                List {
                    
                }
                .overlay {
                    ContentUnavailableView {
                        Label("Aucune équipe", systemImage: "person.2.slash")
                    } description: {
                        Text("Vous n'avez aucune équipe dans votre liste. Complétez là ou importer un fichier.")
                    } actions: {
                        RowButtonView("Ajouter une équipe") {
                            presentAddTeamView = true
                        }
                        .padding(.horizontal)

                        RowButtonView("Importer un fichier") {
                            presentImportView = true
                        }
                        .padding(.horizontal)
                    }
                    .padding()
                }
            }
        }
        .onAppear {
            _setHash()
        }
        .onDisappear {
            _handleHashDiff()
        }
        .alert("Un problème est survenu", isPresented: messageSentFailed) {
            Button("OK") {
            }
        } message: {
            Text(_networkErrorMessage)
        }
        .sheet(item: $contactType) { contactType in
            Group {
                switch contactType {
                case .message(_, let recipients, let body, _):
                    if Guard.main.paymentForNewTournament() != nil {
                        MessageComposeView(recipients: recipients, body: body) { result in
                            switch result {
                            case .cancelled:
                                break
                            case .failed:
                                self.sentError = .messageFailed
                            case .sent:
                                if networkMonitor.connected == false {
                                    self.sentError = .messageNotSent
                                }
                            @unknown default:
                                break
                            }
                        }
                    } else {
                        SubscriptionView(isPresented: self.$showSubscriptionView, showLackOfPlanMessage: true)
                            .environment(\.colorScheme, .light)
                    }
                case .mail(_, let recipients, let bccRecipients, let body, let subject, _):
                    if Guard.main.paymentForNewTournament() != nil {
                        MailComposeView(recipients: recipients, bccRecipients: bccRecipients, body: body, subject: subject) { result in
                            switch result {
                            case .cancelled, .saved:
                                self.contactType = nil
                            case .failed:
                                self.contactType = nil
                                self.sentError = .mailFailed
                            case .sent:
                                if networkMonitor.connected == false {
                                    self.contactType = nil
                                    self.sentError = .mailNotSent
                                }
                            @unknown default:
                                break
                            }
                        }
                    } else {
                        SubscriptionView(isPresented: self.$showSubscriptionView, showLackOfPlanMessage: true)
                            .environment(\.colorScheme, .light)
                    }
                }
            }
            .tint(.master)
        }
        .sheet(isPresented: $isLearningMore) {
            LearnMoreSheetView(tournament: tournament)
                .tint(.master)
        }
        .sheet(isPresented: $presentImportView, onDismiss: {
            _setHash()
        }) {
            NavigationStack {
                FileImportView()
            }
            .tint(.master)
        }
        .onChange(of: tournament.prioritizeClubMembers) {
            _save()
            _setHash()
        }
        .onChange(of: tournament.teamSorting) {
            _save()
            _setHash()
        }
        .onChange(of: currentRankSourceDate) {
            if let currentRankSourceDate, tournament.rankSourceDate != currentRankSourceDate {
                confirmUpdateRank = true
            }
        }
        .sheet(isPresented: $confirmUpdateRank, onDismiss: {
            currentRankSourceDate = tournament.rankSourceDate
        }) {
            UpdateSourceRankDateView(currentRankSourceDate: $currentRankSourceDate, confirmUpdateRank: $confirmUpdateRank, tournament: tournament)
                .tint(.master)
        }
        .sheet(isPresented: $presentAddTeamView, onDismiss: {
            _setHash()
        }) {
            NavigationStack {
                AddTeamView(tournament: tournament)
            }
            .tint(.master)
        }
        .sheet(item: $editedTeam, onDismiss: {
            _setHash()
        }) { editedTeam in
            NavigationStack {
                AddTeamView(tournament: tournament, editedTeam: editedTeam)
            }
            .tint(.master)
        }
        .sheet(item: $pasteString, onDismiss: {
            _setHash()
        }) { pasteString in
            NavigationStack {
                AddTeamView(tournament: tournament, pasteString: pasteString)
            }
            .tint(.master)
        }
        .toolbar {
            ToolbarItemGroup(placement: .navigationBarTrailing) {
                Menu {
                    Toggle(isOn: $compactMode) {
                        Text("Vue compact")
                    }
                    Divider()
                    Picker(selection: $filterMode) {
                        ForEach(FilterMode.allCases) {
                            Text($0.localizedLabel()).tag($0)
                        }
                    } label: {
                    }
                    Picker(selection: $sortingMode) {
                        ForEach(SortingMode.allCases) {
                            Text($0.localizedLabel()).tag($0)
                        }
                    } label: {
                    }
                    
                    Picker(selection: $byDecreasingOrdering) {
                        Text("Croissant").tag(false)
                        Text("Décroissant").tag(true)
                    } label: {
                    }
                } label: {
                    LabelFilter()
                        .symbolVariant(filterMode == .all ? .none : .fill)
                }
                Menu {
                    if tournament.inscriptionClosed() == false {
                        Menu {
                            _sortingTypePickerView()
                        } label: {
                            Text("Méthode de sélection")
                            Text(tournament.teamSorting.localizedLabel())
                        }
                        Divider()
                        rankingDateSourcePickerView(showDateInLabel: true)
                        
                        Divider()
                        Button {
                            tournament.lockRegistration()
                            _save()
                        } label: {
                            Label("Clôturer", systemImage: "lock")
                        }
                        Divider()
                        _sharingTeamsMenuView()
                        Button {
                            presentImportView = true
                        } label: {
                            Label("Importer beach-padel", systemImage: "square.and.arrow.down")
                        }
                        Link(destination: URLs.beachPadel.url) {
                            Label("beach-padel.app.fft.fr", systemImage: "safari")
                        }
                    } else {

                        _sharingTeamsMenuView()
                        
                        Divider()
                        
                        Button {
                            tournament.unlockRegistration()
                            _save()
                        } label: {
                            Label("Ré-ouvrir", systemImage: "lock.open")
                        }
                    }
                } label: {
                    if tournament.inscriptionClosed() == false {
                        LabelOptions()
                    } else {
                        Label("Clôturer", systemImage: "lock")
                    }
                }
            }
        }
        .toolbarBackground(.visible, for: .navigationBar)
        .navigationTitle("Inscriptions")
        .navigationBarTitleDisplayMode(.inline)
    }
    
    private func _sharingTeamsMenuView() -> some View {
        Menu {
            if let teamPaste = teamPaste() {
                ShareLink(item: teamPaste) {
                    Text("En texte")
                }
            }
            if let teamPaste = teamPaste(.csv) {
                ShareLink(item: teamPaste) {
                    Text("En csv")
                }
            }
        } label: {
            Label("Exporter les paires", systemImage: "square.and.arrow.up")
        }
    }
    
    var walkoutTeams: [TeamRegistration] {
        tournament.walkoutTeams()
    }
    
    var unsortedTeamsWithoutWO: [TeamRegistration] {
        tournament.unsortedTeamsWithoutWO()
    }
    
    func teamPaste(_ exportFormat: ExportFormat = .rawText) -> URL? {
        tournament.pasteDataForImporting(exportFormat).createFile(self.tournament.tournamentTitle(.short), exportFormat)
    }

    var unsortedPlayers: [PlayerRegistration] {
        tournament.unsortedPlayers()
    }

    var sortedTeams: [TeamRegistration] {
        if filterMode == .waiting {
            return tournament.waitingListSortedTeams()
        } else {
            return tournament.sortedTeams()
        }
    }

    var filteredTeams: [TeamRegistration] {

        var teams = sortedTeams
        switch filterMode {
        case .wildcardBracket:
            teams = teams.filter({ $0.wildCardBracket })
        case .wildcardGroupStage:
            teams = teams.filter({ $0.wildCardGroupStage })
        case .walkOut:
            teams = teams.filter({ $0.walkOut })
        case .bracket:
            teams = teams.filter({ $0.inRound() && $0.inGroupStage() == false })
        case .groupStage:
            teams = teams.filter({ $0.inGroupStage() })
        default:
            break
        }

        if sortingMode == .registrationDate {
            teams = teams.sorted(by: \.computedRegistrationDate)
        }
        
        if byDecreasingOrdering {
            return teams.reversed()
        } else {
            return teams
        }
    }
    
    private func _teamRegisteredView() -> some View {
        List {
            let selectedSortedTeams = tournament.selectedSortedTeams()

            if presentSearch == false {
                _informationView()
                _rankHandlerView()
                _relatedTips()
            }
            
            let teams = searchField.isEmpty ? filteredTeams : filteredTeams.filter({ $0.contains(searchField.canonicalVersion) })
            
            if teams.isEmpty && searchField.isEmpty == false {
                ContentUnavailableView {
                    Label("Aucun résultat", systemImage: "person.2.slash")
                } description: {
                    Text("\(searchField) est introuvable dans les équipes inscrites.")
                } actions: {
                    RowButtonView("Modifier la recherche") {
                        searchField = ""
                        presentSearch = true
                    }
                    
                    RowButtonView("Créer une équipe") {
                        pasteString = searchField
                    }
                    
                    RowButtonView("D'accord") {
                        searchField = ""
                        presentSearch = false
                    }
                }
            }
            
            if teams.isEmpty == false {
                if compactMode {
                    Section {
                        ForEach(teams) { team in
                            let teamIndex = team.index(in: sortedTeams)
                            NavigationLink {
                                EditingTeamView(team: team)
                                    .environment(tournament)
                            } label: {
                                TeamRowView(team: team)
                            }
                            .swipeActions(edge: .trailing, allowsFullSwipe: true) {
                                _teamDeleteButtonView(team)
                            }
                            .listRowView(isActive: true, color: team.initialRoundColor() ?? tournament.cutLabelColor(index: teamIndex, teamCount: filterMode == .waiting ? 0 : selectedSortedTeams.count), hideColorVariation: true)
                        }
                    } header: {
                        if filterMode == .all && walkoutTeams.isEmpty == false {
                            Text("\(teams.count.formatted()) équipe\(teams.count.pluralSuffix) dont \(walkoutTeams.count.formatted()) forfait\(walkoutTeams.count.pluralSuffix)")
                        } else {
                            Text("\(teams.count.formatted()) équipe\(teams.count.pluralSuffix)")
                        }
                    }
                    .headerProminence(.increased)
                } else {
                    ForEach(teams) { team in
                        let teamIndex = team.index(in: sortedTeams)
                        Section {
                            TeamDetailView(team: team)
                        } header: {
                            TeamHeaderView(team: team, teamIndex: filterMode == .waiting ? nil : teamIndex, tournament: tournament, teamCount: filterMode == .waiting ? 0 : selectedSortedTeams.count)
                        } footer: {
                            _teamFooterView(team)
                        }
                        .headerProminence(.increased)
                    }
                }
            } else if filterMode != .all {
                ContentUnavailableView {
                    Label(filterMode.emptyLocalizedLabelTitle(), systemImage: "person.2.slash")
                } description: {
                    Text(filterMode.emptyLocalizedLabelDescription())
                } actions: {
                    RowButtonView("Supprimer le filtre") {
                        filterMode = .all
                    }
                }
            }
        }
        .searchable(text: $searchField, isPresented: $presentSearch, prompt: Text("Chercher parmi les équipes inscrites"))
        .keyboardType(.alphabet)
        .autocorrectionDisabled()
    }

    @ViewBuilder
    func rankingDateSourcePickerView(showDateInLabel: Bool) -> some View {
        Section {
            let dates = Set(SourceFileManager.shared.allFilesSortedByDate(true).map({ $0.dateFromPath })).sorted().reversed()
            
            Picker(selection: $currentRankSourceDate) {
                if currentRankSourceDate == nil {
                    Text("inconnu").tag(nil as Date?)
                }
                ForEach(dates, id: \.self) { date in
                    Text(date.monthYearFormatted).tag(date as Date?)
                }
            } label: {
                Text("Classement utilisé")
                if showDateInLabel {
                    if let currentRankSourceDate {
                        Text(currentRankSourceDate.monthYearFormatted)
                    } else {
                        Text("Choisir le mois")
                    }
                }
            }
            .pickerStyle(.menu)
        }

    }

    private func _addPlayerSex() -> Int {
        switch tournament.tournamentCategory {
        case .men, .unlisted:
            return 1
        case .women:
            return 0
        case .mix:
            return 1
        }

    }
    
    private func _filterOption() -> PlayerFilterOption {
        return tournament.tournamentCategory.playerFilterOption
    }
    
    @ViewBuilder
    private func _rankHandlerView() -> some View {
        if let mostRecentDate = SourceFileManager.shared.lastDataSourceDate(), let currentRankSourceDate, currentRankSourceDate < mostRecentDate, tournament.hasEnded() == false {
            Section {
                TipView(rankUpdateTip) { action in
                    self.currentRankSourceDate = mostRecentDate
                }
                .tipStyle(tint: nil)
            }
            rankingDateSourcePickerView(showDateInLabel: false)
        } else if tournament.rankSourceDate == nil {
            rankingDateSourcePickerView(showDateInLabel: false)
        }
    }
    
    private func _teamCountForFilterMode(filterMode: FilterMode) -> String {
        switch filterMode {
        case .wildcardBracket:
            return tournament.selectedSortedTeams().filter({ $0.wildCardBracket }).count.formatted()
        case .wildcardGroupStage:
            return tournament.selectedSortedTeams().filter({ $0.wildCardGroupStage }).count.formatted()
        case .all:
            return unsortedTeamsWithoutWO.count.formatted()
        case .bracket:
            return tournament.selectedSortedTeams().filter({ $0.inRound() && $0.inGroupStage() == false }).count.formatted()
        case .groupStage:
            return tournament.selectedSortedTeams().filter({ $0.inGroupStage() }).count.formatted()
        case .walkOut:
            let wo = walkoutTeams.count.formatted()
            return wo
        case .waiting:
            let waiting: Int = max(0, unsortedTeamsWithoutWO.count - tournament.teamCount)
            return waiting.formatted()
        }
    }
    
    @ViewBuilder
    private func _informationView() -> some View {
        Section {
            HStack {
//                VStack(alignment: .leading, spacing: 0) {
//                    Text("Inscriptions").font(.caption)
//                    Text(unsortedTeamsWithoutWO.count.formatted()).font(.largeTitle)
//                }
//                .frame(maxWidth: .infinity)
//                .contentShape(Rectangle())
//                .onTapGesture {
//                    self.filterMode = .all
//                }
//                
                ForEach([FilterMode.all, FilterMode.waiting, FilterMode.walkOut]) { filterMode in
                    _filterModeView(filterMode: filterMode)
                }

                Button {
                    presentAddTeamView = true
                } label: {
                    VStack(alignment: .center, spacing: -2) {
                        Text(" ").font(.caption).padding(.horizontal, -8)
                        Text(" ").font(.largeTitle)
                    }
                    .frame(maxWidth: .infinity)
                    .contentShape(Rectangle())
                    .hidden()
                    .overlay {
                        Image(systemName: "plus.circle.fill")
                            .resizable()
                            .scaledToFit()
                            .padding(8)
                    }
                }
                .buttonBorderShape(.roundedRectangle)
                .buttonStyle(.borderedProminent)
            }
            .padding(.bottom, -4)
            .fixedSize(horizontal: false, vertical: false)
            .listRowSeparator(.hidden)
            HStack {
                ForEach([FilterMode.groupStage, FilterMode.bracket, FilterMode.wildcardGroupStage, FilterMode.wildcardBracket]) { filterMode in
                    _filterModeView(filterMode: filterMode)
                }
            }
            .padding(.bottom, -4)
            .fixedSize(horizontal: false, vertical: false)
            .listRowSeparator(.hidden)

            let registrationIssues = tournament.registrationIssues()
            if registrationIssues > 0 {
                NavigationLink {
                    InscriptionInfoView()
                        .environment(tournament)
                } label: {
                    LabeledContent {
                        Text(tournament.registrationIssues().formatted())
                            .foregroundStyle(.logoRed)
                            .fontWeight(.bold)
                    } label: {
                        Text("Problèmes détéctés")
                    }
                }
            }
            
            if let closedRegistrationDate = tournament.closedRegistrationDate {
                CloseDatePicker(closedRegistrationDate: closedRegistrationDate)
            }

        } header: {
            HStack {
                Spacer()
                FooterButtonView(compactMode ? "passer en affichage détaillée" : "passer en affichage compact") {
                    compactMode.toggle()
                }
                Spacer()
            }
            .textCase(nil)
        } footer: {
            if tournament.closedRegistrationDate != nil {
                Text("Toutes les équipes ayant été inscrites après la date de clôture seront en liste d'attente.")
            }
        }
    }
    
    private func _filterModeView(filterMode: FilterMode) -> some View {
        
        Button {
            if self.filterMode == filterMode {
                self.filterMode = .all
            } else {
                self.filterMode = filterMode
            }
        } label: {
            VStack(alignment: .center, spacing: -2) {
                Text(filterMode.localizedLabel(.short)).font(.caption).padding(.horizontal, -8)
                Text(_teamCountForFilterMode(filterMode: filterMode)).font(.largeTitle)
            }
            .frame(maxWidth: .infinity)
            .contentShape(Rectangle())
        }
        .buttonBorderShape(.roundedRectangle)
        .buttonStyle(.borderedProminent)
        .foregroundStyle(self.filterMode == filterMode ? Color.white : Color.black)
        .tint(self.filterMode == filterMode ? .master : .beige)

    }
//
//    @ViewBuilder
//    private func _informationView() -> some View {
//        Section {
//            Button {
//                filterMode = .all
//            } label: {
//                LabeledContent {
//                    Text(unsortedTeamsWithoutWO.count.formatted() + "/" + tournament.teamCount.formatted())
//                } label: {
//                    Text("Paire\(unsortedTeamsWithoutWO.count.pluralSuffix) inscrite\(unsortedTeamsWithoutWO.count.pluralSuffix)")
//                }
//            }
//            .buttonStyle(.plain)
//            
//            HStack {
//                let waiting: Int = max(0, unsortedTeamsWithoutWO.count - tournament.teamCount)
//                FooterButtonView("\(waiting.formatted()) équipes en attente\(waiting.pluralSuffix)") {
//                    filterMode = .waiting
//                }
//                .disabled(filterMode == .waiting)
//                
//                Divider()
//                
//                let wo = walkoutTeams.count
//                FooterButtonView("\(wo.formatted()) équipes forfait\(wo.pluralSuffix)") {
//                    filterMode = .walkOut
//                }
//                .disabled(filterMode == .walkOut)
//            }
//            .fixedSize(horizontal: true, vertical: true)
//            
//            NavigationLink {
//                InscriptionInfoView()
//                    .environment(tournament)
//            } label: {
//                LabeledContent {
//                    if let registrationIssues {
//                        Text(registrationIssues.formatted())
//                    } else {
//                        ProgressView()
//                    }
//                } label: {
//                    Text("Problèmes détéctés")
//                }
//            }
//        } header: {
//            Text("Statut des inscriptions")
//        } footer: {
//            HStack {
//                Menu {
//                    _managementView()
//                } label: {
//                    Text("Complétez votre liste")
//                }
//                Text("ou")
//                
//                FooterButtonView("Importez un fichier") {
//                    presentImportView = true
//                }
//            }
////            if filterMode != .all {
////                FooterButtonView("tout afficher") {
////                    filterMode = .all
////                }
////            }
//        }
//        .headerProminence(.increased)
//    }
    
    @ViewBuilder
    private func _relatedTips() -> some View {
//        if tournament.inscriptionClosed() && tournament.tournamentLevel.shouldShareTeams() {
//            Section {
//                TipView(teamsExportTip)
//                    .tipStyle(tint: nil)
//            }
//        }
//        if tournament.unsortedTeams().count >= tournament.teamCount
//            && tournament.unsortedPlayers().filter({ $0.source == .beachPadel }).isEmpty {
//            Section {
//                TipView(padelBeachExportTip) { action in
//                    if action.id == "more-info-export" {
//                        isLearningMore = true
//                    }
//                    if action.id == "padel-beach" {
//                        UIApplication.shared.open(URLs.beachPadel.url)
//                    }
//                }
//                .tipStyle(tint: nil)
//            }
//            Section {
//                TipView(padelBeachImportTip) { action in
//                    if action.id == "more-info-import" {
//                        presentImportView = true
//                    }
//                }
//                .tipStyle(tint: nil)
//            }
//        }
//        
        
        if tournament.tournamentCategory == .men && unsortedPlayers.filter({ $0.isMalePlayer() == false }).isEmpty == false {
            Section {
                TipView(inscriptionManagerWomanRankTip)
                    .tipStyle(tint: nil)
            }
        }
//        
//        Section {
//            TipView(slideToDeleteTip)
//                .tipStyle(tint: nil)
//        }
    }
    
    private func _searchSource() -> String? {
        selectionSearchField
    }
    
    @ViewBuilder
    private func _sortingTypePickerView() -> some View {
        @Bindable var tournament = tournament
        Picker(selection: $tournament.teamSorting) {
            ForEach(TeamSortingType.allCases) {
                Text($0.localizedLabel()).tag($0)
            }
        } label: {
        }
    }
    
    @ViewBuilder
    private func _prioritizeClubMembersButton() -> some View {
        @Bindable var tournament = tournament
        if let federalClub = tournament.club() {
            Menu {
                Picker(selection: $tournament.prioritizeClubMembers) {
                    Text("Oui").tag(true)
                    Text("Non").tag(false)
                } label: {
                    
                }
                .labelsHidden()
                
                Divider()
                NavigationLink {
                    ClubsView() { club in
                        if let event = tournament.eventObject() {
                            event.club = club.id
                            do {
                                try dataStore.events.addOrUpdate(instance: event)
                            } catch {
                                Logger.error(error)
                            }
                        }
                        _save()
                    }
                } label: {
                    Text("Changer de club")
                }
            } label: {
                Text("Membres prioritaires")
                Text(federalClub.acronym)
            }
            Divider()
        } else {
            NavigationLink {
                ClubsView() { club in
                    if let event = tournament.eventObject() {
                        event.club = club.id
                        do {
                            try dataStore.events.addOrUpdate(instance: event)
                        } catch {
                            Logger.error(error)
                        }
                    }
                    _save()
                }
            } label: {
                Text("Identifier le club")
            }
            Divider()
        }
    }
    
    private func _teamFooterView(_ team: TeamRegistration) -> some View {
        HStack {
            if let formattedRegistrationDate = team.formattedInscriptionDate() {
                Text(formattedRegistrationDate)
            }
            Spacer()
            NavigationLink {
                EditingTeamView(team: team)
                    .environment(tournament)
            } label: {
                LabelOptions().labelStyle(.titleOnly)
            }
        }
    }
    
    private func _teamDeleteButtonView(_ team: TeamRegistration) -> some View {
        Button(role: .destructive) {
            team.deleteTeamScores()
            do {
                try tournamentStore.teamRegistrations.delete(instance: team)
            } catch {
                Logger.error(error)
            }
            _setHash()
        } label: {
            LabelDelete()
        }
    }
    
    private func _save() {
        do {
            try dataStore.tournaments.addOrUpdate(instance: tournament)
        } catch {
            Logger.error(error)
        }
    }
    
    private var _networkErrorMessage: String {
        var errors: [String] = []
        
        if networkMonitor.connected == false {
            errors.append("L'appareil n'est pas connecté à internet.")
        }
        if sentError == .mailNotSent {
            errors.append("Le mail est dans la boîte d'envoi de l'app Mail. Vérifiez son état dans l'app Mail avant d'essayer de le renvoyer.")
        }
        if (sentError == .messageFailed || sentError == .messageNotSent) {
            errors.append("Le SMS n'a pas été envoyé")
        }
        if sentError == .mailFailed {
            errors.append("Le mail n'a pas été envoyé")
        }
        return errors.joined(separator: "\n")
    }

}

//#Preview {
//    NavigationStack {
//        InscriptionManagerView(tournament: Tournament.mock())
//            .environment(Tournament.mock())
//    }
//}
