import SwiftUI

struct ExportSettings: View {
    @ObservedObject private var model = ImportExportSettingsModel.shared
    @State private var presentingShareSheet = false
    @StateObject private var settings = SettingsModel.shared

    private var filesToShare = [ImportExportSettingsModel.exportFile]
    @ObservedObject private var navigation = NavigationModel.shared

    var body: some View {
        Group {
            #if os(macOS)
                VStack {
                    list

                    importExportButtons
                }
            #else
                list
                #if os(iOS)
                .listStyle(.insetGrouped)
                .sheet(
                    isPresented: $presentingShareSheet,
                    onDismiss: { self.model.isExportInProgress = false }
                ) {
                    ShareSheet(activityItems: filesToShare)
                        .id("settings-share-\(filesToShare.count)")
                }
                #endif
            #endif
        }
        #if os(iOS)
        .toolbar {
            ToolbarItem(placement: .confirmationAction) {
                exportButton
            }
        }
        #endif
        .navigationTitle("Export Settings")
    }

    var list: some View {
        List {
            exportView
        }
        .onAppear {
            model.reset()
        }
    }

    var importExportButtons: some View {
        HStack {
            importButton

            Spacer()

            exportButton
        }
    }

    @ViewBuilder var importButton: some View {
        #if os(macOS)
            Button {
                navigation.presentingSettingsFileImporter = true
            } label: {
                Label("Import", systemImage: "square.and.arrow.down")
            }
        #endif
    }

    struct ExportGroupRow: View {
        let group: ImportExportSettingsModel.ExportGroup

        @ObservedObject private var model = ImportExportSettingsModel.shared

        var body: some View {
            Button(action: { model.toggleExportGroupSelection(group) }) {
                HStack {
                    Text(group.label.localized())
                    Spacer()
                    Image(systemName: "checkmark")
                        .foregroundColor(.accentColor)
                        .opacity(isGroupInSelectedGroups ? 1 : 0)
                }
                .animation(nil, value: isGroupInSelectedGroups)
                .contentShape(Rectangle())
            }
        }

        var isGroupInSelectedGroups: Bool {
            model.selectedExportGroups.contains(group)
        }
    }

    var exportView: some View {
        Group {
            Section(header: Text("Settings")) {
                ForEach(ImportExportSettingsModel.ExportGroup.settingsGroups) { group in
                    ExportGroupRow(group: group)
                }
            }

            Section(header: Text("Locations")) {
                ForEach(ImportExportSettingsModel.ExportGroup.locationsGroups) { group in
                    ExportGroupRow(group: group)
                        .disabled(!model.isGroupEnabled(group))
                }
            }

            Section(header: Text("Other"), footer: otherGroupsFooter) {
                ForEach(ImportExportSettingsModel.ExportGroup.otherGroups) { group in
                    ExportGroupRow(group: group)
                }
            }
        }
        .buttonStyle(.plain)
        .disabled(model.isExportInProgress)
    }

    var exportButton: some View {
        Button(action: exportSettings) {
            Text(model.isExportInProgress ? "In progress..." : "Export")
                .animation(nil, value: model.isExportInProgress)
            #if !os(macOS)
                .foregroundColor(.accentColor)
                .frame(maxWidth: .infinity, alignment: .leading)
                .contentShape(Rectangle())
            #endif
        }
        .disabled(!model.isExportAvailable)
    }

    @ViewBuilder var otherGroupsFooter: some View {
        Text("Other data include last used playback preferences and listing options")
    }

    func exportSettings() {
        let export = {
            model.isExportInProgress = true
            Delay.by(0.3) {
                model.exportAction()
                #if !os(macOS)
                    self.presentingShareSheet = true
                #endif
            }
        }

        if model.isGroupSelected(.accountsUnencryptedPasswords) {
            settings.presentAlert(Alert(
                title: Text("Are you sure you want to export unencrypted passwords?"),
                message: Text("Do not share this file with anyone or you can lose access to your accounts. If you don't select to export passwords you will be asked to provide them during import"),
                primaryButton: .destructive(Text("Export"), action: export),
                secondaryButton: .cancel()
            ))
        } else {
            export()
        }
    }
}

struct ExportSettings_Previews: PreviewProvider {
    static var previews: some View {
        NavigationView {
            ExportSettings()
        }
    }
}