import Foundation
import SwiftUI
import UIKit

struct LoadIconView: View {
    let remoteIconURLString: String?
    let fallbackSystemName: String
    let fallbackColor: Color
    let size: CGFloat

    private var cornerRadius: CGFloat {
        max(6, size / 4)
    }

    @State private var cachedImage: Image?
    @State private var isLoading = false
    @State private var hasAttemptedLoad = false

    var body: some View {
        Group {
            if let cachedImage {
                cachedImage
                    .resizable()
                    .scaledToFit()
                    .frame(width: size, height: size)
                    .clipShape(RoundedRectangle(cornerRadius: cornerRadius))
            } else if let url = remoteURL, !hasAttemptedLoad {
                ProgressView()
                    .frame(width: size, height: size)
                    .task(id: url) {
                        await loadImage(from: url)
                    }
            } else {
                fallbackView
            }
        }
        .frame(width: size, height: size)
        .onChange(of: remoteIconURLString) { oldValue, newValue in
            guard oldValue != newValue else { return }
            cachedImage = nil
            hasAttemptedLoad = false
        }
    }

    private var fallbackView: some View {
        ZStack {
            RoundedRectangle(cornerRadius: cornerRadius)
                .fill(fallbackColor)
            Image(systemName: fallbackSystemName.isEmpty ? "lightbulb" : fallbackSystemName)
                .font(.system(size: size * 0.5))
                .foregroundColor(.white)
        }
    }

    private var remoteURL: URL? {
        guard let remoteIconURLString, let url = URL(string: remoteIconURLString) else { return nil }
        return url
    }

    private func loadImage(from url: URL) async {
        guard !isLoading else { return }
        isLoading = true
        defer { isLoading = false }

        if let uiImage = try? await IconCache.shared.image(for: url) {
            await MainActor.run {
                cachedImage = Image(uiImage: uiImage)
                hasAttemptedLoad = true
            }
        } else {
            await MainActor.run {
                cachedImage = nil
                hasAttemptedLoad = true
            }
        }
    }
}

struct ComponentSummaryMetricView: View {
    let icon: String
    let label: String
    let value: String
    let tint: Color

    var body: some View {
        VStack(alignment: .leading, spacing: 2) {
            HStack(spacing: 6) {
                Image(systemName: icon)
                    .font(.system(size: 14, weight: .semibold))
                    .foregroundStyle(tint)
                Text(value)
                    .font(.body.weight(.semibold))
                    .lineLimit(1)
                    .minimumScaleFactor(0.85)
            }
            Text(label.uppercased())
                .font(.caption2)
                .fontWeight(.medium)
                .foregroundStyle(.secondary)
                .lineLimit(1)
        }
    }
}

struct ComponentMetricBadgeView: View {
    let label: String
    let value: String
    let tint: Color

    var body: some View {
        VStack(alignment: .leading, spacing: 2) {
            Text(label.uppercased())
                .font(.caption2)
                .fontWeight(.medium)
                .foregroundStyle(.secondary)
                .lineLimit(1)
            Text(value)
                .font(.subheadline.weight(.semibold))
                .foregroundStyle(tint)
                .lineLimit(1)
                .minimumScaleFactor(0.85)
        }
        .padding(.horizontal, 12)
        .padding(.vertical, 8)
        .background(
            RoundedRectangle(cornerRadius: 10, style: .continuous)
                .fill(tint.opacity(0.12))
        )
    }
}

extension Color {
    static func componentColor(named colorName: String) -> Color {
        switch colorName {
        case "blue": return .blue
        case "green": return .green
        case "orange": return .orange
        case "red": return .red
        case "purple": return .purple
        case "yellow": return .yellow
        case "pink": return .pink
        case "teal": return .teal
        case "indigo": return .indigo
        case "mint": return .mint
        case "cyan": return .cyan
        case "brown": return .brown
        case "gray": return .gray
        default: return .blue
        }
    }
}
