import SwiftUI

struct GenerationIssuesView<S, T, V>: View where S: Collection, T: Hashable & Comparable, V: View, S.Element == T {

    let text: String

    let statusWhenNonEmpty: IssueStatus

    @Binding
    var items: S

    let map: (T) -> V

    @State
    private var showList = false

    var status: IssueStatus {
        items.isEmpty ? .nominal : statusWhenNonEmpty
    }

    init(text: String, statusWhenNonEmpty: IssueStatus = .error, items: Binding<S>, map: @escaping (T) -> V) {
        self.text = text
        self.statusWhenNonEmpty = statusWhenNonEmpty
        self._items = items
        self.map = map
    }

    var body: some View {
        HStack {
            Button(action: showListIfNonEmpty) {
                Image(systemSymbol: status.symbol)
                    .foregroundStyle(status.color)
            }.buttonStyle(.plain)
            Text("\(items.count) \(text)")
        }
        .sheet(isPresented: $showList) {
            VStack {
                Text("\(items.count) \(text)")
                    .font(.title)
                List(items.sorted(), id: \.self) { item in
                    map(item)
                }
                .frame(minHeight: 400)
                Button("Close") { showList = false }
            }.padding()
        }
    }

    private func showListIfNonEmpty() {
        guard !items.isEmpty else {
            return
        }
        showList = true
    }
}

extension GenerationIssuesView where S == Set<String>, V == Text {

    init(text: String, statusWhenNonEmpty: IssueStatus = .error, items: Binding<Set<String>>) {
        self.text = text
        self.statusWhenNonEmpty = statusWhenNonEmpty
        self._items = items
        self.map = { Text($0) }
    }
}
