import SwiftUI

struct FileDetailView: View {

    @EnvironmentObject
    private var content: Content

    @ObservedObject
    var file: FileResource

    @State
    private var showFileSelection = false

    @State
    private var selectedFile: FileResource?

    var body: some View {
        VStack(alignment: .leading) {
            DetailTitle(
                title: "File",
                text: "A file that can be used in a post or page")

            VStack(alignment: .leading) {
                Button("Show in Finder", action: showFileInFinder)
                Button("Mark as changed", action: markFileAsChanged)
                Button("Delete resource", action: deleteFile)
                if file.isExternallyStored {
                    Button("Import file", action: replaceFile)
                } else {
                    Button("Replace file", action: replaceFile)
                    Button("Make external", action: convertToExternal)
                }
            }

            IdPropertyView(
                id: $file.id,
                title: "Name",
                footer: "The unique name of the file, which is also used to reference it in posts and pages.",
                validation: file.isValid,
                update: { file.update(id: $0) })

            StringPropertyView(
                title: "German Description",
                text: $file.german,
                footer: "The description for the file in German. Descriptions are used for images and to explain the content of a file.")

            StringPropertyView(
                title: "English Description",
                text: $file.english,
                footer: "The description for the file in English. Descriptions are used for images and to explain the content of a file.")

            if let imageDimensions = file.imageDimensions {
                GenericPropertyView(title: "Image dimensions") {
                    Text("\(Int(imageDimensions.width)) x \(Int(imageDimensions.height)) (\(file.aspectRatio))")
                }
                #warning("Add button to show image versions")
            }
            if let fileSize = file.fileSize {
                GenericPropertyView(title: "File size") {
                    Text(formatBytes(fileSize))
                }
            }
            Spacer()
        }.padding()
            .onAppear {
                if file.fileSize == nil {
                    file.determineFileSize()
                }
            }
    }

    private func formatBytes(_ bytes: Int) -> String {
        let formatter = ByteCountFormatter()
        formatter.allowedUnits = [.useMB, .useKB, .useBytes] // Customize units if needed
        formatter.countStyle = .file
        return formatter.string(fromByteCount: Int64(bytes))
    }

    private func showFileInFinder() {
        content.storage.openFinderWindow(withSelectedFile: file.id)
    }

    private func markFileAsChanged() {
        DispatchQueue.main.async {
            file.determineImageDimensions()
            file.determineFileSize()
            // Force regeneration of images and/or file copying
            file.removeFileFromOutputFolder()
            // Trigger content view update to reload image
            file.didChange()
        }
    }

    private func replaceFile() {
        guard let url = openFilePanel() else {
            print("File '\(file.id)': No file selected as replacement")
            return
        }
        guard content.storage.importExternalFile(at: url, fileId: file.id) else {
            print("File '\(file.id)': Failed to replace file")
            return
        }

        markFileAsChanged()
        if file.isExternallyStored {
            DispatchQueue.main.async {
                file.isExternallyStored = false
            }
        }
    }

    private func openFilePanel() -> URL? {
        let panel = NSOpenPanel()

        panel.canChooseFiles = true
        panel.canChooseDirectories = false
        panel.allowsMultipleSelection = false
        panel.showsHiddenFiles = false
        panel.title = "Select file to replace"
        panel.prompt = ""

        let response = panel.runModal()
        guard response == .OK else {
            print("File '\(file.id)': Failed to select file to replace")
            return nil
        }

        return panel.url
    }

    private func convertToExternal() {
        guard !file.isExternallyStored else {
            return
        }

        guard content.storage.delete(file: file.id) else {
            print("File '\(file.id)': Failed to delete file to make it external")
            return
        }
        DispatchQueue.main.async {
            file.fileSize = nil
            file.isExternallyStored = true
        }
    }

    private func deleteFile() {
        if !file.isExternallyStored {
            guard content.storage.delete(file: file.id) else {
                print("File '\(file.id)': Failed to delete file in content folder")
                return
            }
        }
        content.remove(file)
    }
}

extension FileDetailView: MainContentView {

    init(item: FileResource) {
        self.init(file: item)
    }

    static let itemDescription = "a file"
}


#Preview {
    FileDetailView(file: .mock)
}
