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) { _ in
            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
            }
        }
    }
}
