import SwiftUI
import SFSafeSymbols

private struct TextWithSymbol: Comparable, Identifiable {

    let symbol: SFSymbol

    let color: Color

    let text: String

    static func < (lhs: TextWithSymbol, rhs: TextWithSymbol) -> Bool {
        lhs.text < rhs.text
    }

    var id: String {
        text
    }
}

struct PageContentResultsView: View {

    @Environment(\.language)
    private var language

    @ObservedObject
    var results: PageGenerationResults

    private var totalFileCount: Int {
        results.usedFiles.count + results.missingFiles.count + results.missingLinkedFiles.count
    }

    private var allFiles: [TextWithSymbol] {
        results.usedFiles.map {
            TextWithSymbol(
                symbol: $0.type.category.symbol,
                color: .blue,
                text: $0.identifier)
        }
        + results.missingFiles.keys.map {
            TextWithSymbol(
                symbol: .questionmarkCircleFill,
                color: .red,
                text: $0)
        }
        + results.missingLinkedFiles.keys.map {
            TextWithSymbol(
                symbol: .questionmarkCircleFill,
                color: .red,
                text: $0)
        }
    }

    private var totalLinkCount: Int {
        results.externalLinks.count +
        results.missingLinkedPages.count +
        results.linkedPages.count +
        results.missingLinkedTags.count +
        results.linkedTags.count
    }

    private var allLinks: [TextWithSymbol] {
        results.externalLinks.map {
            TextWithSymbol(
                symbol: .network,
                color: .blue,
                text: $0)
        }
        + results.missingLinkedPages.keys.map {
            TextWithSymbol(
                symbol: .document,
                color: .red,
                text: $0)
        }
        + results.linkedPages.map {
            TextWithSymbol(
                symbol: .documentBadgePlus,
                color: .blue,
                text: $0.title(in: language))
        }
        + results.missingLinkedTags.keys.map {
            TextWithSymbol(
                symbol: .tagSlash,
                color: .red,
                text: $0)
        }
        + results.linkedTags.map {
            TextWithSymbol(
                symbol: .tag,
                color: .blue,
                text: $0.title(in: language))
        }
    }
    
    var body: some View {
        HStack {
            PopupWithList(
                symbol: .photoOnRectangleAngled,
                text: "\(totalFileCount) files", canShowPopup: totalFileCount > 0) {
                    Text("Files")
                        .font(.title)
                    List {
                        ForEach(allFiles.sorted()) { file in
                            HStack {
                                Image(systemSymbol: file.symbol)
                                    .frame(width: 18)
                                    .foregroundStyle(file.color)
                                Text(file.text)
                            }
                        }
                    }
                    .frame(minHeight: 400)
                }

            PopupWithList(
                symbol: .photoOnRectangleAngled,
                text: "\(totalLinkCount) links", canShowPopup: totalLinkCount > 0) {
                    Text("Links")
                        .font(.title)
                    List {
                        ForEach(allLinks.sorted()) { file in
                            HStack {
                                Image(systemSymbol: file.symbol)
                                    .frame(width: 18)
                                    .foregroundStyle(file.color)
                                Text(file.text)
                            }
                        }
                    }
                    .frame(minHeight: 400)
                }

            if !results.invalidCommands.isEmpty {
                TextWithPopup(
                    symbol: .exclamationmarkTriangleFill,
                    title: "Invalid commands",
                    text: "\(results.invalidCommands.count) invalid commands",
                    items: results.invalidCommands.map { $0.markdown }.sorted())
                .foregroundStyle(.red)
            }
        }
    }
}
