import Foundation

struct ImageSet: HtmlProducer {

    let image: FileResource

    let type: FileType

    let maxWidth: Int

    let maxHeight: Int

    let quality: CGFloat

    let description: String?

    let extraAttributes: String

    init(image: FileResource, type: FileType? = nil, maxWidth: Int, maxHeight: Int, description: String?, quality: CGFloat = 0.7, extraAttributes: String? = nil) {
        self.image = image
        self.type = type ?? image.type
        self.maxWidth = maxWidth
        self.maxHeight = maxHeight
        self.description = description
        self.quality = quality
        self.extraAttributes = extraAttributes ?? ""
    }

    var jobs: [ImageVersion] {
        let width2x = maxWidth * 2
        let height2x = maxHeight * 2

        return [
            .init(image: image, type: .avif, maximumWidth: maxWidth, maximumHeight: maxHeight, quality: quality),
            .init(image: image, type: .avif, maximumWidth: width2x, maximumHeight: height2x, quality: quality),
            .init(image: image, type: .webp, maximumWidth: maxWidth, maximumHeight: maxHeight, quality: quality),
            .init(image: image, type: .webp, maximumWidth: width2x, maximumHeight: height2x, quality: quality),
            .init(image: image, type: type, maximumWidth: maxWidth, maximumHeight: maxHeight, quality: quality),
            .init(image: image, type: type, maximumWidth: width2x, maximumHeight: height2x, quality: quality)
        ]
    }

    private var imageAltText: String {
        guard let description else {
            return ""
        }
        return " alt='\(description.htmlEscaped())'"
    }

    func populate(_ result: inout String) {
        let fileExtension = image.type.fileExtension.map { "." + $0 } ?? ""

        let prefix1x = "/\(image.outputImageFolder)/\(maxWidth)x\(maxHeight)"
        let prefix2x = "/\(image.outputImageFolder)/\(maxWidth*2)x\(maxHeight*2)"

        let aspectRatio = (image.getImageDimensions()?.scaledToFit(in: .init(width: maxWidth, height: maxHeight)))
            .map { " aspect-ratio='\(Int($0.width)) / \(Int($0.height))'" }

        result += "<picture>"
        result += "<source type='image/avif' srcset='\(prefix1x).avif 1x, \(prefix2x).avif 2x'/>"
        result += "<source type='image/webp' srcset='\(prefix1x).webp 1x, \(prefix1x).webp 2x'/>"
        result += "<img srcset='\(prefix2x)\(fileExtension) 2x' src='\(prefix1x)\(fileExtension)'\(aspectRatio ?? "") loading='lazy'\(imageAltText)\(extraAttributes)/>"
        result += "</picture>"
    }
}
