//
//  AvatarImageView.swift
//  ComposeUI
//
//  Created by Shadowfacts on 3/4/23.
//

import SwiftUI

public struct AvatarImageView: View {
    public typealias FetchAvatar = (URL) async -> UIImage?
    
    let url: URL?
    let size: CGFloat
    let style: Style
    let fetchAvatar: FetchAvatar
    @State private var image: UIImage?
    
    public init(url: URL?, size: CGFloat, style: Style, fetchAvatar: @escaping FetchAvatar) {
        self.url = url
        self.size = size
        self.style = style
        self.fetchAvatar = fetchAvatar
    }
    
    public var body: some View {
        imageView
            .resizable()
            .frame(width: size, height: size)
            .clipShape(RoundedRectangle(cornerRadius: style.cornerRadiusFraction * size, style: .continuous))
            .task { @MainActor in
                image = nil
                if let url {
                    image = await fetchAvatar(url)
                }
            }
            // tell swiftui that this view has changed (and therefore the task needs to re-run) when the url changes
            .id(url)
        
    }
    
    private var imageView: Image {
        if let image {
            return Image(uiImage: image)
        } else {
            return placeholder
        }
    }
    
    private var placeholder: Image {
        Image(systemName: style == .roundRect ? "person.crop.square" : "person.crop.circle")
    }
    
    public enum Style: Equatable {
        case roundRect, circle
        
        var cornerRadiusFraction: CGFloat {
            switch self {
            case .roundRect:
                return 0.1
            case .circle:
                return 0.5
            }
        }
    }
}
