import Foundation
import UIKit

enum CreateClipImageProcessing {
    enum TargetSize {
        case portraitHD
        case custom(_ width: CGFloat, _ height: CGFloat)

        var width: CGFloat {
            switch self {
            case .portraitHD:
                return 1080.0
            case .custom(let width, _):
                return width
            }
        }

        var height: CGFloat {
            switch self {
            case .portraitHD:
                return 1920.0
            case .custom(_, let height):
                return height
            }
        }

        var size: CGSize {
            return .init(width: width, height: height)
        }
    }

    static func resizeByInputRatio(
        image: UIImage,
        sourceType: ClipImageReducer.State.ImageSource.LocalSourceType,
        fitFillThreshold: CGFloat,
        targetSize: TargetSize
    ) -> UIImage? {
        let reformattedImage: UIImage?
        switch sourceType {
        case .takenByCamera:
            reformattedImage = CreateClipImageProcessing
                .resizeAspectFillImage(image: image, targetSize: targetSize)

        case .imported:
            let incomingRatio = image.size.height / image.size.width
            if incomingRatio >= fitFillThreshold {
                reformattedImage = CreateClipImageProcessing
                    .resizeAspectFillImage(image: image, targetSize: targetSize)
            } else {
                reformattedImage = CreateClipImageProcessing
                    .aspectFitImageWithBlackBackground(image: image, targetSize: .portraitHD)
            }
        }

        return reformattedImage
    }

    static func resizeAspectFillImage(image: UIImage, targetSize: TargetSize) -> UIImage? {
        let renderer = UIGraphicsImageRenderer(size: targetSize.size)

        let scaledImage = renderer.image { _ in
            let aspectWidth = targetSize.width / image.size.width
            let aspectHeight = targetSize.height / image.size.height
            let aspectRatio = max(aspectWidth, aspectHeight) // Aspect fill, use max ratio

            let newImageSize = CGSize(width: image.size.width * aspectRatio, height: image.size.height * aspectRatio)

            // Calculate origin to center the image
            let origin = CGPoint(
                x: (targetSize.width - newImageSize.width) / 2.0,
                y: (targetSize.height - newImageSize.height) / 2.0
            )

            image.draw(in: CGRect(origin: origin, size: newImageSize))
        }

        return scaledImage
    }

    static func aspectFitImageWithBlackBackground(
        image: UIImage, targetSize: TargetSize
    ) -> UIImage? {
        let renderer = UIGraphicsImageRenderer(size: targetSize.size)

        let fittedImage = renderer.image { context in
            // Fill the entire background with black color
            UIColor.black.setFill()
            context.fill(CGRect(origin: .zero, size: targetSize.size))

            // Calculate the aspect fit size
            let aspectWidth = targetSize.width / image.size.width
            let aspectHeight = targetSize.height / image.size.height
            let aspectRatio = min(aspectWidth, aspectHeight) // Aspect fit, use the smaller ratio

            let newImageSize = CGSize(width: image.size.width * aspectRatio, height: image.size.height * aspectRatio)

            // Calculate origin to center the image
            let origin = CGPoint(
                x: (targetSize.width - newImageSize.width) / 2,
                y: (targetSize.height - newImageSize.height) / 2
            )

            // Draw the image in the calculated frame
            image.draw(in: CGRect(origin: origin, size: newImageSize))
        }

        return fittedImage
    }
}
