//
//  PrivacySettings.swift
//  SimpleX (iOS)
//
//  Created by Evgeny on 29/05/2022.
//  Copyright © 2022 SimpleX Chat. All rights reserved.
//

import SwiftUI
import SimpleXChat

struct PrivacySettings: View {
    @EnvironmentObject var m: ChatModel
    @EnvironmentObject var theme: AppTheme
    @AppStorage(DEFAULT_PRIVACY_ACCEPT_IMAGES) private var autoAcceptImages = true
    @AppStorage(DEFAULT_PRIVACY_LINK_PREVIEWS) private var useLinkPreviews = true
    @AppStorage(DEFAULT_PRIVACY_SHOW_CHAT_PREVIEWS) private var showChatPreviews = true
    @AppStorage(DEFAULT_PRIVACY_SAVE_LAST_DRAFT) private var saveLastDraft = true
    @AppStorage(GROUP_DEFAULT_PRIVACY_ENCRYPT_LOCAL_FILES, store: groupDefaults) private var encryptLocalFiles = true
    @AppStorage(GROUP_DEFAULT_PRIVACY_ASK_TO_APPROVE_RELAYS, store: groupDefaults) private var askToApproveRelays = true
    @State private var simplexLinkMode = privacySimplexLinkModeDefault.get()
    @AppStorage(DEFAULT_PRIVACY_PROTECT_SCREEN) private var protectScreen = false
    @AppStorage(DEFAULT_PERFORM_LA) private var prefPerformLA = false
    @State private var currentLAMode = privacyLocalAuthModeDefault.get()
    @AppStorage(DEFAULT_PRIVACY_MEDIA_BLUR_RADIUS) private var privacyMediaBlurRadius: Int = 0
    @State private var contactReceipts = false
    @State private var contactReceiptsReset = false
    @State private var contactReceiptsOverrides = 0
    @State private var contactReceiptsDialogue = false
    @State private var groupReceipts = false
    @State private var groupReceiptsReset = false
    @State private var groupReceiptsOverrides = 0
    @State private var groupReceiptsDialogue = false
    @State private var alert: PrivacySettingsViewAlert?

    enum PrivacySettingsViewAlert: Identifiable {
        case error(title: LocalizedStringKey, error: LocalizedStringKey = "")

        var id: String {
            switch self {
            case let .error(title, _): return "error \(title)"
            }
        }
    }

    var body: some View {
        VStack {
            List {
                Section(header: Text("Device").foregroundColor(theme.colors.secondary)) {
                    NavigationLink {
                        SimplexLockView(prefPerformLA: $prefPerformLA, currentLAMode: $currentLAMode)
                            .navigationTitle("SimpleX Lock")
                            .modifier(ThemedBackground(grouped: true))
                    } label: {
                        if prefPerformLA {
                            settingsRow("lock.fill", color: .green) {
                                simplexLockRow(currentLAMode.text)
                            }
                        } else {
                            settingsRow("lock", color: theme.colors.secondary) {
                                simplexLockRow("Off")
                            }
                        }
                    }
                    settingsRow("eye.slash", color: theme.colors.secondary) {
                        Toggle("Protect app screen", isOn: $protectScreen)
                    }
                }

                Section {
                    settingsRow("network", color: theme.colors.secondary) {
                        Toggle("Send link previews", isOn: $useLinkPreviews)
                            .onChange(of: useLinkPreviews) { linkPreviews in
                                privacyLinkPreviewsGroupDefault.set(linkPreviews)
                            }
                    }
                    settingsRow("message", color: theme.colors.secondary) {
                        Toggle("Show last messages", isOn: $showChatPreviews)
                    }
                    settingsRow("rectangle.and.pencil.and.ellipsis", color: theme.colors.secondary) {
                        Toggle("Message draft", isOn: $saveLastDraft)
                    }
                    .onChange(of: saveLastDraft) { saveDraft in
                        if !saveDraft {
                            m.draft = nil
                            m.draftChatId = nil
                        }
                    }
                    settingsRow("link", color: theme.colors.secondary) {
                        Picker("SimpleX links", selection: $simplexLinkMode) {
                            ForEach(
                                SimpleXLinkMode.values + (SimpleXLinkMode.values.contains(simplexLinkMode) ? [] : [simplexLinkMode])
                            ) { mode in
                                Text(mode.text)
                            }
                        }
                    }
                    .frame(height: 36)
                    .onChange(of: simplexLinkMode) { mode in
                        privacySimplexLinkModeDefault.set(mode)
                    }
                } header: {
                    Text("Chats")
                        .foregroundColor(theme.colors.secondary)
                }

                Section {
                    settingsRow("lock.doc", color: theme.colors.secondary) {
                        Toggle("Encrypt local files", isOn: $encryptLocalFiles)
                            .onChange(of: encryptLocalFiles) {
                                setEncryptLocalFiles($0)
                            }
                    }
                    settingsRow("photo", color: theme.colors.secondary) {
                        Toggle("Auto-accept images", isOn: $autoAcceptImages)
                            .onChange(of: autoAcceptImages) {
                                privacyAcceptImagesGroupDefault.set($0)
                            }
                    }
                    settingsRow("circle.filled.pattern.diagonalline.rectangle", color: theme.colors.secondary) {
                        Picker("Blur media", selection: $privacyMediaBlurRadius) {
                            let values = [0, 12, 24, 48] + ([0, 12, 24, 48].contains(privacyMediaBlurRadius) ? [] : [privacyMediaBlurRadius])
                            ForEach(values, id: \.self) { radius in
                                let text: String = switch radius {
                                case 0: NSLocalizedString("Off", comment: "blur media")
                                case 12: NSLocalizedString("Soft", comment: "blur media")
                                case 24: NSLocalizedString("Medium", comment: "blur media")
                                case 48: NSLocalizedString("Strong", comment: "blur media")
                                default: "\(radius)"
                                }
                                Text(text)
                            }
                        }
                    }
                    .frame(height: 36)
                    settingsRow("network.badge.shield.half.filled", color: theme.colors.secondary) {
                        Toggle("Protect IP address", isOn: $askToApproveRelays)
                    }
                } header: {
                    Text("Files")
                        .foregroundColor(theme.colors.secondary)
                } footer: {
                    if askToApproveRelays {
                        Text("The app will ask to confirm downloads from unknown file servers (except .onion).")
                            .foregroundColor(theme.colors.secondary)
                    } else {
                        Text("Without Tor or VPN, your IP address will be visible to file servers.")
                            .foregroundColor(theme.colors.secondary)
                    }
                }

                Section {
                    settingsRow("person", color: theme.colors.secondary) {
                        Toggle("Contacts", isOn: $contactReceipts)
                    }
                    settingsRow("person.2", color: theme.colors.secondary) {
                        Toggle("Small groups (max 20)", isOn: $groupReceipts)
                    }
                } header: {
                    Text("Send delivery receipts to")
                        .foregroundColor(theme.colors.secondary)
                } footer: {
                    VStack(alignment: .leading) {
                        Text("These settings are for your current profile **\(m.currentUser?.displayName ?? "")**.")
                        Text("They can be overridden in contact and group settings.")
                    }
                    .foregroundColor(theme.colors.secondary)
                    .frame(maxWidth: .infinity, alignment: .leading)
                }
                .confirmationDialog(contactReceiptsDialogTitle, isPresented: $contactReceiptsDialogue, titleVisibility: .visible) {
                    Button(contactReceipts ? "Enable (keep overrides)" : "Disable (keep overrides)") {
                        setSendReceiptsContacts(contactReceipts, clearOverrides: false)
                    }
                    Button(contactReceipts ? "Enable for all" : "Disable for all", role: .destructive) {
                        setSendReceiptsContacts(contactReceipts, clearOverrides: true)
                    }
                    Button("Cancel", role: .cancel) {
                        contactReceiptsReset = true
                        contactReceipts.toggle()
                    }
                }
                .confirmationDialog(groupReceiptsDialogTitle, isPresented: $groupReceiptsDialogue, titleVisibility: .visible) {
                    Button(groupReceipts ? "Enable (keep overrides)" : "Disable (keep overrides)") {
                        setSendReceiptsGroups(groupReceipts, clearOverrides: false)
                    }
                    Button(groupReceipts ? "Enable for all" : "Disable for all", role: .destructive) {
                        setSendReceiptsGroups(groupReceipts, clearOverrides: true)
                    }
                    Button("Cancel", role: .cancel) {
                        groupReceiptsReset = true
                        groupReceipts.toggle()
                    }
                }
            }
        }
        .onChange(of: contactReceipts) { _ in
            if contactReceiptsReset {
                contactReceiptsReset = false
            } else {
                setOrAskSendReceiptsContacts(contactReceipts)
            }
        }
        .onChange(of: groupReceipts) { _ in
            if groupReceiptsReset {
                groupReceiptsReset = false
            } else {
                setOrAskSendReceiptsGroups(groupReceipts)
            }
        }
        .onAppear {
            if let u = m.currentUser {
                if contactReceipts != u.sendRcptsContacts {
                    contactReceiptsReset = true
                    contactReceipts = u.sendRcptsContacts
                }
                if groupReceipts != u.sendRcptsSmallGroups {
                    groupReceiptsReset = true
                    groupReceipts = u.sendRcptsSmallGroups
                }
            }
        }
        .alert(item: $alert) { alert in
            switch alert {
            case let .error(title, error):
                return Alert(title: Text(title), message: Text(error))
            }
        }
    }

    private func setEncryptLocalFiles(_ enable: Bool) {
        do {
            try apiSetEncryptLocalFiles(enable)
        } catch let error {
            let err = responseError(error)
            logger.error("apiSetEncryptLocalFiles \(err)")
            alert = .error(title: "Error", error: "\(err)")
        }
    }

    private func setOrAskSendReceiptsContacts(_ enable: Bool) {
        contactReceiptsOverrides = m.chats.reduce(0) { count, chat in
            let sendRcpts = chat.chatInfo.contact?.chatSettings.sendRcpts
            return count + (sendRcpts == nil || sendRcpts == enable ? 0 : 1)
        }
        if contactReceiptsOverrides == 0 {
            setSendReceiptsContacts(enable, clearOverrides: false)
        } else {
            contactReceiptsDialogue = true
        }
    }

    private var contactReceiptsDialogTitle: LocalizedStringKey {
        contactReceipts
        ? "Sending receipts is disabled for \(contactReceiptsOverrides) contacts"
        : "Sending receipts is enabled for \(contactReceiptsOverrides) contacts"
    }

    private func setSendReceiptsContacts(_ enable: Bool, clearOverrides: Bool) {
        Task {
            do {
                if let currentUser = m.currentUser {
                    let userMsgReceiptSettings = UserMsgReceiptSettings(enable: enable, clearOverrides: clearOverrides)
                    try await apiSetUserContactReceipts(currentUser.userId, userMsgReceiptSettings: userMsgReceiptSettings)
                    privacyDeliveryReceiptsSet.set(true)
                    await MainActor.run {
                        var updatedUser = currentUser
                        updatedUser.sendRcptsContacts = enable
                        m.updateUser(updatedUser)
                        if clearOverrides {
                            m.chats.forEach { chat in
                                if var contact = chat.chatInfo.contact {
                                    let sendRcpts = contact.chatSettings.sendRcpts
                                    if sendRcpts != nil && sendRcpts != enable {
                                        contact.chatSettings.sendRcpts = nil
                                        m.updateContact(contact)
                                    }
                                }
                            }
                        }
                    }
                }
            } catch let error {
                alert = .error(title: "Error setting delivery receipts!", error: "Error: \(responseError(error))")
            }
        }
    }

    private func setOrAskSendReceiptsGroups(_ enable: Bool) {
        groupReceiptsOverrides = m.chats.reduce(0) { count, chat in
            let sendRcpts = chat.chatInfo.groupInfo?.chatSettings.sendRcpts
            return count + (sendRcpts == nil || sendRcpts == enable ? 0 : 1)
        }
        if groupReceiptsOverrides == 0 {
            setSendReceiptsGroups(enable, clearOverrides: false)
        } else {
            groupReceiptsDialogue = true
        }
    }

    private var groupReceiptsDialogTitle: LocalizedStringKey {
        groupReceipts
        ? "Sending receipts is disabled for \(groupReceiptsOverrides) groups"
        : "Sending receipts is enabled for \(groupReceiptsOverrides) groups"
    }

    private func setSendReceiptsGroups(_ enable: Bool, clearOverrides: Bool) {
        Task {
            do {
                if let currentUser = m.currentUser {
                    let userMsgReceiptSettings = UserMsgReceiptSettings(enable: enable, clearOverrides: clearOverrides)
                    try await apiSetUserGroupReceipts(currentUser.userId, userMsgReceiptSettings: userMsgReceiptSettings)
                    privacyDeliveryReceiptsSet.set(true)
                    await MainActor.run {
                        var updatedUser = currentUser
                        updatedUser.sendRcptsSmallGroups = enable
                        m.updateUser(updatedUser)
                        if clearOverrides {
                            m.chats.forEach { chat in
                                if var groupInfo = chat.chatInfo.groupInfo {
                                    let sendRcpts = groupInfo.chatSettings.sendRcpts
                                    if sendRcpts != nil && sendRcpts != enable {
                                        groupInfo.chatSettings.sendRcpts = nil
                                        m.updateGroup(groupInfo)
                                    }
                                }
                            }
                        }
                    }
                }
            } catch let error {
                alert = .error(title: "Error setting delivery receipts!", error: "Error: \(responseError(error))")
            }
        }
    }

    private func simplexLockRow(_ value: LocalizedStringKey) -> some View {
        HStack {
            Text("SimpleX Lock")
            Spacer()
            Text(value)
        }
    }
}

enum LAMode: String, Identifiable, CaseIterable {
    case system
    case passcode

    public var id: Self { self }

    var text: LocalizedStringKey {
        switch self {
        case .system: return "System"
        case .passcode: return "Passcode"
        }
    }
}

struct SimplexLockView: View {
    @Binding var prefPerformLA: Bool
    @Binding var currentLAMode: LAMode
    @EnvironmentObject var m: ChatModel
    @EnvironmentObject var theme: AppTheme
    @AppStorage(DEFAULT_LA_NOTICE_SHOWN) private var prefLANoticeShown = false
    @State private var laMode: LAMode = privacyLocalAuthModeDefault.get()
    @AppStorage(DEFAULT_LA_LOCK_DELAY) private var laLockDelay = 30
    @State private var performLA: Bool = UserDefaults.standard.bool(forKey: DEFAULT_PERFORM_LA)
    @State private var selfDestruct: Bool = UserDefaults.standard.bool(forKey: DEFAULT_LA_SELF_DESTRUCT)
    @State private var currentSelfDestruct: Bool = UserDefaults.standard.bool(forKey: DEFAULT_LA_SELF_DESTRUCT)
    @AppStorage(DEFAULT_LA_SELF_DESTRUCT_DISPLAY_NAME) private var selfDestructDisplayName = ""
    @AppStorage(GROUP_DEFAULT_ALLOW_SHARE_EXTENSION, store: groupDefaults) private var allowShareExtension = false
    @State private var performLAToggleReset = false
    @State private var performLAModeReset = false
    @State private var performLASelfDestructReset = false
    @State private var showPasswordAction: PasswordAction? = nil
    @State private var showChangePassword = false
    @State var laAlert: LASettingViewAlert? = nil

    enum LASettingViewAlert: Identifiable {
        case laTurnedOnAlert
        case laFailedAlert
        case laUnavailableInstructionAlert
        case laUnavailableTurningOffAlert
        case laPasscodeSetAlert
        case laPasscodeChangedAlert
        case laSelfDestructPasscodeSetAlert
        case laSelfDestructPasscodeChangedAlert
        case laPasscodeNotChangedAlert

        var id: Self { self }
    }

    enum PasswordAction: Identifiable {
        case enableAuth
        case toggleMode
        case changePasscode
        case enableSelfDestruct
        case changeSelfDestructPasscode
        case selfDestructInfo

        var id: Self { self }
    }

    let laDelays: [Int] = [10, 30, 60, 180, 600, 0]

    func laDelayText(_ t: Int) -> LocalizedStringKey {
        let m = t / 60
        let s = t % 60
        return t == 0
            ? "Immediately"
            : m == 0 || s != 0
            ? "\(s) seconds" // there are no options where both minutes and seconds are needed
            : "\(m) minutes"
    }

    var body: some View {
        VStack {
            List {
                Section("") {
                    Toggle("Enable lock", isOn: $performLA)
                    Picker("Lock mode", selection: $laMode) {
                        ForEach(LAMode.allCases) { mode in
                            Text(mode.text)
                        }
                    }
                    .frame(height: 36)
                    if performLA {
                        Picker("Lock after", selection: $laLockDelay) {
                            let delays = laDelays.contains(laLockDelay) ? laDelays : [laLockDelay] + laDelays
                            ForEach(delays, id: \.self) { t in
                                Text(laDelayText(t))
                            }
                        }
                        .frame(height: 36)
                        if showChangePassword && laMode == .passcode {
                            Button("Change passcode") {
                                changeLAPassword()
                            }
                        }
                    }
                }

                if performLA {
                    Section("Share to SimpleX") {
                        Toggle("Allow sharing", isOn: $allowShareExtension)
                    }
                }
                
                if performLA && laMode == .passcode {
                    Section(header: Text("Self-destruct passcode").foregroundColor(theme.colors.secondary)) {
                        Toggle(isOn: $selfDestruct) {
                            HStack(spacing: 6) {
                                Text("Enable self-destruct")
                                Image(systemName: "info.circle")
                                    .foregroundColor(theme.colors.primary)
                                    .font(.system(size: 14))
                            }
                            .onTapGesture {
                                showPasswordAction = .selfDestructInfo
                            }
                        }
                        if selfDestruct {
                            TextField("New display name", text: $selfDestructDisplayName)
                            Button("Change self-destruct passcode") {
                                changeSelfDestructPassword()
                            }
                        }
                    }
                }
            }
        }
        .onChange(of: performLA) { performLAToggle in
            appLocalAuthEnabledGroupDefault.set(performLAToggle)
            prefLANoticeShown = true
            if performLAToggleReset {
                performLAToggleReset = false
            } else if performLAToggle {
                switch currentLAMode {
                case .system:
                    enableLA()
                case .passcode:
                    resetLA()
                    showPasswordAction = .enableAuth
                }
            } else {
                disableLA()
            }
        }
        .onChange(of: laMode) { _ in
            if performLAModeReset {
                performLAModeReset = false
            } else if prefPerformLA {
                toggleLAMode()
            } else {
                updateLAMode()
            }
        }
        .onChange(of: selfDestruct) { _ in
            if performLASelfDestructReset {
                performLASelfDestructReset = false
            } else if prefPerformLA {
                toggleSelfDestruct()
            }
        }
        .alert(item: $laAlert) { alertItem in
            switch alertItem {
            case .laTurnedOnAlert: return laTurnedOnAlert()
            case .laFailedAlert: return laFailedAlert()
            case .laUnavailableInstructionAlert: return laUnavailableInstructionAlert()
            case .laUnavailableTurningOffAlert: return laUnavailableTurningOffAlert()
            case .laPasscodeSetAlert: return passcodeAlert("Passcode set!")
            case .laPasscodeChangedAlert: return passcodeAlert("Passcode changed!")
            case .laSelfDestructPasscodeSetAlert: return selfDestructPasscodeAlert("Self-destruct passcode enabled!")
            case .laSelfDestructPasscodeChangedAlert: return selfDestructPasscodeAlert("Self-destruct passcode changed!")
            case .laPasscodeNotChangedAlert: return mkAlert(title: "Passcode not changed!")
            }
        }
        .sheet(item: $showPasswordAction) { a in
            switch a {
            case .enableAuth:
                SetAppPasscodeView {
                    m.contentViewAccessAuthenticated = true
                    laLockDelay = 30
                    prefPerformLA = true
                    showChangePassword = true
                    showLAAlert(.laPasscodeSetAlert)
                } cancel: {
                    resetLAEnabled(false)
                }
            case .toggleMode:
                SetAppPasscodeView {
                    laLockDelay = 30
                    updateLAMode()
                    showChangePassword = true
                    showLAAlert(.laPasscodeSetAlert)
                } cancel: {
                    revertLAMode()
                }
            case .changePasscode:
                SetAppPasscodeView {
                    showLAAlert(.laPasscodeChangedAlert)
                } cancel: {
                    showLAAlert(.laPasscodeNotChangedAlert)
                }
            case .enableSelfDestruct:
                SetAppPasscodeView(
                    passcodeKeychain: kcSelfDestructPassword,
                    prohibitedPasscodeKeychain: kcAppPassword,
                    title: "Set passcode",
                    reason: NSLocalizedString("Enable self-destruct passcode", comment: "set passcode view")
                ) {
                    updateSelfDestruct()
                    showLAAlert(.laSelfDestructPasscodeSetAlert)
                } cancel: {
                    revertSelfDestruct()
                }
            case .changeSelfDestructPasscode:
                SetAppPasscodeView(
                    passcodeKeychain: kcSelfDestructPassword,
                    prohibitedPasscodeKeychain: kcAppPassword,
                    reason: NSLocalizedString("Change self-destruct passcode", comment: "set passcode view")
                ) {
                    showLAAlert(.laSelfDestructPasscodeChangedAlert)
                } cancel: {
                    showLAAlert(.laPasscodeNotChangedAlert)
                }
            case .selfDestructInfo:
                selfDestructInfoView()
            }
        }
        .onAppear {
            showChangePassword = prefPerformLA && currentLAMode == .passcode
        }
        .onDisappear() {
            m.laRequest = nil
        }
    }

    private func selfDestructInfoView() -> some View {
        VStack(alignment: .leading) {
            Text("Self-destruct")
                .font(.largeTitle)
                .bold()
                .padding(.vertical)
            ScrollView {
                VStack(alignment: .leading) {
                    Group {
                        Text("If you enter your self-destruct passcode while opening the app:")
                        VStack(spacing: 8) {
                            textListItem("1.", "All app data is deleted.")
                            textListItem("2.", "App passcode is replaced with self-destruct passcode.")
                            textListItem("3.", "An empty chat profile with the provided name is created, and the app opens as usual.")
                        }
                    }
                    .padding(.bottom)
                }
            }
        }
        .frame(maxWidth: .infinity)
        .padding()
    }

    private func  showLAAlert(_ a: LASettingViewAlert) {
        DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) {
            laAlert = a
        }
    }

    private func toggleLAMode() {
        authenticate(reason: NSLocalizedString("Change lock mode", comment: "authentication reason")) { laResult in
            switch laResult {
            case .failed:
                revertLAMode()
                laAlert = .laFailedAlert
            case .success:
                switch laMode {
                case .system:
                    updateLAMode()
                    authenticate(reason: NSLocalizedString("Enable SimpleX Lock", comment: "authentication reason")) { laResult in
                        switch laResult {
                        case .success:
                            _ = kcAppPassword.remove()
                            resetSelfDestruct()
                            laAlert = .laTurnedOnAlert
                        case .failed, .unavailable:
                            currentLAMode = .passcode
                            privacyLocalAuthModeDefault.set(.passcode)
                            revertLAMode()
                            laAlert = .laFailedAlert
                        }
                    }
                case .passcode:
                    showPasswordAction = .toggleMode
                }
            case .unavailable:
                disableUnavailableLA()
            }
        }
    }

    private func toggleSelfDestruct() {
        authenticate(reason: NSLocalizedString("Change self-destruct mode", comment: "authentication reason")) { laResult in
            switch laResult {
            case .failed:
                revertSelfDestruct()
                laAlert = .laFailedAlert
            case .success:
                if selfDestruct {
                    showPasswordAction = .enableSelfDestruct
                } else {
                    resetSelfDestruct()
                }
            case .unavailable:
                disableUnavailableLA()
            }
        }
    }

    private func changeLAPassword() {
        authenticate(title: "Current Passcode", reason: NSLocalizedString("Change passcode", comment: "authentication reason")) { laResult in
            switch laResult {
            case .failed: laAlert = .laFailedAlert
            case .success: showPasswordAction = .changePasscode
            case .unavailable: disableUnavailableLA()
            }
        }
    }

    private func changeSelfDestructPassword() {
        authenticate(reason: NSLocalizedString("Change self-destruct passcode", comment: "authentication reason")) { laResult in
            switch laResult {
            case .failed: laAlert = .laFailedAlert
            case .success: showPasswordAction = .changeSelfDestructPasscode
            case .unavailable: disableUnavailableLA()
            }
        }
    }

    private func enableLA() {
        resetLA()
        authenticate(reason: NSLocalizedString("Enable SimpleX Lock", comment: "authentication reason")) { laResult in
            switch laResult {
            case .success:
                m.contentViewAccessAuthenticated = true
                prefPerformLA = true
                laAlert = .laTurnedOnAlert
            case .failed:
                resetLAEnabled(false)
                laAlert = .laFailedAlert
            case .unavailable:
                disableUnavailableLA()
            }
        }
    }

    private func disableUnavailableLA() {
        resetLAEnabled(false)
        laMode = .system
        updateLAMode()
        laAlert = .laUnavailableInstructionAlert
    }

    private func disableLA() {
        authenticate(reason: NSLocalizedString("Disable SimpleX Lock", comment: "authentication reason")) { laResult in
            switch (laResult) {
            case .success:
                prefPerformLA = false
                resetLA()
            case .failed:
                resetLAEnabled(true)
                laAlert = .laFailedAlert
            case .unavailable:
                prefPerformLA = false
                laAlert = .laUnavailableTurningOffAlert
            }
        }
    }

    private func resetLA() {
        _ = kcAppPassword.remove()
        laLockDelay = 30
        showChangePassword = false
        resetSelfDestruct()
    }

    private func resetLAEnabled(_ onOff: Bool) {
        prefPerformLA = onOff
        performLAToggleReset = true
        withAnimation { performLA = onOff }
    }

    private func revertLAMode() {
        performLAModeReset = true
        withAnimation { laMode = currentLAMode }
    }

    private func updateLAMode() {
        currentLAMode = laMode
        privacyLocalAuthModeDefault.set(laMode)
    }

    private func resetSelfDestruct() {
        _ = kcSelfDestructPassword.remove()
        selfDestruct = false
        updateSelfDestruct()
    }

    private func revertSelfDestruct() {
        performLASelfDestructReset = true
        withAnimation { selfDestruct = currentSelfDestruct }
    }

    private func updateSelfDestruct() {
        UserDefaults.standard.set(selfDestruct, forKey: DEFAULT_LA_SELF_DESTRUCT)
        currentSelfDestruct = selfDestruct
    }

    private func passcodeAlert(_ title: LocalizedStringKey) -> Alert {
        mkAlert(title: title, message: "Please remember or store it securely - there is no way to recover a lost passcode!")
    }

    private func selfDestructPasscodeAlert(_ title: LocalizedStringKey) -> Alert {
        mkAlert(title: title, message: "If you enter this passcode when opening the app, all app data will be irreversibly removed!")
    }
}

struct PrivacySettings_Previews: PreviewProvider {
    static var previews: some View {
        PrivacySettings()
    }
}
