//
//  TeamsCallingView.swift
//  PadelClub
//
//  Created by razmig on 10/07/2024.
//

import SwiftUI
import LeStorage

struct TeamsCallingView: View {
    @Environment(Tournament.self) var tournament: Tournament
    @EnvironmentObject var dataStore: DataStore
    let teams : [TeamRegistration]
    
    @State private var hideConfirmed: Bool = false
    @State private var hideGoodSummoned: Bool = false
    @State private var hideSummoned: Bool = false
    @State private var searchText: String = ""

    var filteredTeams: [TeamRegistration] {
        teams
            .filter({ hideConfirmed == false || $0.confirmed() == false })
            .filter({ hideSummoned == false || $0.called() == false })
            .filter({ hideGoodSummoned == false || tournament.isStartDateIsDifferentThanCallDate($0) == true })
            .filter({ searchText.isEmpty || $0.contains(searchText) })
    }
    
    var anyFilterEnabled: Bool {
        hideConfirmed || hideGoodSummoned || hideSummoned
    }
    
    var body: some View {
        List {
            if tournament.isPrivate {
                Section {
                    RowButtonView("Rendre visible sur Padel Club") {
                        tournament.isPrivate = false
                        do {
                            try dataStore.tournaments.addOrUpdate(instance: tournament)
                        } catch {
                            Logger.error(error)
                        }
                    }
                } footer: {
                    Text("Si vous convoquez un tournoi privée, les joueurs n'auront pas le lien pour suivre le tournoi.")
                        .foregroundStyle(.logoRed)
                }
            }

            
            PlayersWithoutContactView(players: teams.flatMap({ $0.unsortedPlayers() }).sorted(by: \.computedRank))

            let called = teams.filter { tournament.isStartDateIsDifferentThanCallDate($0) == false }
            let confirmed = teams.filter { $0.confirmed() }
            let justCalled = teams.filter { $0.called() }

            let label = "\(justCalled.count.formatted()) / \(teams.count.formatted())"
            let subtitle = "dont \(called.count.formatted()) au bon horaire"
            let confirmedLabel = "\(confirmed.count.formatted()) / \(teams.count.formatted())"

            if teams.isEmpty == false, searchText.isEmpty {
                Section {
                    LabeledContent {
                        Text(label).font(.title3)
                    } label: {
                        Text("Paire\(justCalled.count.pluralSuffix) convoquée\(justCalled.count.pluralSuffix)")
                        Text(subtitle)
                    }
                    LabeledContent {
                        Text(confirmedLabel).font(.title3)
                    } label: {
                        Text("Paire\(confirmed.count.pluralSuffix) confirmée\(confirmed.count.pluralSuffix)")
                    }
                } footer: {
                    Text("Vous pouvez filtrer cette liste en appuyant sur ") + Text(Image(systemName: "line.3.horizontal.decrease.circle"))
                }
            }
            
            if filteredTeams.isEmpty == false {
                Section {
                    ForEach(filteredTeams) { team in
                        TeamCallView(team: team) {
                            searchText = ""
                        }
                    }
                } header: {
                    HStack {
                        Text("Paire\(filteredTeams.count.pluralSuffix)")
                        Spacer()
                        Text(filteredTeams.count.formatted())
                    }
                } footer: {
                    CallView(teams: filteredTeams)
                }
            } else {
                ContentUnavailableView("Aucune équipe", systemImage: "person.2.slash")
            }
        }
        .toolbar(content: {
            ToolbarItem(placement: .topBarTrailing) {
                Menu {
                    Toggle(isOn: $hideConfirmed) {
                        Text("Masquer les confirmées")
                    }
                    Toggle(isOn: $hideSummoned) {
                        Text("Masquer les convoquées")
                    }
                    Toggle(isOn: $hideGoodSummoned) {
                        Text("Masquer les convoquées à la bonne heure")
                    }
                } label: {
                    LabelFilter()
                        .symbolVariant(anyFilterEnabled ? .fill : .none)
                }
            }
        })
        .searchable(text: $searchText, placement: .navigationBarDrawer(displayMode: .always))
        .headerProminence(.increased)
        .navigationTitle("Statut des convocations")
        .navigationBarTitleDisplayMode(.inline)
        .toolbarBackground(.visible, for: .navigationBar)
    }
}

struct CallMenuOptionsView: View {
    @Environment(\.dismiss) private var dismiss
    @Environment(Tournament.self) var tournament: Tournament
    let team: TeamRegistration
    let action: (() -> Void)?
    
    var confirmed: Binding<Bool> {
        Binding {
            team.confirmed()
        } set: { _ in
            team.toggleSummonConfirmation()
            do {
                try self.tournament.tournamentStore?.teamRegistrations.addOrUpdate(instance: team)
            } catch {
                Logger.error(error)
            }
            action?()
        }
    }
    
    var body: some View {
        List {
            Section {
                TeamRowView(team: team, displayCallDate: true)
                Toggle(isOn: confirmed) {
                    Text("Confirmation reçue")
                }
                if team.expectedSummonDate() != nil {
                    CallView(team: team, displayContext: .menu)
                }
            } footer: {
                CallView(teams: [team])
            }
            
            Section {
                NavigationLink {
                    EditingTeamView(team: team)
                        .environment(tournament)
                } label: {
                    Text("Détails de l'équipe")
                }
            }
            
            Section {
                RowButtonView("Effacer la date de convocation", role: .destructive) {
                    team.callDate = nil
                    do {
                        try self.tournament.tournamentStore?.teamRegistrations.addOrUpdate(instance: team)
                    } catch {
                        Logger.error(error)
                    }
                    action?()
                    dismiss()
                }
            }
            
            Section {
                RowButtonView("Indiquer comme convoquée", role: .destructive) {
                    team.callDate = team.initialMatch()?.startDate ?? tournament.startDate
                    do {
                        try self.tournament.tournamentStore?.teamRegistrations.addOrUpdate(instance: team)
                    } catch {
                        Logger.error(error)
                    }
                    action?()
                    dismiss()
                }
            }
        }
        .navigationTitle("Options de convocation")
        .navigationBarTitleDisplayMode(.inline)
        .toolbarBackground(.visible, for: .navigationBar)
    }
}
