//
//  TournamentGeneralSettingsView.swift
//  PadelClub
//
//  Created by Razmig Sarkissian on 18/04/2024.
//

import SwiftUI
import LeStorage

struct TournamentGeneralSettingsView: View {
    @EnvironmentObject var dataStore: DataStore
    
    @Bindable var tournament: Tournament
    @State private var tournamentName: String = ""
    @State private var tournamentInformation: String = ""
    @State private var entryFee: Double? = nil
    @State private var umpireCustomMail: String
    @State private var umpireCustomPhone: String
    @State private var umpireCustomContact: String
    @State private var umpireCustomMailIsInvalid: Bool = false
    @State private var umpireCustomPhoneIsInvalid: Bool = false

    @FocusState private var focusedField: Tournament.CodingKeys?
    let priceTags: [Double] = [15.0, 20.0, 25.0]
    
    init(tournament: Tournament) {
        self.tournament = tournament
        _tournamentName = State(wrappedValue: tournament.name ?? "")
        _tournamentInformation = State(wrappedValue: tournament.information ?? "")
        _entryFee = State(wrappedValue: tournament.entryFee)
        _umpireCustomMail = State(wrappedValue: tournament.umpireCustomMail ?? "")
        _umpireCustomPhone = State(wrappedValue: tournament.umpireCustomPhone ?? "")
        _umpireCustomContact = State(wrappedValue: tournament.umpireCustomContact ?? "")
    }
    
    var body: some View {
        @Bindable var tournament = tournament
        Form {
            Section {
                TournamentDatePickerView()
                TournamentDurationManagerView()
                LabeledContent {
                    TextField(tournament.isFree() ? "Gratuite" : "Inscription", value: $entryFee, format: .currency(code: Locale.defaultCurrency()))
                        .keyboardType(.decimalPad)
                        .multilineTextAlignment(.trailing)
                        .frame(maxWidth: .infinity)
                        .focused($focusedField, equals: ._entryFee)
                } label: {
                    Text("Inscription")
                }
            } footer: {
                Text("Si vous souhaitez que Padel Club vous aide à suivre les encaissements, indiquer un prix d'inscription. Sinon Padel Club vous aidera à suivre simplement l'arrivée et la présence des joueurs.")
            }
            
            if tournament.onlineRegistrationCanBeEnabled() {
                Section {
                    NavigationLink {
                        RegistrationSetupView(tournament: tournament)
                    } label: {
                        LabeledContent {
                            if tournament.enableOnlineRegistration {
                                Text("activée").foregroundStyle(.green)
                                    .font(.headline)
                            } else {
                                Text("désactivée").foregroundStyle(.logoRed)
                                    .font(.headline)
                            }
                        } label: {
                            Text("Accéder aux paramètres")
                            Text(tournament.getOnlineRegistrationStatus().statusLocalized())
                        }
                    }
                } header: {
                    Text("Inscription en ligne")
                } footer: {
                    Text("Paramétrez les possibilités d'inscription en ligne à votre tournoi via Padel Club")
                }
            }
            
            _customUmpireView()
            
            Section {
                if tournament.hideUmpireMail, tournament.hideUmpirePhone, tournament.enableOnlineRegistration {
                    Text("Attention, les emails envoyés automatiquement au regard des inscriptions en ligne ne contiendront aucun moyen de vous contacter.").foregroundStyle(.logoRed)
                }
                
                Toggle(isOn: $tournament.hideUmpireMail) {
                    Text("Masquer l'email")
                }
                Toggle(isOn: $tournament.hideUmpirePhone) {
                    Text("Masquer le téléphone")
                }

            } footer: {
                Text("Ces informations ne seront pas affichées sur la page d'information du tournoi sur Padel Club et dans les emails envoyés automatiquement au regard des inscriptions en lignes.")
            }
            
            Section {
                TextField("Nom du tournoi", text: $tournamentName, axis: .vertical)
                    .lineLimit(2)
                    .frame(maxWidth: .infinity)
                    .keyboardType(.alphabet)
                    .focused($focusedField, equals: ._name)
            } header: {
                Text("Nom du tournoi")
            }
            
            Section {
                ZStack {
                    Text(tournamentInformation).opacity(0)
                    Text(ContactType.defaultCustomMessage).opacity(0)
                    TextEditor(text: $tournamentInformation)
                        .keyboardType(.alphabet)
                        .focused($focusedField, equals: ._information)
                }
                .frame(maxHeight: 200)
                .overlay {
                    if tournamentInformation.isEmpty, focusedField != ._information {
                        Text("Texte visible dans l'onglet informations sur Padel Club.").italic()
                            .foregroundStyle(.secondary)
                    }
                }
            } header: {
                Text("Description du tournoi")
            } footer: {
                FooterButtonView("Ajouter le prix de l'inscription") {
                    tournamentInformation.append("\n" + tournament.entryFeeMessage)
                }
            }
        }
        .navigationBarBackButtonHidden(focusedField != nil)
        .toolbar(content: {
            if focusedField != nil {
                ToolbarItem(placement: .topBarLeading) {
                    Button("Annuler", role: .cancel) {
                        focusedField = nil
                    }
                }
            }
        })
        .toolbarBackground(.visible, for: .navigationBar)
        .toolbar {
            if focusedField != nil {
                ToolbarItem(placement: .keyboard) {
                    HStack {
                        if focusedField == ._entryFee {
                            if tournament.isFree() {
                                ForEach(priceTags, id: \.self) { priceTag in
                                    Button(priceTag.formatted(.currency(code: Locale.defaultCurrency()).precision(.fractionLength(0)))) {
                                        entryFee = priceTag
                                        tournament.entryFee = priceTag
                                        focusedField = nil
                                    }
                                    .buttonStyle(.bordered)
                                }
                            } else {
                                Button("Gratuit") {
                                    entryFee = nil
                                    tournament.entryFee = nil
                                    focusedField = nil
                                }
                                .buttonStyle(.bordered)
                                
                            }
                        } else {
                            if focusedField == ._name, tournamentName.isEmpty == false {
                                Button("Effacer") {
                                    tournament.name = nil
                                    tournamentName = ""
                                }
                                .buttonStyle(.borderless)
                            } else if focusedField == ._information, tournamentInformation.isEmpty == false {
                                Button("Effacer") {
                                    tournament.information = nil
                                    tournamentInformation = ""
                                }
                                .buttonStyle(.borderless)
                            } else if focusedField == ._umpireCustomMail, umpireCustomMail.isEmpty == false {
                                Button("Effacer") {
                                    _deleteUmpireMail()
                                }
                                .buttonStyle(.borderless)
                            } else if focusedField == ._umpireCustomPhone, umpireCustomPhone.isEmpty == false {
                                Button("Effacer") {
                                    _deleteUmpirePhone()
                                }
                                .buttonStyle(.borderless)
                            } else if focusedField == ._umpireCustomContact, umpireCustomContact.isEmpty == false {
                                Button("Effacer") {
                                    _deleteUmpireContact()
                                }
                                .buttonStyle(.borderless)
                            }
                        }
                        Spacer()
                        Button("Valider") {
                            focusedField = nil
                        }
                        .buttonStyle(.bordered)
                    }
                }
            }
        }
        .onChange(of: tournament.startDate) {
            _save()
        }
        .onChange(of: tournament.entryFee) {
            _save()
        }
        .onChange(of: [tournament.name, tournament.information, tournament.umpireCustomMail, tournament.umpireCustomPhone, tournament.umpireCustomContact]) {
            _save()
        }
        .onChange(of: [tournament.hideUmpireMail, tournament.hideUmpirePhone]) {
            _save()
        }
        .onChange(of: tournament.dayDuration) {
            _save()
        }
        .onChange(of: focusedField) { old, new in
            if old == ._name {
                let tournamentName = tournamentName.prefixMultilineTrimmed(200)
                if tournamentName.isEmpty {
                    tournament.name = nil
                } else {
                    tournament.name = tournamentName
                }
            } else if old == ._information {
                let tournamentInformation = tournamentInformation.prefixMultilineTrimmed(4000)
                if tournamentInformation.isEmpty {
                    tournament.information = nil
                } else {
                    tournament.information = tournamentInformation
                }
            } else if old == ._entryFee {
                tournament.entryFee = entryFee
            } else if old == ._umpireCustomMail {
                _confirmUmpireMail()
            } else if old == ._umpireCustomPhone {
                _confirmUmpirePhone()
            } else if old == ._umpireCustomContact {
                _confirmUmpireContact()
            }
            _save()
        }
    }
    
    private func _confirmUmpireMail() {
        umpireCustomMailIsInvalid = false
        if umpireCustomMail.isEmpty {
            tournament.umpireCustomMail = nil
        } else if umpireCustomMail.isValidEmail() {
            tournament.umpireCustomMail = umpireCustomMail
        } else {
            umpireCustomMailIsInvalid = true
        }
    }
    
    private func _deleteUmpireMail() {
        umpireCustomMailIsInvalid = false
        umpireCustomMail = ""
        tournament.umpireCustomMail = nil
    }

    private func _confirmUmpirePhone() {
        umpireCustomPhoneIsInvalid = false
        if umpireCustomPhone.isEmpty {
            tournament.umpireCustomPhone = nil
        } else if umpireCustomPhone.isPhoneNumber() {
            tournament.umpireCustomPhone = umpireCustomPhone.prefixMultilineTrimmed(15)
        } else {
            umpireCustomPhoneIsInvalid = true
        }
    }
    
    private func _deleteUmpirePhone() {
        umpireCustomPhoneIsInvalid = false
        umpireCustomPhone = ""
        tournament.umpireCustomPhone = nil
    }
    
    private func _confirmUmpireContact() {
        if umpireCustomContact.isEmpty {
            tournament.umpireCustomContact = nil
        } else {
            tournament.umpireCustomContact = umpireCustomContact.prefixMultilineTrimmed(200)
        }
    }
        
    private func _deleteUmpireContact() {
        umpireCustomContact = ""
        tournament.umpireCustomContact = nil
    }
    
    private func _save() {
        do {
            try dataStore.tournaments.addOrUpdate(instance: tournament)
        } catch {
            Logger.error(error)
        }
    }
    
    private func _customUmpireView() -> some View {
        Section {
            VStack(alignment: .leading) {
                TextField(dataStore.user.email, text: $umpireCustomMail)
                    .frame(maxWidth: .infinity)
                    .keyboardType(.emailAddress)
                    .autocapitalization(.none)
                    .focused($focusedField, equals: ._umpireCustomMail)
                    .onSubmit {
                        _confirmUmpireMail()
                    }
                if umpireCustomMailIsInvalid {
                    Text("Vous n'avez pas indiqué un email valide.").foregroundStyle(.logoRed)
                }
            }
            
            VStack(alignment: .leading) {
                TextField(dataStore.user.phone ?? "Téléphone", text: $umpireCustomPhone)
                    .frame(maxWidth: .infinity)
                    .keyboardType(.phonePad)
                    .focused($focusedField, equals: ._umpireCustomPhone)
                    .onSubmit {
                        _confirmUmpirePhone()
                    }
                if umpireCustomPhoneIsInvalid {
                    Text("Vous n'avez pas indiqué un téléphone valide.").foregroundStyle(.logoRed)
                }
            }

            
            VStack(alignment: .leading) {
                TextField(dataStore.user.fullName(), text: $umpireCustomContact)
                    .frame(maxWidth: .infinity)
                    .keyboardType(.default)
                    .focused($focusedField, equals: ._umpireCustomContact)
                    .onSubmit {
                        _confirmUmpireContact()
                    }
                if dataStore.user.getSummonsMessageSignature() != nil, umpireCustomContact != dataStore.user.fullName() {
                    Text("Attention vous avez une signature personnalisée contenant un contact différent.").foregroundStyle(.logoRed)
                    
                    FooterButtonView("retirer la personnalisation ?") {
                        dataStore.user.summonsMessageSignature = nil
                        self.dataStore.saveUser()
                    }
                }            }

        } header: {
            Text("Juge-arbitre")
        } footer: {
            Text("Ces informations seront utilisées pour vous contacter. Vous pouvez les modifier si vous souhaitez utiliser les informations de contact différentes de votre compte Padel Club.")
        }
    }
}
