//
//  UIImage.swift
//  Mastodon
//
//  Created by sxiaojian on 2021/3/8.
//

import CoreImage
import CoreImage.CIFilterBuiltins
import UIKit

extension UIImage {
    public static func placeholder(
        size: CGSize = CGSize(width: 1, height: 1),
        color: UIColor,
        cornerRadius: CGFloat = 0
    ) -> UIImage {
        let render = UIGraphicsImageRenderer(size: size)

        return render.image { (context: UIGraphicsImageRendererContext) in
            // set clear fill
            context.cgContext.setFillColor(color.cgColor)
            
            let rect = CGRect(origin: .zero, size: size)
            
            // clip corner if needs
            if cornerRadius > 0 {
                let path = UIBezierPath(roundedRect: rect, cornerRadius: cornerRadius).cgPath
                context.cgContext.addPath(path)
                context.cgContext.clip(using: .evenOdd)
            }
            
            // set fill
            context.fill(rect)
        }
    }
}

// refs: https://www.hackingwithswift.com/example-code/media/how-to-read-the-average-color-of-a-uiimage-using-ciareaaverage
extension UIImage {
    @available(iOS 14.0, *)
    public var dominantColor: UIColor? {
        guard let inputImage = CIImage(image: self) else { return nil }

        let filter = CIFilter.areaAverage()
        filter.inputImage = inputImage
        filter.extent = inputImage.extent
        guard let outputImage = filter.outputImage else { return nil }

        var bitmap = [UInt8](repeating: 0, count: 4)
        let context = CIContext(options: [.workingColorSpace: kCFNull])
        context.render(outputImage, toBitmap: &bitmap, rowBytes: 4, bounds: CGRect(x: 0, y: 0, width: 1, height: 1), format: .RGBA8, colorSpace: nil)

        return UIColor(red: CGFloat(bitmap[0]) / 255, green: CGFloat(bitmap[1]) / 255, blue: CGFloat(bitmap[2]) / 255, alpha: CGFloat(bitmap[3]) / 255)
    }
}

extension UIImage {
    public var domainLumaCoefficientsStyle: UIUserInterfaceStyle? {
        guard let brightness = cgImage?.brightness else { return nil }
        return brightness > 100 ? .light : .dark // 0 ~ 255
    }
}

extension UIImage {
    public func blur(radius: CGFloat) -> UIImage? {
        guard let inputImage = CIImage(image: self) else { return nil }
        let blurFilter = CIFilter.gaussianBlur()
        blurFilter.inputImage = inputImage
        blurFilter.radius = Float(radius)
        guard let outputImage = blurFilter.outputImage else { return nil }
        guard let cgImage = CIContext().createCGImage(outputImage, from: outputImage.extent) else { return nil }
        let image = UIImage(cgImage: cgImage, scale: scale, orientation: imageOrientation)
        return image
    }
}

extension UIImage {
    public func withRoundedCorners(radius: CGFloat? = nil) -> UIImage? {
        let maxRadius = min(size.width, size.height) / 2
        let cornerRadius: CGFloat = {
            guard let radius = radius, radius > 0 else { return maxRadius }
            return min(radius, maxRadius)
        }()

        let render = UIGraphicsImageRenderer(size: size)
        return render.image { (_: UIGraphicsImageRendererContext) in
            let rect = CGRect(origin: .zero, size: size)
            UIBezierPath(roundedRect: rect, cornerRadius: cornerRadius).addClip()
            draw(in: rect)
        }
    }
}

extension UIImage {
    public static func adaptiveUserInterfaceStyleImage(lightImage: UIImage, darkImage: UIImage) -> UIImage {
        let imageAsset = UIImageAsset()
        imageAsset.register(lightImage, with: UITraitCollection(traitsFrom: [
            UITraitCollection(displayScale: 1.0),
            UITraitCollection(userInterfaceStyle: .light)
        ]))
        imageAsset.register(darkImage, with: UITraitCollection(traitsFrom: [
            UITraitCollection(displayScale: 1.0),
            UITraitCollection(userInterfaceStyle: .dark)
        ]))
        return imageAsset.image(with: UITraitCollection.current)
    }
}