//
//  EditingTeamView.swift
//  PadelClub
//
//  Created by Razmig Sarkissian on 17/04/2024.
//

import SwiftUI
import LeStorage

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

    var team: TeamRegistration
    @State private var editedTeam: TeamRegistration?
    @State private var contactType: ContactType? = nil
    @State private var sentError: ContactManagerError? = nil
    @State private var showSubscriptionView: Bool = false
    @State private var registrationDate : Date
    @State private var callDate : Date
    @State private var name: String
    
    var messageSentFailed: Binding<Bool> {
        Binding {
            sentError != nil
        } set: { newValue in
            if newValue == false {
                sentError = nil
            }
        }
    }

    var tournamentStore: TournamentStore {
        return self.tournament.tournamentStore
    }

    init(team: TeamRegistration) {
        self.team = team
        _name = .init(wrappedValue: team.name ?? "")
        _registrationDate = State(wrappedValue: team.registrationDate ?? Date())
        _callDate = State(wrappedValue: team.callDate ?? Date())
    }
    
    var body: some View {
        List {
            Section {
                RowButtonView("Modifier la composition de l'équipe") {
                    editedTeam = team
                }

                TeamDetailView(team: team)
            } footer: {
                HStack {
                    CopyPasteButtonView(pasteValue: team.playersPasteData())
                    Spacer()
                    NavigationLink {
                        GroupStageTeamReplacementView(team: team)
                            .environment(tournament)
                    } label: {
                        Text("Chercher à remplacer")
                            .underline()
                    }
                }
            }
            
            Section {
                DatePicker(selection: $registrationDate) {
                    Text("Inscription")
                    Text(registrationDate.localizedWeekDay().capitalized)
                }
                if let callDate = team.callDate {
                    LabeledContent() {
                        Text(callDate.localizedDate())
                    } label: {
                        Text("Convocation")
                    }
                } else {
                    Text("Cette équipe n'a pas été convoquée")
                }

                Toggle(isOn: hasArrived) {
                    Text("Équipe sur place")
                }
                
                Toggle(isOn: .init(get: {
                    return team.wildCardBracket
                }, set: { value in
                    team.resetPositions()
                    team.wildCardGroupStage = false
                    team.walkOut = false
                    team.wildCardBracket = value
                    do {
                        try tournamentStore.teamRegistrations.addOrUpdate(instance: team)
                    } catch {
                        Logger.error(error)
                    }
                })) {
                    Text("Wildcard Tableau")
                }
                
                Toggle(isOn: .init(get: {
                    return team.wildCardGroupStage
                }, set: { value in
                    team.resetPositions()
                    team.wildCardBracket = false
                    team.walkOut = false
                    team.wildCardGroupStage = value
                    do {
                        try tournamentStore.teamRegistrations.addOrUpdate(instance: team)
                    } catch {
                        Logger.error(error)
                    }
                })) {
                    Text("Wildcard Poule")
                }
                
                Toggle(isOn: .init(get: {
                    return team.walkOut
                }, set: { value in
                    team.resetPositions()
                    team.wildCardBracket = false
                    team.wildCardGroupStage = false
                    team.walkOut = value
                    do {
                        try tournamentStore.teamRegistrations.addOrUpdate(instance: team)
                    } catch {
                        Logger.error(error)
                    }
                })) {
                    Text("Forfait")
                }

                LabeledContent {
                    TextField("Nom", text: $name)
                        .autocorrectionDisabled()
                        .keyboardType(.alphabet)
                        .keyboardType(.alphabet)
                        .multilineTextAlignment(.trailing)
                        .frame(maxWidth: .infinity)
                        .submitLabel(.done)
                        .onSubmit(of: .text) {
                            let trimmed = name.trimmed
                            if trimmed.isEmpty {
                                team.name = nil
                            } else {
                                team.name = trimmed
                            }
                            
                            _save()
                        }
                } label: {
                    Text("Nom de l'équipe")
                }
            }
            
            Section {
                RowButtonView("Retirer des poules", role: .destructive) {
                    team.resetGroupeStagePosition()
                    _save()
                }
                .disabled(team.inGroupStage() == false)
            }

            Section {
                RowButtonView("Retirer du tableau", role: .destructive) {
                    team.resetBracketPosition()
                    _save()
                }
                .disabled(team.inRound() == false)
            }
            
            Section {
                RowButtonView("Effacer l'équipe", role: .destructive, systemImage: "trash") {
                    team.deleteTeamScores()
                    do {
                        try tournamentStore.teamRegistrations.delete(instance: team)
                    } catch {
                        Logger.error(error)
                    }
                }
            }
        }
        .alert("Un problème est survenu", isPresented: messageSentFailed) {
            Button("OK") {
            }
        } message: {
            Text(_networkErrorMessage)
        }
        .sheet(item: $contactType) { contactType in
            Group {
                switch contactType {
                case .message(_, let recipients, let body, _):
                    if Guard.main.paymentForNewTournament() != nil {
                        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
                            }
                        }
                    } else {
                        SubscriptionView(isPresented: self.$showSubscriptionView, showLackOfPlanMessage: true)
                            .environment(\.colorScheme, .light)
                    }
                case .mail(_, let recipients, let bccRecipients, let body, let subject, _):
                    if Guard.main.paymentForNewTournament() != nil {
                        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
                            }
                        }
                    } else {
                        SubscriptionView(isPresented: self.$showSubscriptionView, showLackOfPlanMessage: true)
                            .environment(\.colorScheme, .light)
                    }
                }
            }
            .tint(.master)
        }
        .sheet(item: $editedTeam) { editedTeam in
            NavigationStack {
                AddTeamView(tournament: tournament, editedTeam: editedTeam)
            }
            .tint(.master)
        }
        .toolbar {
            ToolbarItem(placement: .topBarTrailing) {
                MenuWarningView(tournament: tournament, teams: [team], contactType: $contactType)
            }
        }
        .onChange(of: registrationDate) {
            team.registrationDate = registrationDate
            _save()
        }
        .toolbarBackground(.visible, for: .navigationBar)
        .navigationTitle("Édition de l'équipe")
        .navigationBarTitleDisplayMode(.inline)
    }
    
    private var hasArrived: Binding<Bool> {
        Binding {
            team.unsortedPlayers().allSatisfy({ $0.hasArrived })
        } set: { hasArrived in
            team.unsortedPlayers().forEach {
                $0.hasArrived = hasArrived
            }
            do {
                try tournamentStore.playerRegistrations.addOrUpdate(contentOfs: team.unsortedPlayers())
            } catch {
                Logger.error(error)
            }
        }

    }
    private func _save() {
        do {
            try tournamentStore.teamRegistrations.addOrUpdate(instance: team)
        } catch {
            Logger.error(error)
        }
    }
    
    private var _networkErrorMessage: String {
        var errors: [String] = []
        
        if networkMonitor.connected == false {
            errors.append("L'appareil n'est pas connecté à internet.")
        }
        if sentError == .mailNotSent {
            errors.append("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.")
        }
        if (sentError == .messageFailed || sentError == .messageNotSent) {
            errors.append("Le SMS n'a pas été envoyé")
        }
        if sentError == .mailFailed {
            errors.append("Le mail n'a pas été envoyé")
        }
        return errors.joined(separator: "\n")
    }

}

//#Preview {
//    EditingTeamView(team: TeamRegistration.mock())
//}
