//
//  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
    @Environment(NavigationViewModel.self) var navigation: NavigationViewModel

    @Environment(\.dismiss) var dismiss

    @Bindable 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 confirmDuplicate: Bool = false
    @State private var presentAddTeamView: Bool = false
    @State private var compactMode: Bool = true
    @State private var pasteString: String?
    @State private var registrationIssues: Int? = nil
    @State private var refreshResult: String? = nil
    @State private var refreshStatus: Bool?
    @State private var showLegendView: Bool = false
    
    var tournamentStore: TournamentStore? {
        return self.tournament.tournamentStore
    }
    
    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 registeredLocally
        case registeredOnline
        case walkOut
        case waiting
        case bracket
        case groupStage
        case wildcardGroupStage
        case wildcardBracket
        case notImported
        
        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 .registeredOnline:
                return "Aucune équipe inscrite en ligne."
            case .registeredLocally:
                return "Aucune équipe inscrite par vous-même."
            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."
            case .notImported:
                return "Vous n'avez aucune équipe non importé. Elles proviennent toutes du fichier."
            }
        }

        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 .registeredLocally:
                return "Aucune équipe inscrite par vous-même"
            case .registeredOnline:
                return "Aucune équipe inscrite en ligne"
            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"
            case .notImported:
                return "Aucune équipe non importée"
            }
        }

        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 .registeredLocally:
                return displayStyle == .wide ? "Inscrites par vous-même" : "par vous-même"
            case .registeredOnline:
                return displayStyle == .wide ? "Inscrites en ligne" : "en ligne"
            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"
            case .notImported:
                return "Non importées"
            }
        }
    }


    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(currentSelectedSortedTeams: [TeamRegistration]? = nil) {
        #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 = currentSelectedSortedTeams == nil ? tournament.selectedSortedTeams() : currentSelectedSortedTeams!
        if self.teamsHash == nil, selectedSortedTeams.isEmpty == false {
            self.teamsHash = _simpleHash(ids: selectedSortedTeams.map { $0.id })
        }
        self.registrationIssues = nil
        Task {
            self.registrationIssues = await tournament.registrationIssues(selectedTeams: selectedSortedTeams)
        }
    }
    
    private func _handleHashDiff(selectedSortedTeams: [TeamRegistration]) {
        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 {
        let selectedSortedTeams = tournament.selectedSortedTeams()
        return Group {
            if tournament.unsortedTeamsCount() > 0 {
                _teamRegisteredView(selectedSortedTeams: selectedSortedTeams)
            } 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
                        }

                        RowButtonView("Importer un fichier") {
                            presentImportView = true
                        }
                        
                        if tournament.enableOnlineRegistration {
                            RowButtonView("Rafraîchir la liste", cornerRadius: 20) {
                                await _refreshList(forced: true)
                            }
                        } else if tournament.onlineRegistrationCanBeEnabled() {
                            RowButtonView("Inscription en ligne") {
                                navigation.path.append(Screen.settings)
                            }
                        }
                        
                        _importTeamsMenuView(title: "Importer des paires d'un autre tournoi")
                    }
                }
            }
        }
        .task(priority: .background) {
            await _refreshList(forced: false)
        }
        .refreshable {
            await _refreshList(forced: true)
        }
        .onAppear {
            if tournament.enableOnlineRegistration == false || refreshStatus == true {
                _setHash(currentSelectedSortedTeams: selectedSortedTeams)
            }
        }
        .onDisappear {
            _handleHashDiff(selectedSortedTeams: selectedSortedTeams)
        }
        .sheet(isPresented: $isLearningMore) {
            LearnMoreSheetView(tournament: tournament)
                .tint(.master)
        }
        .sheet(isPresented: $presentImportView, onDismiss: {
            _setHash()
            currentRankSourceDate = tournament.rankSourceDate
        }) {
            NavigationStack {
                FileImportView(defaultFileProvider: tournament.isAnimation() ? .custom : .frenchFederation)
            }
            .tint(.master)
        }
        .onChange(of: tournament.prioritizeClubMembers) {
            _save()
            _setHash()
        }
        .onChange(of: tournament.teamSorting) {
            _save()
            _setHash()
        }
        .onChange(of: currentRankSourceDate) {
            if let currentRankSourceDate, tournament.rankSourceDate != currentRankSourceDate, unsortedPlayers.isEmpty == false {
                confirmUpdateRank = true
            } else {
                tournament.rankSourceDate = currentRankSourceDate
                _save()
            }
        }
        .sheet(isPresented: $confirmUpdateRank, onDismiss: {
            currentRankSourceDate = tournament.rankSourceDate
        }) {
            UpdateSourceRankDateView(currentRankSourceDate: $currentRankSourceDate, confirmUpdateRank: $confirmUpdateRank, tournament: tournament)
                .tint(.master)
        }
        .fullScreenCover(isPresented: $presentAddTeamView, onDismiss: {
            _setHash()
        }) {
            NavigationStack {
                AddTeamView(tournament: tournament)
            }
            .tint(.master)
        }
        .fullScreenCover(item: $editedTeam, onDismiss: {
            _setHash()
        }) { editedTeam in
            NavigationStack {
                AddTeamView(tournament: tournament, editedTeam: editedTeam)
            }
            .tint(.master)
        }
        .fullScreenCover(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")
                        }
                        
                    }

                    if tournament.isAnimation() == false {
                        if tournament.inscriptionClosed() == false {
                            Divider()

                            Section {
                                Button("+1 en tableau") {
                                    tournament.addWildCard(1, .bracket)
                                    _setHash()
                                }
                                
                                if tournament.groupStageCount > 0 {
                                    Button("+1 en poules") {
                                        tournament.addWildCard(1, .groupStage)
                                        _setHash()
                                    }
                                }
                            } header: {
                                Text("Ajout de wildcards")
                            }
                            
                            Button("Bloquer une place") {
                                tournament.addEmptyTeamRegistration(1)
                                _setHash()
                            }

                            Divider()

                            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")
                            }

                            Divider()
                            _importTeamsMenuView(title: "Importer des paires")
                            _sharingTeamsMenuView()
                        } else {
                            
                            _sharingTeamsMenuView()
                            
                            Divider()
                            
                            Button {
                                tournament.unlockRegistration()
                                _save()
                            } label: {
                                Label("Ré-ouvrir", systemImage: "lock.open")
                            }
                        }
                    } else {
                        Button("Bloquer une place") {
                            tournament.addEmptyTeamRegistration(1)
                        }

                        Toggle(isOn: $tournament.hideTeamsWeight) {
                            Text("Masquer les poids des équipes")
                        }
                        
                        //rankingDateSourcePickerView(showDateInLabel: true)

                        Divider()

                        _sharingTeamsMenuView()
                        
                        Divider()

                        _importTeamsMenuView(title: "Importer des paires")
                        
                        Button {
                            presentImportView = true
                        } label: {
                            Label("Importer un fichier", systemImage: "square.and.arrow.down")
                        }
                    }
                } label: {
                    if tournament.inscriptionClosed() == false {
                        LabelOptions()
                    } else {
                        Label("Clôturé", systemImage: "lock")
                    }
                }
            }
        }
        .toolbarBackground(.visible, for: .navigationBar)
        .navigationTitle("Inscriptions")
        .navigationBarTitleDisplayMode(.inline)
        .onChange(of: tournament.hideTeamsWeight) {
            _save()
        }
    }
    
    private func _sharingTeamsMenuView() -> some View {
        Menu {
            ShareLink(item: teamPaste(), preview: .init("Inscriptions")) {
                Text("En texte")
            }
            ShareLink(item: teamPaste(.csv), preview: .init("Inscriptions")) {
                Text("En csv")
            }
        } label: {
            Label("Exporter les paires", systemImage: "square.and.arrow.up")
        }
    }
    
    private func _importTeamsMenuView(title: String) -> some View {
        NavigationLink {
            ConsolationTournamentImportView()
                .environment(tournament)
        } label: {
            Label(title, systemImage: "square.and.arrow.down")
        }
    }
    
    var walkoutTeams: [TeamRegistration] {
        tournament.walkoutTeams()
    }
    
    var unsortedTeamsWithoutWO: [TeamRegistration] {
        tournament.unsortedTeamsWithoutWO()
    }
    
    func teamPaste(_ exportFormat: ExportFormat = .rawText) -> TournamentShareFile {
        TournamentShareFile(tournament: tournament, exportFormat: exportFormat)
    }

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

    func sortedTeams(selectedSortedTeams: [TeamRegistration]) -> [TeamRegistration] {
        if filterMode == .waiting {
            return tournament.waitingListSortedTeams(selectedSortedTeams: selectedSortedTeams)
        } else {
            return tournament.sortedTeams(selectedSortedTeams: selectedSortedTeams)
        }
    }

    func filteredTeams(sortedTeams: [TeamRegistration]) -> [TeamRegistration] {
        let filtered = sortedTeams.lazy.filter { team in
            switch filterMode {
            case .wildcardBracket:
                return team.wildCardBracket
            case .wildcardGroupStage:
                return team.wildCardGroupStage
            case .walkOut:
                return team.walkOut
            case .bracket:
                return team.inRound() && !team.inGroupStage()
            case .groupStage:
                return team.inGroupStage()
            case .notImported:
                return !team.isImported()
            case .registeredLocally:
                return !team.hasRegisteredOnline()
            case .registeredOnline:
                return team.hasRegisteredOnline()
            default:
                return true
            }
        }
        
        let sorted = sortingMode == .registrationDate
            ? filtered.sorted(by: { $0.computedRegistrationDate < $1.computedRegistrationDate })
            : Array(filtered)
        
        return byDecreasingOrdering ? sorted.reversed() : sorted
    }
    
//    private func _fixModel() {
//        let players = tournament.players()
//        
//        players.forEach { player in
//            if player.source == .onlineRegistration {
//                player.source = .frenchFederation
//                player.registeredOnline = true
//            }
//        }
//        
//        try? tournamentStore.playerRegistrations.addOrUpdate(contentOfs: players)
//    }
//    
    private func _refreshList(forced: Bool) async {
        if refreshStatus == true, forced == false { return }
        if tournament.enableOnlineRegistration == false { return }
        if tournament.hasEnded() { return }
        if tournament.refreshInProgress { return }
        
        refreshResult = nil
        refreshStatus = nil
        do {
            await self.tournament.refreshTeamList(forced: forced)
            
            _setHash()
            if let lastTeamRefresh = self.tournament.lastTeamRefresh?.formatted(date: .abbreviated, time: .shortened) {
                self.refreshResult = "Dernière m-à-j : \(lastTeamRefresh)"
            } else {
                self.refreshResult = "La synchronization a réussi"
            }
            self.refreshStatus = true

        } catch {
            Logger.error(error)
            self.refreshResult = "La synchronization a échoué"
            self.refreshStatus = false
        }
    }
    
    private func _teamRegisteredView(selectedSortedTeams: [TeamRegistration]) -> some View {
        List {
            if presentSearch == false {
                _informationView(for: selectedSortedTeams)
                
                if tournament.isAnimation() == false {
                    _rankHandlerView()
                    _relatedTips()
                }
            }
            
            let sortedTeams = sortedTeams(selectedSortedTeams: selectedSortedTeams)
            let teams = searchField.isEmpty ? filteredTeams(sortedTeams: sortedTeams) : filteredTeams(sortedTeams: sortedTeams).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
                    }
                }
            }
            
            let isImported = teams.anySatisfy({ $0.isImported() })

            if teams.isEmpty == false {
                if compactMode {
                    Section {
                        ForEach(teams) { team in
                            let teamIndex = team.index(in: sortedTeams)
                            let color: Color? = isImported ? (team.unrankedOrUnknown() ? .logoRed : (team.isImported() == false ? .beigeNotUniversal : nil)) : nil
                            
                            NavigationLink {
                                EditingTeamView(team: team)
                                    .environment(tournament)
                            } label: {
                                TeamRowView(team: team, teamIndex: teamIndex)
                            }
                            .swipeActions(edge: .trailing, allowsFullSwipe: true) {
                                if tournament.enableOnlineRegistration == false {
                                    _teamDeleteButtonView(team)
                                }
                            }
                            .listRowView(isActive: true, color: team.initialRoundColor() ?? tournament.cutLabelColor(index: teamIndex, teamCount: filterMode == .waiting ? 0 : selectedSortedTeams.count), hideColorVariation: true, backgroundColor: color, alignment: .leading)
                        }
                    } 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)")
                        }
                    } footer: {
                        FooterButtonView("Légende des codes couleurs") {
                            showLegendView = true
                        }
                    }
                    .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
                    }
                }
            }
        }
        .id(refreshStatus)
        .searchable(text: $searchField, isPresented: $presentSearch, prompt: Text("Chercher parmi les équipes inscrites"))
        .keyboardType(.alphabet)
        .autocorrectionDisabled()
        .sheet(isPresented: $showLegendView) {
            InscriptionLegendView()
        }
    }

    @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 = tournament.rankSourceShouldBeRefreshed() {
            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, in teams: [TeamRegistration]) -> String {
        switch filterMode {
        case .wildcardBracket:
            return teams.filter({ $0.wildCardBracket }).count.formatted()
        case .wildcardGroupStage:
            return teams.filter({ $0.wildCardGroupStage }).count.formatted()
        case .all:
            return unsortedTeamsWithoutWO.count.formatted()
        case .bracket:
            return teams.filter({ $0.inRound() && $0.inGroupStage() == false }).count.formatted()
        case .groupStage:
            return teams.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()
        case .notImported:
            let notImported: Int = max(0, sortedTeams(selectedSortedTeams: teams).filter({ $0.isImported() == false }).count)
            return notImported.formatted()
        case .registeredLocally:
            let registeredLocally: Int = max(0, sortedTeams(selectedSortedTeams: teams).filter({ $0.hasRegisteredOnline() == false }).count)
            return registeredLocally.formatted()
        case .registeredOnline:
            let registeredOnline: Int = max(0, sortedTeams(selectedSortedTeams: teams).filter({ $0.hasRegisteredOnline() }).count)
            return registeredOnline.formatted()

        }
    }
    
    @ViewBuilder
    private func _informationView(for teams: [TeamRegistration]) -> 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, in: teams)
                }

                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, in: teams)
                }
            }
            .padding(.bottom, -4)
            .fixedSize(horizontal: false, vertical: false)
            .listRowSeparator(.hidden)

            if tournament.isAnimation() == false {
                NavigationLink {
                    InscriptionInfoView(tournament: tournament)
                        .environment(tournament)
                } label: {
                    LabeledContent {
                        if let registrationIssues {
                            Text(registrationIssues.formatted())
                                .foregroundStyle(.logoRed)
                                .fontWeight(.bold)
                        } else {
                            ProgressView()
                        }
                    } label: {
                        Text("Problèmes détectés")
                    }
                }
            }
            
            if let closedRegistrationDate = tournament.closedRegistrationDate {
                CloseDatePicker(closedRegistrationDate: closedRegistrationDate)
            }
            
//            Button("bug fix") {
//                _fixModel()
//            }
            
            if tournament.enableOnlineRegistration {
                LabeledContent {
                    Text(tournament.unsortedTeams().filter({ $0.hasRegisteredOnline() }).count.formatted())
                        .font(.largeTitle)
                } label: {
                    Text("Inscriptions en ligne")
                    if let refreshResult {
                        Text(refreshResult).foregroundStyle(.secondary)
                    } else {
                        Text(" ")
                    }
                }

                RowButtonView("Rafraîchir les inscriptions en ligne") {
                    await _refreshList(forced: true)
                }
            }
        } 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, in teams: [TeamRegistration]) -> 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, in: teams)).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)
        }
    }
}

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

struct TournamentRoundShareContent: Transferable {
    let tournament: Tournament
    
    func shareContent() -> String {
        print("Generating URL...")
        let content = tournament.rounds().compactMap { $0.pasteData() }.joined(separator: "\n\n")
        return content
    }
    
    static var transferRepresentation: some TransferRepresentation {
        ProxyRepresentation { transferable in
            return transferable.shareContent()
        }
    }
}

struct TournamentGroupStageShareContent: Transferable {
    let tournament: Tournament
    
    func shareContent() -> String {
        print("Generating URL...")
        let content = tournament.groupStages().compactMap { $0.pasteData() }.joined(separator: "\n\n")
        return content
    }
    
    static var transferRepresentation: some TransferRepresentation {
        ProxyRepresentation { transferable in
            return transferable.shareContent()
        }
    }
}

struct TournamentShareFile: Transferable {
    let tournament: Tournament
    let exportFormat: ExportFormat
    
    func shareFile() -> URL {
        print("Generating URL...")
       return  tournament.pasteDataForImporting(exportFormat).createFile(self.tournament.tournamentTitle()+"-inscriptions", exportFormat)
    }
    
    static var transferRepresentation: some TransferRepresentation {
        FileRepresentation(exportedContentType: .utf8PlainText) { transferable in
            return SentTransferredFile(transferable.shareFile())
        }
        
        ProxyRepresentation { transferable in
            return transferable.shareFile()
        }
    }
}
