//
//  SendToAllView.swift
//  PadelClub
//
//  Created by Razmig Sarkissian on 28/04/2024.
//

import SwiftUI
import LeStorage

struct SendToAllView: View {
    @Environment(\.dismiss) var dismiss
    @EnvironmentObject var dataStore: DataStore
    @Environment(Tournament.self) var tournament: Tournament
    @EnvironmentObject var networkMonitor: NetworkMonitor

    @State private var contactType: ContactType? = nil
    @State private var contactMethod: Int = 1
    @State private var contactRecipients: Set<String> = Set()
    @State private var sentError: ContactManagerError? = nil
    let addLink: Bool
//    @State var cannotPayForTournament: Bool = false
    @State private var pageLink: PageLink = .teams
    
    @State var showSubscriptionView: Bool = false
    @State var showUserCreationView: Bool = false

    @State var summonParamByMessage: Bool = false
    @State var summonParamReSummon: Bool = false
    
    var messageSentFailed: Binding<Bool> {
        Binding {
            sentError != nil
        } set: { newValue in
            if newValue == false {
                sentError = nil
            }
        }
    }
    
    var body: some View {
        NavigationStack {
            List(selection: $contactRecipients) {
                Section {
                    Picker(selection: $contactMethod) {
                        Text("Contacter par sms").tag(0)
                        Text("Contacter par mail").tag(1)
                    } label: {
                        Text("méthode")
                    }
                    .labelsHidden()
                    .pickerStyle(.inline)
                }
                
                Section {
                    ForEach(tournament.groupStages()) { groupStage in
                        let teams = groupStage.teams()
                        if teams.isEmpty == false {
                            LabeledContent {
                                Text(teams.count.formatted() + " équipe" + teams.count.pluralSuffix)
                            } label: {
                                Text(groupStage.groupStageTitle())
                            }
                            .tag(groupStage.id)
                        }
                    }
                    ForEach(tournament.rounds()) { round in
                        let teams = round.teams()
                        if teams.isEmpty == false {
                            LabeledContent {
                                Text(teams.count.formatted() + " équipe" + teams.count.pluralSuffix)
                            } label: {
                                Text(round.roundTitle())
                            }
                            .tag(round.id)
                        }
                    }
                }
                
                if addLink {
                    Section {
                        let links : [PageLink] = [.teams, .summons, .groupStages, .matches, .rankings]
                        Picker(selection: $pageLink) {
                            ForEach(links) { pageLink in
                                Text(pageLink.localizedLabel())
                            }
                        } label: {
                            Text("Choisir une page du tournoi en particulier")
                        }
                        .pickerStyle(.menu)
                    }
                }
                
                Section {
                    RowButtonView("Contacter \(_totalString())") {
                        self._contact()
                    }
                }
            }
            .toolbar {
                ToolbarItem(placement: .topBarLeading) {
                    Button("Annuler", role: .cancel) {
                        dismiss()
                    }

                }
            }
            .environment(\.editMode, Binding.constant(EditMode.active))
            .headerProminence(.increased)
            .navigationTitle("Préparation")
            .navigationBarTitleDisplayMode(.inline)
            .toolbarBackground(.visible, for: .navigationBar)
            .alert("Un problème est survenu", isPresented: messageSentFailed) {
                Button("OK") {
                }
            } message: {
                let message = [networkMonitor.connected == false ? "L'appareil n'est pas connecté à internet." as String? : nil, sentError == .mailNotSent ? "Le mail est dans la boîte d'envoi de l'app Mail. Vérifiez son état dans l'app Mail avant d'essayer de le renvoyer." as String? : nil, (sentError == .messageFailed || sentError == .messageNotSent) ? "Le SMS n'a pas été envoyé" as String? : nil, sentError == .mailFailed ? "Le mail n'a pas été envoyé" as String? : nil].compacted().joined(separator: "\n")
                Text(message)
            }
            .sheet(item: $contactType) { contactType in
                Group {
                    switch contactType {
                    case .message(_, let recipients, let body, _):
                        MessageComposeView(recipients: recipients, body: body) { result in
                            switch result {
                            case .cancelled:
                                break
                            case .failed:
                                self.sentError = .messageFailed
                            case .sent:
                                if networkMonitor.connected == false {
                                    self.sentError = .messageNotSent
                                }
                            @unknown default:
                                break
                            }
                        }
                    case .mail(_, let recipients, let bccRecipients, let body, let subject, _):
                        MailComposeView(recipients: recipients, bccRecipients: bccRecipients, body: body, subject: subject) { result in
                            switch result {
                            case .cancelled, .saved:
                                self.contactType = nil
                            case .failed:
                                self.contactType = nil
                                self.sentError = .mailFailed
                            case .sent:
                                if networkMonitor.connected == false {
                                    self.contactType = nil
                                    self.sentError = .mailNotSent
                                }
                            @unknown default:
                                break
                            }
                        }
                    }
                }
                .tint(.master)
            }
            .sheet(isPresented: self.$showSubscriptionView, content: {
                NavigationStack {
                    SubscriptionView(isPresented: self.$showSubscriptionView, showLackOfPlanMessage: true)
                }
            })
            .sheet(isPresented: self.$showUserCreationView, content: {
                NavigationStack {
                    LoginView { _ in
                        self.showUserCreationView = false
                        self._contact()
                    }
                }
            })

        }
    }
    
    func _teams() -> [TeamRegistration] {
        if _roundTeams().isEmpty && _groupStagesTeams().isEmpty {
            return tournament.selectedSortedTeams()
        }
        return _roundTeams() + _groupStagesTeams()
    }
    
    func _roundTeams() -> [TeamRegistration] {
        let rounds : [Round] = contactRecipients.compactMap { Store.main.findById($0) }
        return rounds.flatMap({ $0.teams() })
    }

    func _groupStagesTeams() -> [TeamRegistration] {
        let groupStages : [GroupStage] = contactRecipients.compactMap { Store.main.findById($0) }
        return groupStages.flatMap({ $0.teams() })
    }
    
    func _totalString() -> String {
        if contactRecipients.isEmpty {
            return "toutes les équipes"
        } else {
            let teams = _teams()
            return teams.count.formatted() + " équipe" + teams.count.pluralSuffix
        }
    }
    
    func finalMessage() -> String {
        var message = [String?]()
        message.append("\n\n")
        if addLink {
            message.append(tournament.shareURL(pageLink)?.absoluteString)
        }
        
        let signature = dataStore.user.summonsMessageSignature ?? dataStore.user.defaultSignature()

        message.append(signature)
        
        return message.compactMap { $0 }.joined(separator: "\n\n")
    }
    
    fileprivate func _contact() {
        
        self._verifyUser {
            self._payTournamentAndExecute {
                
                if contactMethod == 0 {
                    contactType = .message(date: nil, recipients: _teams().flatMap { $0.unsortedPlayers() }.compactMap { $0.phoneNumber }, body: finalMessage(), tournamentBuild: nil)
                } else {
                    contactType = .mail(date: nil, recipients: tournament.umpireMail(), bccRecipients: _teams().flatMap { $0.unsortedPlayers() }.compactMap { $0.email }, body: finalMessage(), subject: tournament.tournamentTitle(), tournamentBuild: nil)
                }
            }
        }
        
    }
    
    fileprivate func _verifyUser(_ handler: () -> ()) {
        if Store.main.userId != nil {
            handler()
        } else {
            self.showUserCreationView = true
        }
    }
    
    fileprivate func _payTournamentAndExecute(_ handler: () -> ()) {
        do {
            try tournament.payIfNecessary()
            handler()
        } catch {
            self.showSubscriptionView = true
        }
    }
}

//#Preview {
//    SendToAllView(addLink: true)
//}
