//
//  CallMessageCustomizationView.swift
//  Padel Tournament
//
//  Created by Razmig Sarkissian on 02/11/2023.
//

import SwiftUI
import LeStorage

struct CallMessageCustomizationView: View {
    @EnvironmentObject var dataStore: DataStore
    var tournament: Tournament
    enum Field {
        case signature
        case body
        case paymentMethods
        case clubName
    }
    
    @FocusState var focusedField: CallMessageCustomizationView.Field?
    @State private var customClubName: String = ""
    @State private var customCallMessageBody: String = ""
    @State private var customCallMessageSignature: String = ""
    @State private var summonsAvailablePaymentMethods: String = ""
    
    var columns: [GridItem] = Array(repeating: .init(.flexible()), count: 3)
    
    init(tournament: Tournament) {
        self.tournament = tournament
        _customCallMessageBody = State(wrappedValue: DataStore.shared.user.summonsMessageBody ?? (DataStore.shared.user.summonsUseFullCustomMessage ? "" : ContactType.defaultCustomMessage))
        _customCallMessageSignature = State(wrappedValue: DataStore.shared.user.summonsMessageSignature ?? DataStore.shared.user.defaultSignature())
        _customClubName = State(wrappedValue: tournament.clubName ?? "Lieu du tournoi")
        _summonsAvailablePaymentMethods = State(wrappedValue: DataStore.shared.user.summonsAvailablePaymentMethods ?? ContactType.defaultAvailablePaymentMethods)
    }
    
    var clubName: String {
        customClubName
    }

    var entryFeeMessage: String? {
        dataStore.user.summonsDisplayEntryFee ? tournament.entryFeeMessage : nil
    }
    
    var computedMessage: String {
        [entryFeeMessage, customCallMessageBody].compacted().map { $0.trimmed }.joined(separator: "\n")
    }
    
    var finalMessage: String? {
        let localizedCalled = "convoqué" + (tournament.tournamentCategory == .women ? "e" : "") + "s"
        return "Bonjour,\n\nVous êtes \(localizedCalled) pour jouer en \(RoundRule.roundName(fromRoundIndex: 2).lowercased()) du \(tournament.tournamentTitle(.short)) au \(clubName) le \(tournament.startDate.formatted(Date.FormatStyle().weekday(.wide).day().month(.wide))) à \(tournament.startDate.formatted(Date.FormatStyle().hour().minute())).\n\n" + computedMessage + "\n\n\(customCallMessageSignature)"
    }

    var body: some View {
        @Bindable var user = dataStore.user
        List {
            _renderingView()
                .disabled(true)
            _optionsView()
            _editorView()
            
            if user.summonsUseFullCustomMessage && tournament.isFree() == false {
                _paymentMethodsView()
            }
            
            Section {
                ZStack {
                    Text(customCallMessageSignature).hidden()
                    TextEditor(text: $customCallMessageSignature)
                        .autocorrectionDisabled()
                        .focused($focusedField, equals: .signature)
                }
            } header: {
                Text("Signature du message")
            } footer: {
                HStack {
                    Spacer()
                    FooterButtonView("effacer") {
                        customCallMessageSignature = ""
                        _save()
                    }
                    Divider()
                    FooterButtonView("défaut") {
                        customCallMessageSignature = DataStore.shared.user.defaultSignature()
                        _save()
                    }
                    Divider()
                    FooterButtonView("éditer") {
                        focusedField = .signature
                    }
                }
            }
            
            _clubNameView()
        }
        .headerProminence(.increased)
        .navigationBarTitleDisplayMode(.inline)
        .toolbarBackground(.visible, for: .navigationBar)
        .navigationTitle("Message de convocation")
        .toolbar {
            ToolbarItemGroup(placement: .keyboard) {
                if focusedField != .clubName {
                    Spacer()
                    Button {
                        focusedField = nil
                        _save()
                    } label: {
                        Text("Valider")
                    }
                    .buttonStyle(.bordered)
                }
            }
        }
        .onChange(of: user.summonsUseFullCustomMessage) {
            user.summonsMessageBody = nil
            if user.summonsUseFullCustomMessage == false {
                customCallMessageBody = ContactType.defaultCustomMessage
            } else {
                customCallMessageBody = ""
            }
            _save()
        }
        .onChange(of: user.summonsDisplayEntryFee) {
            _save()
        }
    }
    
    private func _save() {
        self.dataStore.user.summonsMessageBody = customCallMessageBody
        self.dataStore.user.summonsMessageSignature = customCallMessageSignature
        self.dataStore.user.summonsAvailablePaymentMethods = summonsAvailablePaymentMethods
        self.dataStore.saveUser()
    }
    
    @ViewBuilder
    private func _editorView() -> some View {
        @Bindable var user = dataStore.user

        Section {
            ZStack {
                Text(customCallMessageBody).hidden()
                    .padding(.vertical, 20)
                TextEditor(text: $customCallMessageBody)
                    .autocorrectionDisabled()
                    .focused($focusedField, equals: .body)
            }
        } header: {
            if user.summonsUseFullCustomMessage {
                Text("Message de convocation")
            } else {
                Text("Information supplémentaire")
            }
        } footer: {
            if user.summonsUseFullCustomMessage == false {
                HStack {
                    Spacer()
                    FooterButtonView("effacer") {
                        customCallMessageBody = ""
                        _save()
                    }
                    Divider()
                    FooterButtonView("défaut") {
                        customCallMessageBody = ContactType.defaultCustomMessage
                        _save()
                    }
                    Divider()
                    FooterButtonView("éditer") {
                        focusedField = .body
                    }
                }
            } else {
                LazyVGrid(columns: columns, spacing: 0) {
                    FooterButtonView("#titre") {
                        customCallMessageBody.append("#titre")
                        focusedField = .body
                    }
                    FooterButtonView("#manche") {
                        customCallMessageBody.append("#manche")
                        focusedField = .body
                    }
                    FooterButtonView("#prix") {
                        customCallMessageBody.append("#prix")
                        focusedField = .body
                    }
                    FooterButtonView("#jour") {
                        customCallMessageBody.append("#jour")
                        focusedField = .body
                    }
                    FooterButtonView("#horaire") {
                        customCallMessageBody.append("#horaire")
                        focusedField = .body
                    }
                    FooterButtonView("#club") {
                        customCallMessageBody.append("#club")
                        focusedField = .body
                    }
                    FooterButtonView("#signature") {
                        customCallMessageBody.append("#signature")
                        focusedField = .body
                    }
                }
            }
        }
    }
    
    @ViewBuilder
    private func _clubNameView() -> some View {
        if let eventClub = tournament.eventObject()?.clubObject() {
            let hasBeenCreated: Bool = eventClub.hasBeenCreated(by: Store.main.userId)
            Section {
                TextField("Nom du club", text: $customClubName, axis: .vertical)
                    .lineLimit(2)
                    .autocorrectionDisabled()
                    .focused($focusedField, equals: .clubName)
                    .onSubmit {
                        eventClub.name = customClubName
                        do {
                            try dataStore.clubs.addOrUpdate(instance: eventClub)
                        } catch {
                            Logger.error(error)
                        }
                    }
                    .disabled(hasBeenCreated == false)
            } footer: {
                if hasBeenCreated == false {
                    Text("Édition impossible, vous n'êtes pas le créateur de ce club.").foregroundStyle(.logoRed)
                } else {
                    HStack {
                        Spacer()
                        FooterButtonView("éditer") {
                            focusedField = .clubName
                        }
                    }
                }
            }
        }
    }
    
    @ViewBuilder
    private func _renderingView() -> some View {
        @Bindable var user = dataStore.user
        Section {
            Group {
                if user.summonsUseFullCustomMessage {
                    Text(self.computedFullCustomMessage())
                }
                else if let finalMessage {
                    Text(finalMessage)
                }
            }.italic().foregroundStyle(.gray)
        } header: {
            Text("Rendu généré automatiquement")
        }
    }
        
    @ViewBuilder
    private func _optionsView() -> some View {
        @Bindable var user = dataStore.user
        Section {
            Toggle(isOn: $user.summonsUseFullCustomMessage) {
                Text("Tout personnaliser")
                Text("Écrivez votre propre message.")
            }
            if user.summonsUseFullCustomMessage == false {
                Toggle(isOn: $user.summonsDisplayEntryFee) {
                    Text("Afficher le prix d'inscription")
                    Text("et les informations sur le paiement")
                }
            }
        } header: {
            Text("Options")
        }
        
        if user.summonsDisplayEntryFee && user.summonsUseFullCustomMessage == false && tournament.isFree() == false {
            _paymentMethodsView()
        }
    }
    
    @ViewBuilder
    private func _paymentMethodsView() -> some View {
        Section {
            ZStack {
                Text(summonsAvailablePaymentMethods).hidden()
                    .padding(.vertical, 20)
                TextEditor(text: $summonsAvailablePaymentMethods)
                    .autocorrectionDisabled()
                    .focused($focusedField, equals: .paymentMethods)
            }
        } header: {
            Text("Information sur le paiement")
        } footer: {
            HStack {
                Spacer()
                FooterButtonView("effacer") {
                    summonsAvailablePaymentMethods = ""
                    _save()
                }
                Divider()
                FooterButtonView("défaut") {
                    summonsAvailablePaymentMethods = ContactType.defaultAvailablePaymentMethods
                    _save()
                }
                Divider()
                FooterButtonView("éditer") {
                    focusedField = .paymentMethods
                }
            }
        }
    }
    
    func computedFullCustomMessage() -> String {
        return ContactType.callingCustomMessage(source: customCallMessageBody, tournament: tournament, startDate: Date(), roundLabel: RoundRule.roundName(fromRoundIndex: 2))
    }
}
