import SwiftUI
import SFSafeSymbols

struct InsertableRoute: View, InsertableCommandView {

    @Environment(\.language)
    var language

    final class Model: ObservableObject, InsertableCommandModel {

        @Published
        var caption: String?

        @Published
        var chartTitle: String?

        @Published
        var components: Set<RouteStatisticType> = Set(RouteStatisticType.allCases)

        @Published
        var mapTitle: String?

        @Published
        var selectedImage: FileResource?

        @Published
        var dataFile: FileResource?

        var isReady: Bool {
            selectedImage != nil && dataFile != nil
        }

        init() {

        }

        var command: String? {
            guard let selectedImage,
                  let dataFile else {
                return nil
            }
            var result = ["```route"]
            result.append("\(RouteBlock.Key.image.rawValue): \(selectedImage.identifier)")
            result.append("\(RouteBlock.Key.file.rawValue): \(dataFile.identifier)")
            if components != Set(RouteStatisticType.allCases) {
                let list = components
                    .map { $0.rawValue }
                    .joined(separator: ", ")
                result.append("\(RouteBlock.Key.components.rawValue): \(list)")
            }
            if let caption {
                result.append("\(RouteBlock.Key.caption.rawValue): \(caption)")
            }
            if let chartTitle {
                result.append("\(RouteBlock.Key.chartTitle.rawValue): \(chartTitle)")
            }
            if let mapTitle {
                result.append("\(RouteBlock.Key.mapTitle.rawValue): \(mapTitle)")
            }
            result.append("```")
            return result.joined(separator: "\n")
        }
    }

    static let title = "Route"

    static let sheetTitle = "Insert route map and statistics"

    static let icon: SFSymbol = .map

    @ObservedObject
    private var model: Model

    init(model: Model) {
        self.model = model
    }

    var body: some View {
        VStack {
            FilePropertyView(
                title: "Map Image",
                footer: "Select the image to insert as the map",
                selectedFile: $model.selectedImage,
                allowedType: .image)
            FilePropertyView(
                title: "Data File",
                footer: "Select the file containing the statistics",
                selectedFile: $model.dataFile,
                allowedType: .text)
            OptionalStringPropertyView(
                title: "Map Title",
                text: $model.mapTitle,
                prompt: "Map title",
                footer: "The title to show above the map image")
            OptionalStringPropertyView(
                title: "Map Image Caption",
                text: $model.caption,
                prompt: "Image Caption",
                footer: "The caption to show below the fullscreen map")
            OptionalStringPropertyView(
                title: "Chart Title",
                text: $model.chartTitle,
                prompt: "Title",
                footer: "The title to show above the statistics")
            ForEach(RouteStatisticType.allCases.sorted(), id: \.rawValue) { type in
                Toggle(isOn: Binding(
                    get: {
                        model.components.contains(type)
                    },
                    set: { isSelected in
                        if isSelected {
                            model.components.insert(type)
                        } else {
                            model.components.remove(type)
                        }
                    }
                )) {
                    Text(type.displayText(in: language))
                }.toggleStyle(.checkbox)
            }
        }
    }
}

#Preview {
    InsertableRoute(model: .init())
}
