import SwiftUI

struct FileListView: View {

    @EnvironmentObject
    private var content: Content

    @Binding
    var selectedFile: FileResource?

    @State
    private var selectedFileType: FileTypeCategory? = nil

    @State
    private var searchString = ""

    let allowedType: FileTypeCategory?

    init(selectedFile: Binding<FileResource?>, allowedType: FileTypeCategory? = nil) {
        self._selectedFile = selectedFile
        self.allowedType = allowedType
    }

    var filesBySelectedType: [FileResource] {
        guard let selectedFileType else {
            return content.files
        }
        return content.files.filter { selectedFileType == $0.type.category }
    }

    var filteredFiles: [FileResource] {
        guard !searchString.isEmpty else {
            return filesBySelectedType
        }
        return filesBySelectedType.filter { $0.identifier.contains(searchString) }
    }

    var body: some View {
        VStack(alignment: .center) {
            if allowedType == nil {
                Picker("", selection: $selectedFileType) {
                    let all: FileTypeCategory? = nil
                    Text("All").tag(all)
                    ForEach(FileTypeCategory.allCases) { type in
                        Text(type.text).tag(type)
                    }
                }
                .pickerStyle(.menu)
                .padding(.trailing, 7)
            }
            TextField("", text: $searchString, prompt: Text("Search"))
                .textFieldStyle(.roundedBorder)
                .padding(.horizontal, 8)
            ScrollView {
                LazyVStack(spacing: 0) {
                    ForEach(filteredFiles) { file in
                        SelectableListItem(selected: selectedFile == file) {
                            Text(file.identifier)
                                .lineLimit(1)
                        }
                        .id(file.identifier)
                        .onTapGesture {
                            selectedFile = file
                        }
                    }
                }
                .padding(.horizontal, 8)
            }
            .onChange(of: selectedFileType) { oldValue, newValue in
                guard oldValue != newValue else {
                    return
                }
                let newFile = filteredFiles.first

                guard let selectedFile else {
                    if let newFile {
                        DispatchQueue.main.async {
                            selectedFile = newFile
                        }
                    }
                    return
                }

                if newValue == selectedFile.type.category {
                    return
                }
                DispatchQueue.main.async {
                    self.selectedFile = newFile
                }
            }
        }
        .onAppear {
            if let allowedType {
                selectedFileType = allowedType
            }
            if selectedFile == nil {
                selectedFile = content.files.first
            }
        }
    }
}

#Preview {
    NavigationSplitView {
        FileListView(selectedFile: .constant(nil))
            .environmentObject(Content.mock)
            .navigationSplitViewColumnWidth(250)
    } detail: {
        Text("")
            .frame(width: 50)
    }
}
