import SwiftUI

struct DeleteAccountView: View {
    @EnvironmentObject var userService: UserService

    var title: String {
        guard case .signedIn(let auth) = userService.signedInState else {
            return ""
        }
        
        let defaultStr = "Delete Account?"
        
        guard let deleteStatus = auth.deleteStatus else {
            return defaultStr
        }
        
        switch deleteStatus {
        case .notRequested:
            return defaultStr
            
        case .pendingConfirmation:
            return "Pending Confirmation"
            
        case .pendingDelete:
            return "Pending Deletion"
        }
    }
    
    var message: String {
        guard case .signedIn(let auth) = userService.signedInState else {
            return ""
        }
        
        let defaultStr = "Deleting your Riotact account means you will no longer be able to comment on articles, manage preferences or access our free, daily digest and weekly newsletter.\n\nOld comments will be deleted and will not be recoverable, including any comment threads you have started."
        
        guard let deleteStatus = auth.deleteStatus else {
            return defaultStr
        }
        
        switch deleteStatus {
        case .notRequested:
            return defaultStr
            
        case .pendingConfirmation:
            return "Please confirm your deletion request by following the instructions sent to \(auth.email)."
            
        case .pendingDelete:
            return "Your account is currently pending deletion."
        }
    }
    
    var body: some View {
        ZStack(alignment: .bottom) {
            ColorName.background.color
                .ignoresSafeArea()
            
            ScrollView {
                VStack(spacing: 20) {
                    UserAvatarView()
                        .frame(width: 144, height: 144)
                    
                    Text(title)
                        .textStyle(.title1)
                        .multilineTextAlignment(.center)
                    
                    Text(message)
                        .textStyle(.body)
                        .multilineTextAlignment(.center)
                    
                    Spacer()
                    
                }
                .padding()
                .padding(.bottom, 60)
            }
            
            DeleteButtonOptionsView()
                .padding()
                .padding(.top, 30)
                .background(
                    LinearGradient(colors: [ColorName.background.color.opacity(0),ColorName.background.color], startPoint: .top, endPoint: .bottom)
                )
        }
        .navigationTitle("Account Deletion")
    }
}

private struct DeleteButtonOptionsView: View {
    enum DeleteButton: Equatable {
        case delete(String)
        case cancelDeletion
        case resendDeleteRequest(String)
        
        var title: String {
            switch self {
            case .delete:
                return "Delete Account"
            case .cancelDeletion:
                return "Cancel Account Deletion"
            case .resendDeleteRequest:
                return "Resend Delete Confirmation Email"
            }
        }
        
        var message: String {
            switch self {
            case .delete(let email):
                return "An email to verify your request will be sent to \(email)."
            case .cancelDeletion:
                return "Your request for account deletion will be withdrawn immediately."
            case .resendDeleteRequest(let email):
                return "An email to verify your request will be sent to \(email)."
            }
        }
        
        var buttonText: String {
            switch self {
            case .delete:
                return "Delete"
            case .cancelDeletion:
                return "Okay"
            case .resendDeleteRequest:
                return "Resend"
            }
        }
    }
    
    @EnvironmentObject var userService: UserService
    
    @State private var activeDeleteButton: DeleteButton?
    @State private var _outgoingDeleteButton: DeleteButton?
        
    var body: some View {
        if case .signedIn(let authResponse) = userService.signedInState {

            let buttonIsPresented = Binding<Bool> {
                activeDeleteButton != nil
            } set: { newValue in
                if !newValue {
                    _outgoingDeleteButton = activeDeleteButton
                    activeDeleteButton = nil
                } else {
                    _outgoingDeleteButton = nil
                }
            }
            
            VStack {
                if let deleteStatus = authResponse.deleteStatus {
                    switch deleteStatus {
                    case .notRequested:
                        deleteButton(.delete(authResponse.email))
                            .buttonStyle(PrimaryButtonStyle())
                        
                    case .pendingConfirmation:
                        deleteButton(.cancelDeletion)
                            .buttonStyle(PrimaryButtonStyle())
                        
                        deleteButton(.resendDeleteRequest(authResponse.email))
                            .buttonStyle(SecondaryButtonStyle())
                        
                    case .pendingDelete:
                        deleteButton(.cancelDeletion)
                            .buttonStyle(PrimaryButtonStyle())
                        
                    }
                } else {
                    deleteButton(.delete(authResponse.email))
                        .buttonStyle(PrimaryButtonStyle())
                }
            }
            .alert(isPresented: buttonIsPresented) {
                Alert(title: Text(activeDeleteButton?.title ?? ""),
                      message: Text(activeDeleteButton?.message ?? ""),
                      primaryButton: .cancel {
                  _outgoingDeleteButton = nil
                },
                      secondaryButton: .destructive(Text(activeDeleteButton?.buttonText ?? ""), action: {
                    actionForDeleteButton(_outgoingDeleteButton)
                    
                }))
            }
            
        } else {
            EmptyView()
        }
    }
    
    @ViewBuilder private func deleteButton(_ type: DeleteButton) -> some View {
        Button {
            activeDeleteButton = type
        } label: {
            if _outgoingDeleteButton == type {
                ProgressView()
                    .progressViewStyle(CircularProgressViewStyle())
                    .foregroundColor(ColorName.textOnTint.color)
                    .padding(1)
                
            } else {
                Text(type.title)
            }
        }
    }
    
    private func actionForDeleteButton(_ type: DeleteButton?) {
        
        guard let type = type else {
            return
        }
    
        Task {
            do {
                switch type {
                case .delete:
                    _ = try await userService.requestDeletion()
                    
                case .cancelDeletion:
                    _ = try await userService.cancelDeletionRequest()
                    
                case .resendDeleteRequest:
                    _ = try await userService.resendDeletionRequest()
                }
                
                DispatchQueue.main.async {
                    _outgoingDeleteButton = nil
                }
                
                await userService.signInWithStoredToken()
                
            } catch {
                DispatchQueue.main.async {
                    _outgoingDeleteButton = nil
                }
            }
        }
    }
}

struct DeleteAccountView_Previews: PreviewProvider {
    static var previews: some View {
        DeleteAccountView()
    }
}
