import SwiftUI

struct StorageStatusView: View {

    @EnvironmentObject
    private var content: Content

    @Binding
    var isPresented: Bool

    var title: String {
        switch content.saveState {
        case .storageNotInitialized:
            "No Database Loaded"
        case .savingPausedDueToLoadErrors:
            "Database corrupted"
        case .isSaved:
            "Database is healthy"
        case .needsSave:
            "Database will be saved soon"
        case .failedToSave:
            "Database errors"
        case .isSaving:
            "Database is being saved"
        }
    }

    var subtitle: String {
        switch content.saveState {
        case .storageNotInitialized:
            "To start editing the content of a website, create a new database or load an existing one. Open a folder with an existing database, or choose an empty folder to create a new project."
        case .savingPausedDueToLoadErrors:
            "The errors loading the database are listed below. Saving has been disabled to prevent data corruption. Enable saving to save the partially loaded data."
        case .isSaved:
            "All data is saved to disk"
        case .needsSave:
            "Wait for a few seconds until the remaining changes are saved."
        case .failedToSave:
            "The errors while saving the database are listed below."
        case .isSaving:
            "Changes are being written to disk"
        }
    }

    var buttonText: String {
        switch content.saveState {
        case .storageNotInitialized:
            "Choose folder"
        case .savingPausedDueToLoadErrors:
            "Save partial data"
        case .isSaved, .isSaving, .needsSave:
            "Save database"
        case .failedToSave:
            "Attempt save again"
        }
    }

    var body: some View {
        VStack {
            Text(title)
                .font(.title)
                .padding()
            Text(subtitle)
                .multilineTextAlignment(.center)

            List(content.storageErrors) { error in
                VStack {
                    Text(error.message)
                    Text(error.date.formatted())
                        .font(.footnote)
                }
            }
            .frame(minHeight: 300)
            Button(buttonText, action: saveButtonPressed)
                .padding()
                .disabled(content.saveState == .isSaving)
            Button("Dismiss", action: { isPresented = false })
                .padding()
        }
        .padding()
    }

    func saveButtonPressed() {
        switch content.saveState {
        case .storageNotInitialized:
            selectContentPath()
        case .savingPausedDueToLoadErrors:
            content.resumeSavingAfterLoadingErrors()
        case .isSaved, .needsSave, .failedToSave:
            content.saveUnconditionally()
        case .isSaving:
            break
        }
    }

    private func selectContentPath() {
        let panel = NSOpenPanel()
        // Sets up so user can only select a single directory
        panel.canChooseFiles = false
        panel.canChooseDirectories = true
        panel.allowsMultipleSelection = false
        panel.showsHiddenFiles = false
        panel.title = "Select the database folder"

        let response = panel.runModal()
        guard response == .OK else {
            content.storageErrors.append(.init(message: "Failed to select a folder: \(response)"))
            return
        }
        guard let url = panel.url else {
            content.storageErrors.append(.init(message: "No url found for selected content folder"))
            return
        }

        guard content.storage.save(contentPath: url) else {
            content.storageErrors.append(.init(message: "Failed to set content path"))
            return
        }
        content.loadFromDisk { }
    }
}
