//
//  RegistrationSetupView.swift
//  PadelClub
//
//  Created by razmig on 20/11/2024.
//

import SwiftUI
import LeStorage

struct RegistrationSetupView: View {
    @EnvironmentObject var dataStore: DataStore
    @Bindable var tournament: Tournament
    @State private var enableOnlineRegistration: Bool
    @State private var registrationDateLimit: Date
    @State private var openingRegistrationDate: Date
    @State private var targetTeamCount: Int
    @State private var waitingListLimit: Int
    @State private var registrationDateLimitEnabled: Bool
    @State private var teamCountLimit: Bool
    @State private var waitingListLimitEnabled: Bool
    @State private var openingRegistrationDateEnabled: Bool
    @State private var userAccountIsRequired: Bool
    @State private var licenseIsRequired: Bool
    @State private var minPlayerPerTeam: Int
    @State private var maxPlayerPerTeam: Int
    @State private var showMoreInfos: Bool = false

    @State private var hasChanges: Bool = false

    @Environment(\.dismiss) private var dismiss

    init(tournament: Tournament) {
        self.tournament = tournament
        _enableOnlineRegistration = .init(wrappedValue: tournament.enableOnlineRegistration)

        // Registration Date Limit
        if let registrationDateLimit = tournament.registrationDateLimit {
            _registrationDateLimit = .init(wrappedValue: registrationDateLimit)
            _registrationDateLimitEnabled = .init(wrappedValue: true)
        } else {
            _registrationDateLimit = .init(wrappedValue: tournament.startDate.truncateMinutesAndSeconds())
            _registrationDateLimitEnabled = .init(wrappedValue: false)
        }
        
        // Opening Registration Date
        if let openingRegistrationDate = tournament.openingRegistrationDate {
            _openingRegistrationDate = .init(wrappedValue: openingRegistrationDate)
            _openingRegistrationDateEnabled = .init(wrappedValue: true)
        } else {
            _openingRegistrationDate = .init(wrappedValue: tournament.creationDate.truncateMinutesAndSeconds())
            _openingRegistrationDateEnabled = .init(wrappedValue: false)
        }

        // Target Team Count
        _targetTeamCount = .init(wrappedValue: tournament.teamCount) // Default value
        _teamCountLimit = .init(wrappedValue: tournament.teamCountLimit)

        // Waiting List Limit
        if let waitingListLimit = tournament.waitingListLimit {
            _waitingListLimit = .init(wrappedValue: waitingListLimit)
            _waitingListLimitEnabled = .init(wrappedValue: true)
        } else {
            _waitingListLimit = .init(wrappedValue: 0) // Default value
            _waitingListLimitEnabled = .init(wrappedValue: false)
        }
        
        _userAccountIsRequired = .init(wrappedValue: tournament.accountIsRequired)
        _licenseIsRequired = .init(wrappedValue: tournament.licenseIsRequired)
        _maxPlayerPerTeam = .init(wrappedValue: tournament.maximumPlayerPerTeam)
        _minPlayerPerTeam = .init(wrappedValue: tournament.minimumPlayerPerTeam)

    }
    
    func displayWarning() -> Bool {
        let unsortedTeamsCount = tournament.unsortedTeamsCount()
        return tournament.shouldWarnOnlineRegistrationUpdates() && targetTeamCount != tournament.teamCount && (tournament.teamCount <= unsortedTeamsCount || targetTeamCount <= unsortedTeamsCount)
    }
    
    var body: some View {
        List {
            Section {
                Toggle(isOn: $enableOnlineRegistration) {
                    Text("Activer")
                }
            } footer: {
                VStack(alignment: .leading) {
                    Text("Les inscriptions en ligne permettent à des joueurs de s'inscrire à votre tournoi en passant par le site Padel Club. Vous verrez alors votre liste d'inscription s'agrandir dans la vue Gestion des Inscriptions de l'application.")
                    
                    FooterButtonView("En savoir plus") {
                        self.showMoreInfos = true

                    }
                }
            }
            
            if enableOnlineRegistration {
                if let shareURL = tournament.shareURL(.info) {
                    Section {
                        Link(destination: shareURL) {
                            Text(shareURL.absoluteString)
                        }
                    } header: {
                        Text("Page d'inscription")
                    } footer: {
                        HStack {
                            CopyPasteButtonView(pasteValue: shareURL.absoluteString)
                            Spacer()
                            ShareLink(item: shareURL) {
                                Label("Partager", systemImage: "square.and.arrow.up")
                            }
                        }
                    }
                }
                
                Section {
                    Toggle(isOn: $openingRegistrationDateEnabled) {
                        Text("Définir une date")
                    }
                    
                    if openingRegistrationDateEnabled {
                        DatePicker(selection: $openingRegistrationDate) {
                            DateMenuView(date: $openingRegistrationDate)
                        }
                    }
                } header: {
                    Text("Date d'ouverture des inscriptions")
                } footer: {
                    Text("Activez et définissez une date d'ouverture pour les inscriptions au tournoi. Les inscriptions en ligne ne seront possible qu'à partir de cette date.")
                }
                
                Section {
                    Toggle(isOn: $registrationDateLimitEnabled) {
                        Text("Définir une date")
                    }
                    
                    if registrationDateLimitEnabled {
                        DatePicker(selection: $registrationDateLimit) {
                            DateMenuView(date: $registrationDateLimit)
                        }
                    }
                } header: {
                    Text("Date de fermeture des inscriptions")
                } footer: {
                    Text("Si une date de fermeture des inscriptions en ligne est définie, alors plus aucune inscription ne sera possible après cette date. Sinon, la date du début du tournoi ou la date de clôture des inscriptions seront utilisées.")
                }
                
                Section {
                    if displayWarning() {
                        Text("Attention, l'inscription en ligne est activée et vous avez des équipes inscrites en ligne, en modifiant la structure ces équipes seront intégrées ou retirées de votre sélection d'équipes. Padel Club saura prévenir les équipes inscrites en ligne automatiquement.")
                            .foregroundStyle(.logoRed)
                    }


                    Toggle(isOn: $teamCountLimit) {
                        Text("Activer une limite")
                    }
                    
                    if teamCountLimit {
                        StepperView(count: $targetTeamCount, minimum: 4)
                    }
              } header: {
                    Text("Paires admises")
                } footer: {
                    Text("Les inscriptions seront indiquées en attente pour les joueurs au-délà de cette limite dans le cas où aucune limite de liste d'attente n'est active ou non atteinte. Dans le cas contraire, plus aucune inscription ne seront possibles.")
                }
                
                Section {
                    Toggle(isOn: $waitingListLimitEnabled) {
                        Text("Activer une limite")
                    }
                    
                    if waitingListLimitEnabled {
                        StepperView(count: $waitingListLimit, minimum: 0)
                    }
                } header: {
                    Text("Liste d'attente")
                } footer: {
                    Text("Si une limite à la liste d'attente existe, les inscriptions ne seront plus possibles une fois la liste d'attente pleine. Si aucune limite de liste d'attente n'est active, alors les inscriptions seront toujours possibles. Les joueurs auront une indication comme quoi ils sont en liste d'attente.")
                }
                
                if tournament.isAnimation() {
                    Section {
//                        Toggle(isOn: $userAccountIsRequired) {
//                            Text("Compte Padel Club requis pour s'inscrire")
//                        }
//                        .disabled(true)

                        Toggle(isOn: $licenseIsRequired) {
                            Text("Licence FFT requise pour s'inscrire")
                        }

                        LabeledContent {
                            StepperView(count: $minPlayerPerTeam, minimum: 1, maximum: maxPlayerPerTeam)
                        } label: {
                            Text("Nombre minimum de joueurs possible")
                        }
                        LabeledContent {
                            StepperView(count: $maxPlayerPerTeam, minimum: minPlayerPerTeam)
                        } label: {
                            Text("Nombre maximum de joueurs possible")
                        }
                    }
                }
            } else {
                ContentUnavailableView(
                    "Activez les inscriptions en ligne",
                    systemImage: "person.2.crop.square.stack.fill",
                    description: Text("Permettez aux joueurs de s'inscrire eux-mêmes à ce tournoi. Les équipes inscrites apparaîtront automatiquement dans la liste de l'arbitre. L'inscription en ligne requiert un email de contact et une licence FFT.")
                )
            }
        }
        .sheet(isPresented: $showMoreInfos) {
            RegistrationInfoSheetView()
        }
        .toolbar(content: {
            if hasChanges {
                ToolbarItem(placement: .topBarLeading) {
                    Button("Annuler", role: .cancel) {
                        dismiss()
                    }
                }

                ToolbarItem(placement: .topBarTrailing) {
                    ButtonValidateView(role: .destructive) {
                        _save()
                        dismiss()
                    }
                }
            }
        })
        .toolbarRole(.editor)
        .headerProminence(.increased)
        .navigationTitle("Inscription en ligne")
        .navigationBarTitleDisplayMode(.inline)
        .toolbarBackground(.visible, for: .navigationBar)
        .navigationBarBackButtonHidden(hasChanges)
        .onChange(of: enableOnlineRegistration, {
            _hasChanged()
        })
        .onChange(of: openingRegistrationDateEnabled) {
            _hasChanged()
        }

        .onChange(of: openingRegistrationDate) {
            _hasChanged()
        }

        .onChange(of: registrationDateLimitEnabled) {
            _hasChanged()
        }

        .onChange(of: registrationDateLimit) {
            _hasChanged()
        }

        .onChange(of: teamCountLimit) {
            _hasChanged()
        }

        .onChange(of: targetTeamCount) {
            _hasChanged()
        }

        .onChange(of: waitingListLimitEnabled) {
            _hasChanged()
        }

        .onChange(of: waitingListLimit) {
            _hasChanged()
        }
        
        .onChange(of: [minPlayerPerTeam, maxPlayerPerTeam]) {
            _hasChanged()
        }
        .onChange(of: [userAccountIsRequired, licenseIsRequired]) {
            _hasChanged()
        }
    }
    
    private func _hasChanged() {
        hasChanges = true
    }
    
    private func _save() {
        hasChanges = false
        
        tournament.enableOnlineRegistration = enableOnlineRegistration
        
        if enableOnlineRegistration {
            tournament.accountIsRequired = userAccountIsRequired
            tournament.licenseIsRequired = licenseIsRequired
            tournament.minimumPlayerPerTeam = minPlayerPerTeam
            tournament.maximumPlayerPerTeam = maxPlayerPerTeam
        } else {
            tournament.accountIsRequired = true
            tournament.licenseIsRequired = true
            tournament.minimumPlayerPerTeam = 2
            tournament.maximumPlayerPerTeam = 2
        }
        
        if openingRegistrationDateEnabled == false {
            tournament.openingRegistrationDate = nil
        } else {
            tournament.openingRegistrationDate = openingRegistrationDate
        }

        if registrationDateLimitEnabled == false {
            tournament.registrationDateLimit = nil
        } else {
            tournament.registrationDateLimit = registrationDateLimit
        }
        
        tournament.teamCountLimit = teamCountLimit
        tournament.teamCount = targetTeamCount

        if waitingListLimitEnabled == false {
            tournament.waitingListLimit = nil
        } else {
            tournament.waitingListLimit = waitingListLimit
        }

        do {
            try self.dataStore.tournaments.addOrUpdate(instance: tournament)
        } catch {
            Logger.error(error)
        }
        
        dismiss()
    }
}


enum OnlineRegistrationStatus: Int {
    case open = 1
    case notEnabled = 2
    case notStarted = 3
    case ended = 4
    case waitingListPossible = 5
    case waitingListFull = 6
    case inProgress = 7
    case endedWithResults = 8
    
    var displayName: String {
        switch self {
        case .open:
            return "Open"
        case .notEnabled:
            return "Not Enabled"
        case .notStarted:
            return "Not Started"
        case .ended:
            return "Ended"
        case .waitingListPossible:
            return "Waiting List Possible"
        case .waitingListFull:
            return "Waiting List Full"
        case .inProgress:
            return "In Progress"
        case .endedWithResults:
            return "Ended with Results"
        }
    }
    
    func statusLocalized() -> String {
        switch self {
        case .open:
            return "Inscription ouverte"
        case .notEnabled:
            return "Inscription désactivée"
        case .notStarted:
            return "Inscription pas encore ouverte"
        case .ended:
            return "Inscription terminée"
        case .waitingListPossible:
            return "Liste d'attente disponible"
        case .waitingListFull:
            return "Liste d'attente complète"
        case .inProgress:
            return "Tournoi en cours"
        case .endedWithResults:
            return "Tournoi terminé"
        }
    }
}
