import SwiftUI

struct GenerationStringIssuesView<T>: View where T: Hashable {

    let text: String

    let statusWhenNonEmpty: IssueStatus

    let items: Set<T>

    let map: (T) -> String

    @State
    private var showList = false

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

    init(text: String, statusWhenNonEmpty: IssueStatus = .error, items: Set<T>, map: @escaping (T) -> String) {
        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.map(map).sorted(), id: \.self) { item in
                    Text(item)
                }
                .frame(minHeight: 400)
                Button("Close") { showList = false }
            }.padding()
        }
    }

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

extension GenerationStringIssuesView where T == String {

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