import type { GradientColor } from '@/lvgl-widgets/type'

/**
 * 将 rgba/rgb 转换为 hex8
 */
function rgbaToHex8(rgbaStr: string): string {
  const match = rgbaStr.match(/rgba?\((\d+),\s*(\d+),\s*(\d+)(?:,\s*([\d.]+))?\)/)
  if (!match) return rgbaStr

  const r = parseInt(match[1]).toString(16).padStart(2, '0')
  const g = parseInt(match[2]).toString(16).padStart(2, '0')
  const b = parseInt(match[3]).toString(16).padStart(2, '0')
  let a = 'ff'
  if (match[4]) {
    const alpha = parseFloat(match[4])
    a = Math.round(alpha * 255)
      .toString(16)
      .padStart(2, '0')
  }

  return `#${r}${g}${b}${a}`.toUpperCase()
}

/**
 * 分隔 CSS 参数（处理嵌套括号）
 * 例如: "0deg, rgba(0,0,0,1) 0%" -> ["0deg", "rgba(0,0,0,1) 0%"]
 */
function splitArgs(str: string): string[] {
  const result: string[] = []
  let current = ''
  let depth = 0

  for (let i = 0; i < str.length; i++) {
    const char = str[i]
    if (char === '(') depth++
    if (char === ')') depth--
    if (char === ',' && depth === 0) {
      result.push(current.trim())
      current = ''
    } else {
      current += char
    }
  }
  result.push(current.trim())
  return result
}

/**
 * hex 转 rgba，支持 #RGB、#RRGGBB、#RRGGBBAA
 * @param hex 十六进制颜色
 * @param alpha 透明度 0-1
 */
export function hexToRgba(hex: string, alpha: number): string {
  if (!hex || !hex.startsWith('#')) return hex
  let r = 0,
    g = 0,
    b = 0
  const h = hex.slice(1)
  if (h.length === 3) {
    r = parseInt(h[0] + h[0], 16)
    g = parseInt(h[1] + h[1], 16)
    b = parseInt(h[2] + h[2], 16)
  } else if (h.length === 6 || h.length === 8) {
    r = parseInt(h.slice(0, 2), 16)
    g = parseInt(h.slice(2, 4), 16)
    b = parseInt(h.slice(4, 6), 16)
  } else {
    return hex
  }
  return `rgba(${r}, ${g}, ${b}, ${alpha})`
}

/**
 * [工具] hex8 (#RRGGBBAA) 转 rgba
 */
function hex8ToRgba(hex: string): string {
  if (!/^#[0-9A-F]{8}$/i.test(hex)) return hex
  const r = parseInt(hex.slice(1, 3), 16)
  const g = parseInt(hex.slice(3, 5), 16)
  const b = parseInt(hex.slice(5, 7), 16)
  const a = (parseInt(hex.slice(7, 9), 16) / 255).toFixed(2)
  // 去掉 a 末尾多余的 0 和点
  const alpha = parseFloat(a)
  return `rgba(${r}, ${g}, ${b}, ${alpha})`
}

/**
 * 核心方法：将渐变对象转换回 CSS 字符串
 */
export function generateCssGradient(
  config: GradientColor,
  width?: number,
  height?: number
): string {
  const { type, points, direction, angle, center } = config

  // 1. 处理颜色点部分
  const stops = (points || [])
    // 优先按照 LVGL 渐变位置（0~255）排序
    .sort((a, b) => {
      const pa = a.point
      const pb = b.point
      return pa - pb
    })
    .map((p) => {
      // LVGL 渐变位置 0~255 映射为 CSS 0~100%
      const percent = p.point !== undefined ? Math.round((p.point / 255) * 100) : p.point
      return `${hex8ToRgba(p.color)} ${percent}%`
    })
    .join(', ')

  // 2. 根据类型组装前缀和参数
  if (type === 'linear') {
    let dirParam = '180deg' // 默认从上到下
    if (angle?.start !== undefined) {
      dirParam = `${angle.start}deg`
    } else if (direction === 'horizontal') {
      dirParam = 'to right'
    } else if (direction === 'vertical') {
      dirParam = 'to bottom'
    }
    return `linear-gradient(${dirParam}, ${stops})`
  }

  if (type === 'radial') {
    const cx = center?.x && width ? (center.x / width) * 100 : 50
    const cy = center?.y && height ? (center.y / height) * 100 : 50
    return `radial-gradient(circle at ${cx}% ${cy}%, ${stops})`
  }

  if (type === 'conical') {
    const startAngle = angle?.start ?? 0
    const cx = center?.x && width ? (center.x / width) * 100 : 50
    const cy = center?.y && height ? (center.y / height) * 100 : 50
    return `conic-gradient(from ${startAngle}deg at ${cx}% ${cy}%, ${stops})`
  }

  return ''
}

/**
 * 解析渐变颜色
 * @param css eg: linear-gradient(0deg, rgba(122, 38, 38, 1) 0%, rgba(0, 0, 0, 1) 100%) / radial-gradient(circle, rgba(71, 17, 17, 1) 0%, rgba(0, 0, 0, 1) 100%)
 * @returns
 */
export function parseCssGradient(css: string): GradientColor | null {
  // 1. 识别渐变类型
  const typeMatch = css.match(/^(linear|radial|conic)-gradient\((.*)\)$/)
  if (!typeMatch) return null

  const rawType = typeMatch[1]
  const content = typeMatch[2]
  const args = splitArgs(content)

  const result: GradientColor = {
    type: rawType === 'conic' ? 'conical' : (rawType as any),
    gradientType: rawType === 'conic' ? 'advanced' : 'gradient',
    points: []
  }

  // 2. 解析颜色点和配置项
  args.forEach((arg, index) => {
    // 判断是否是颜色点 (通常以 % 结尾，或者包含 rgba/rgb/hex)
    const stopMatch = arg.match(/(rgba?\(.*?\)|#[a-fA-F0-9]+)\s+(\d+)%/)

    if (stopMatch) {
      const pointPercent = parseFloat(stopMatch[2])
      result?.points?.push({
        color: rgbaToHex8(stopMatch[1]),
        // 反向计算 LVGL 渐变位置 0~255
        point: Math.round((pointPercent / 100) * 255)
      })
    } else {
      // 处理配置项 (第一个参数可能是角度、位置或形状)
      if (index === 0) {
        if (rawType === 'linear') {
          // 线性渐变方向
          if (arg.includes('deg')) {
            const deg = parseFloat(arg)
            result.angle = { start: deg, end: (deg + 180) % 360 }
            // 简单逻辑映射方向
            if (deg === 0 || deg === 180) result.direction = 'vertical'
            if (deg === 90 || deg === 270) result.direction = 'horizontal'
          } else if (arg.includes('to right')) {
            result.direction = 'horizontal'
          } else if (arg.includes('to top')) {
            result.direction = 'vertical'
          }
        } else if (rawType === 'radial') {
          // 径向渐变中心点 (简单解析)
          result.center = { x: 50, y: 50 } // 默认
          if (arg.includes('at')) {
            const posMatch = arg.match(/at\s+(\d+)%\s+(\d+)%/)
            if (posMatch) {
              result.center = { x: parseFloat(posMatch[1]), y: parseFloat(posMatch[2]) }
            }
          }
        } else if (rawType === 'conic') {
          // 锥形渐变
          const angleMatch = arg.match(/from\s+(\d+)deg/)
          if (angleMatch) {
            result.angle = { start: parseFloat(angleMatch[1]), end: 360 }
          }
        }
      }
    }
  })

  // 如果没有明确定义中心点，给默认值
  if (result.type === 'radial' && !result.center) {
    result.center = { x: 50, y: 50 }
  }

  return result
}
