//
//  IMImageContainerLogic.swift

//
//  Created by Leon on 2025/8/22.
//

import UIKit

/// 设计稿中的常量
struct ImageDisplayConstants {
    var W_MAX: CGFloat
    var H_MAX: CGFloat
    var W_MIN: CGFloat
    var H_MIN: CGFloat
    var RATIO_MIN: CGFloat
    var RATIO_MAX: CGFloat
    
    static let `default` = ImageDisplayConstants(
        W_MAX: 372,
        H_MAX: 372,
        W_MIN: 48,
        H_MIN: 48,
        RATIO_MIN: 9.0 / 21.0,
        RATIO_MAX: 21.0 / 9.0
    )
}

/// 计算结果
struct CalculatedImageSize {
    var width: CGFloat
    var height: CGFloat
    var type: ImageType
    var ratio: CGFloat
}

/// 图片类型
enum ImageType: String {
    case large
    case small
    case tiny
}

/// 工具类
class ImageDisplayLogic {
    
    /// 限制数值范围
    private static func clamp(_ value: CGFloat, min: CGFloat, max: CGFloat) -> CGFloat {
        return Swift.min(Swift.max(value, min), max)
    }
    
    /// 判断图片类型
    static func getImageType(originalWidth: CGFloat,
                             originalHeight: CGFloat,
                             constants: ImageDisplayConstants = .default) -> ImageType {
        let W_MAX = constants.W_MAX
        let H_MAX = constants.H_MAX
        let W_MIN = constants.W_MIN
        let H_MIN = constants.H_MIN
        
        // A. 大图
        let isLargeImage = (
            (originalWidth >= W_MAX && originalHeight > (9.0/21.0) * H_MAX) ||
            (originalHeight >= H_MAX && originalWidth > (9.0/21.0) * W_MAX)
        )
        if isLargeImage { return .large }
        
        // C. 超小图
        let isTinyImage = (originalWidth < W_MIN || originalHeight < H_MIN)
        if isTinyImage { return .tiny }
        
        // B. 小图
        return .small
    }
    
    /// 计算最终展示比例
    static func calculateDisplayRatio(originalWidth: CGFloat,
                                      originalHeight: CGFloat,
                                      imageType: ImageType,
                                      constants: ImageDisplayConstants = .default) -> CGFloat {
        let originalRatio = originalWidth / originalHeight
        if imageType == .large {
            return clamp(originalRatio, min: constants.RATIO_MIN, max: constants.RATIO_MAX)
        } else {
            return originalRatio
        }
    }
    
    /// 计算最终展示尺寸
    static func calculateImageDisplaySize(originalWidth: CGFloat,
                                          originalHeight: CGFloat,
                                          constants: ImageDisplayConstants = .default) -> CalculatedImageSize {
        let W_MAX = constants.W_MAX
        let H_MAX = constants.H_MAX
        let W_MIN = constants.W_MIN
        let H_MIN = constants.H_MIN
        
        // 1. 类型
        let imageType = getImageType(originalWidth: originalWidth, originalHeight: originalHeight, constants: constants)
        
        // 2. 比例
        let displayRatio = calculateDisplayRatio(originalWidth: originalWidth, originalHeight: originalHeight, imageType: imageType, constants: constants)
        
        // 3. 最终尺寸
        var finalWidth: CGFloat = 0
        var finalHeight: CGFloat = 0
        
        switch imageType {
        case .large:
            if displayRatio >= 1 {
                // 宽图
                finalWidth = W_MAX
                finalHeight = W_MAX / displayRatio
            } else {
                // 高图
                finalHeight = H_MAX
                finalWidth = H_MAX * displayRatio
            }
        case .small:
            if displayRatio >= 1 {
                finalHeight = originalHeight
                finalWidth = min(originalWidth, W_MAX)
            } else {
                finalWidth = originalWidth
                finalHeight = min(originalHeight, H_MAX)
            }
        case .tiny:
            if displayRatio >= 1 {
                finalHeight = H_MIN
                finalWidth = min(H_MIN * displayRatio, W_MAX)
            } else {
                finalWidth = W_MIN
                finalHeight = min(W_MIN / displayRatio, H_MAX)
            }
        }
        
        return CalculatedImageSize(
            width: round(finalWidth),
            height: round(finalHeight),
            type: imageType,
            ratio: displayRatio
        )
    }
    
    /// 根据容器宽度调整常量
    static func adjustConstants(for containerWidth: CGFloat) -> ImageDisplayConstants {
        let maxSize = min(containerWidth * 0.5, 372)
        var c = ImageDisplayConstants.default
        c.W_MAX = maxSize
        c.H_MAX = maxSize
        return c
    }
}
