/**
 * 图片展示逻辑工具函数
 * 基于设计稿规则：大图、小图、超小图的不同展示策略
 */

// 设计稿中的常量类型
export interface ImageDisplayConstants {
  W_MAX: number
  H_MAX: number
  W_MIN: number
  H_MIN: number
  RATIO_MIN: number
  RATIO_MAX: number
}

// 设计稿中的常量
export const IMAGE_DISPLAY_CONSTANTS: ImageDisplayConstants = {
  // 最大宽度和高度 (50%聊天区域)
  W_MAX: 372, // 6/12 Columns，实际像素值需要根据设备调整
  H_MAX: 372, // 与 W_MAX 相等

  // 最小宽度和高度
  W_MIN: 48,
  H_MIN: 48,

  // 比例限制
  RATIO_MIN: 9 / 21, // 最小比例 (高图极值)
  RATIO_MAX: 21 / 9, // 最大比例 (宽图极值)
}

export interface ImageDimensions {
  width: number
  height: number
}

export interface CalculatedImageSize extends ImageDimensions {
  type: 'large' | 'small' | 'tiny'
  ratio: number
}

/**
 * 限制数值在指定范围内
 */
function clamp(value: number, min: number, max: number): number {
  return Math.min(Math.max(value, min), max)
}

/**
 * 判断图片类型
 */
export function getImageType(
  originalWidth: number,
  originalHeight: number,
  constants: ImageDisplayConstants = IMAGE_DISPLAY_CONSTANTS
): 'large' | 'small' | 'tiny' {
  const { W_MAX, H_MAX, W_MIN, H_MIN } = constants

  // A. 大图：原图尺寸超过展示区域内支持的最大横图或最大竖图的图片
  const isLargeImage =
    (originalWidth >= W_MAX && originalHeight > (9 / 21) * H_MAX) ||
    (originalHeight >= H_MAX && originalWidth > (9 / 21) * W_MAX)

  if (isLargeImage) {
    return 'large'
  }

  // C. 超小图：原图至少有一边小于最小宽度或高度的图片
  const isTinyImage = originalWidth < W_MIN || originalHeight < H_MIN

  if (isTinyImage) {
    return 'tiny'
  }

  // B. 小图：其他情况
  return 'small'
}

/**
 * 计算最终的图片展示比例
 */
export function calculateDisplayRatio(
  originalWidth: number,
  originalHeight: number,
  imageType: 'large' | 'small' | 'tiny',
  constants: ImageDisplayConstants = IMAGE_DISPLAY_CONSTANTS
): number {
  const originalRatio = originalWidth / originalHeight

  if (imageType === 'large') {
    // 大图：限制比例范围 9:21 到 21:9
    return clamp(originalRatio, constants.RATIO_MIN, constants.RATIO_MAX)
  } else {
    // 小图和超小图：保持原始比例
    return originalRatio
  }
}

/**
 * 计算最终的图片展示尺寸
 */
export function calculateImageDisplaySize(
  originalWidth: number,
  originalHeight: number,
  constants: ImageDisplayConstants = IMAGE_DISPLAY_CONSTANTS
): CalculatedImageSize {
  const { W_MAX, H_MAX, W_MIN, H_MIN } = constants

  // 1. 确定图片类型
  const imageType = getImageType(originalWidth, originalHeight, constants)

  // 2. 确定展示比例
  const displayRatio = calculateDisplayRatio(originalWidth, originalHeight, imageType, constants)

  // 3. 计算最终尺寸
  let finalWidth: number
  let finalHeight: number

  if (imageType === 'large') {
    // A大图：撑满最大宽度或高度，根据比例计算另一边
    if (displayRatio >= 1) {
      // 宽图
      finalWidth = W_MAX
      finalHeight = W_MAX / displayRatio
    } else {
      // 高图
      finalHeight = H_MAX
      finalWidth = H_MAX * displayRatio
    }
  } else if (imageType === 'small') {
    // B小图：使用原图尺寸，当原图中有超出最大范围的边则使用对应的最大值
    if (displayRatio >= 1) {
      // 宽图
      finalHeight = originalHeight
      finalWidth = Math.min(originalWidth, W_MAX)
    } else {
      // 高图
      finalWidth = originalWidth
      finalHeight = Math.min(originalHeight, H_MAX)
    }
  } else {
    // C超小图：先将短边放大至最小值，再根据原图比例计算另一边，然后对比另一边是否超过最大值限制
    if (displayRatio >= 1) {
      // 宽图
      finalHeight = H_MIN
      finalWidth = Math.min(H_MIN * displayRatio, W_MAX)
    } else {
      // 高图
      finalWidth = W_MIN
      finalHeight = Math.min(W_MIN / displayRatio, H_MAX)
    }
  }

  return {
    width: Math.round(finalWidth),
    height: Math.round(finalHeight),
    type: imageType,
    ratio: displayRatio,
  }
}

/**
 * 根据容器宽度调整图片展示常量（响应式）
 */
export function adjustImageConstantsForContainer(containerWidth: number): ImageDisplayConstants {
  // 计算50%聊天区域的实际像素值
  const maxSize = Math.min(containerWidth * 0.5, 372) // 不超过设计稿最大值

  return {
    ...IMAGE_DISPLAY_CONSTANTS,
    W_MAX: maxSize,
    H_MAX: maxSize,
  }
}
