//
//  LoginView.swift
//  PadelClub
//
//  Created by Laurent Morvillier on 19/02/2024.
//

import SwiftUI
import LeStorage

enum LoginReason {
    case loginRequiredForFeature
    
    var title: String {
        switch self {
        case .loginRequiredForFeature:
            return "Compte requis"
        }
    }
    
    var systemImage: String {
        switch self {
        case .loginRequiredForFeature:
            return "person.crop.circle.fill"
        }
    }
    
    var description: String {
        switch self {
        case .loginRequiredForFeature:
            return "Pour accéder à cette fonctionnalité, veuillez-vous connecter ou créer un compte"
        }
    }
    
}

typealias Credentials = (username: String, password: String)
struct LoginView: View {
    
    @EnvironmentObject var dataStore: DataStore
    @EnvironmentObject var networkMonitor: NetworkMonitor
    @Environment(NavigationViewModel.self) private var navigation: NavigationViewModel

    @State var username: String = ""
    @State var password: String = ""
    @State var isLoading: Bool = false
    
    @State var showEmailPopup: Bool = false
    @State var showUserCreationForm: Bool = false
    @State var showSubscriptionView: Bool = false
    @State var credentials: Credentials?

    @State var errorText: String? = nil
    @FocusState var focusedField: UserLogin?
    
    var reason: LoginReason? = nil
    
    var showEmailValidationMessage: Bool {
        credentials != nil
    }
    
    enum UserLogin {
        case username
        case password
    }

    var loginFailed: Binding<Bool> {
        Binding {
            errorText != nil
        } set: { newValue in
            if newValue == false {
                errorText = nil
            }
        }
    }
    
    var handler: (User) -> ()
    
    var body: some View {
        
        Form {
            
            if self.showEmailValidationMessage || (dataStore.appSettings.didCreateAccount == true && dataStore.appSettings.didRegisterAccount == false) {
                Section {
                    ContentUnavailableView {
                        Label("Vérifiez vos emails.", systemImage: "envelope.badge")
                    } description: {
                        Text("Vous pourrez ensuite vous connecter ici. N'oubliez pas de vérifiez vos spams !")
                    } actions: {
                        SupportButtonView(contentIsUnavailable: true)
                    }
                }
            }
            
            if let reason {
                Section {
                    ContentUnavailableView {
                        Label(reason.title, systemImage: reason.systemImage)
                    } description: {
                        Text(reason.description)
                    }
                }
            }
            
            Section {
                TextField("Nom d'utilisateur", text: self.$username)
                    .autocorrectionDisabled(true)
                    .keyboardType(.asciiCapable)
                    .textContentType(.init(rawValue: ""))
                    .textInputAutocapitalization(.never)
                    .focused($focusedField, equals: .username)
                    .submitLabel(.next)
                    .onSubmit(of: .text) {
                        focusedField = .password
                    }
                PasswordField("Mot de passe", text: self.$password)
                    .textContentType(.init(rawValue: ""))
                    .submitLabel(.send)
                    .onSubmit(of: .text) {
                        if password.isEmpty == false && username.isEmpty == false {
                            Task {
                                await self._login()
                            }
                        }
                    }
            }
            
            Section {
                RowButtonView("Connexion") {
                    await self._login()
                }
                .disabled(password.isEmpty || username.isEmpty)
//                if let error = self.errorText {
//                    Text(error).font(.callout).foregroundStyle(.red)
//                }
            }
            
            if !self.showEmailValidationMessage {
                Section {
                    Button(action: {
                        self.showUserCreationForm = true
                    }, label: {
                        Text("Créer un compte")
                    })
                    .sheet(isPresented: self.$showUserCreationForm, onDismiss: {
                        if let credentials {
                            self.username = credentials.username
                            self.password = credentials.password
                        }
                    }) {
                        UserCreationFormView(isPresented: self.$showUserCreationForm, credentials: self.$credentials)
                    }

                    
//                    NavigationLink("Créer un compte") {
//                        UserCreationView()
//                    }
                    Button(action: {
                        self.showEmailPopup = true
                    }, label: {
                        Text("Mot passe oublié")
                    })
                    .alert(
                        Text("Changer de mot de passe")
                        ,
                        isPresented: self.$showEmailPopup
                    ) {
                        EmailConfirmationView()
                    } message: {
                        Text("Veuillez entrer votre email")
                    }
                }
            }
            
        }
        .alert("Un problème est survenu", isPresented: loginFailed) {
            Button("OK") {
            }
        } message: {
            let message = [networkMonitor.connected == false ? "L'appareil n'est pas connecté à internet." as String? : nil, errorText].compacted().joined(separator: "\n")
            Text(message)
        }
        .navigationTitle("Connexion")
        .onAppear {
            #if DEBUG
            if let username = PListReader.readString(plist: "local", key: "username") {
                self.username = username
            }
            if let password = PListReader.readString(plist: "local", key: "password") {
                self.password = password
            }
            #endif
        }
    }
    
    fileprivate func _login() async {
        self.errorText = nil // reset error
        self.isLoading = true
        do {
            let service = try StoreCenter.main.service()
            let user: User = try await service.login(
                username: self.username,
                password: self.password)
            self.dataStore.user = user
            self.isLoading = false
            await MainActor.run {
                dataStore.appSettings.didRegisterAccount = true
                dataStore.appSettingsStorage.write()
            }
            self.handler(user)
            navigation.umpirePath.removeAll()
        } catch {
            self.isLoading = false
            self.errorText = ErrorUtils.message(error: error)
            Logger.error(error)
        }
    }
    
}

struct EmailConfirmationView: View {
    
    @State var email: String = ""
    @State var errorMessage: String = ""
    
    var body: some View {
        VStack {
            TextField("Email", text: self.$email)
                .keyboardType(.emailAddress)
            Button {
                self._forgottenPassword()
            } label: {
                Text("Envoyer l'email")
            }

        }
    }
    
    fileprivate func _forgottenPassword() {
        
        Task {
            do {
                let service = try StoreCenter.main.service()
                try await service.forgotPassword(email: self.email)
            } catch {
                Logger.error(error)
                self.errorMessage = ErrorUtils.message(error: error)
            }
        }
    }
    
}

//#Preview {
//    NavigationStack {
//        LoginView(handler: { _ in })
//    }
//}

//#Preview {
//    EmailConfirmationView()
//}
