/**
 * Dynamic Unit System
 * 
 * Handles dynamic unit conversion and display for product parameters.
 * Base units: storage=GB, bandwidth=Mbps, cpu=Core
 */

const UNIT_CONVERSIONS = {
  cpu: { Core: 1 },
  bandwidth_up: { Mbps: 1, Gbps: 1000 },
  bandwidth_down: { Mbps: 1, Gbps: 1000 },
  storage: { GB: 1, TB: 1024 },
  ipv4: { '个': 1 },
  ipv6: { '个': 1 },
  custom: {}
}

const BASE_UNITS = {
  cpu: 'Core',
  bandwidth_up: 'Mbps',
  bandwidth_down: 'Mbps',
  storage: 'GB',
  ipv4: '个',
  ipv6: '个',
  custom: ''
}

const DEFAULT_DISPLAY_UNITS = {
  cpu: 'Core',
  bandwidth_up: 'Mbps',
  bandwidth_down: 'Mbps',
  storage: 'GB',
  ipv4: '个',
  ipv6: '个',
  custom: ''
}

const ARG_KEY_OPTIONS = [
  { label: 'CPU (cpu)', value: 'cpu' },
  { label: 'IPv4', value: 'ipv4' },
  { label: 'IPv6', value: 'ipv6' },
  { label: '上行带宽 (bandwidth_up)', value: 'bandwidth_up' },
  { label: '下行带宽 (bandwidth_down)', value: 'bandwidth_down' },
  { label: '存储空间 (storage)', value: 'storage' },
  { label: '自定义 (custom)', value: 'custom' }
]

/**
 * Convert value between units
 * @param {number} value
 * @param {string} fromUnit
 * @param {string} toUnit
 * @param {string} argKey - e.g. 'storage', 'bandwidth_up'
 */
export function convertUnit(value, fromUnit, toUnit, argKey) {
  if (value === null || value === undefined || fromUnit === toUnit) return value
  const conversions = UNIT_CONVERSIONS[argKey]
  if (!conversions || !conversions[fromUnit] || !conversions[toUnit]) return value
  const baseValue = value * conversions[fromUnit]
  return baseValue / conversions[toUnit]
}

/**
 * Convert from display unit to base unit for storage/submission
 */
export function toBaseUnit(value, displayUnit, argKey) {
  const baseUnit = BASE_UNITS[argKey]
  if (!baseUnit || !displayUnit) return value
  return convertUnit(value, displayUnit, baseUnit, argKey)
}

/**
 * Convert from base unit to display unit for showing in UI
 */
export function fromBaseUnit(value, displayUnit, argKey) {
  const baseUnit = BASE_UNITS[argKey]
  if (!baseUnit || !displayUnit) return value
  return convertUnit(value, baseUnit, displayUnit, argKey)
}

/**
 * Get base unit string for a given argKey
 */
export function getBaseUnit(argKey) {
  return BASE_UNITS[argKey] || ''
}

/**
 * Get default display unit for a given argKey
 */
export function getDefaultDisplayUnit(argKey) {
  return DEFAULT_DISPLAY_UNITS[argKey] || ''
}

/**
 * Get all available units for a parameter type
 */
export function getAvailableUnits(argKey) {
  const conversions = UNIT_CONVERSIONS[argKey]
  return conversions ? Object.keys(conversions) : []
}

/**
 * Get argKey select options
 */
export function getArgKeyOptions() {
  return ARG_KEY_OPTIONS
}

/**
 * Check if a parameter has dynamic unit enabled.
 * Returns true when arg_key maps to a known unit type with multiple selectable units.
 */
export function hasUnit(param) {
  if (!param) return false
  const argKey = param.argKey || param.arg_key || param.key || ''
  if (!argKey || !(argKey in UNIT_CONVERSIONS)) return false
  return Object.keys(UNIT_CONVERSIONS[argKey]).length > 1
}

/**
 * Get the argKey from a parameter object (handles camelCase, snake_case, and plain key)
 */
export function getArgKey(param) {
  if (!param) return ''
  return param.argKey || param.arg_key || param.key || ''
}

/**
 * Get the available units from a parameter object
 */
export function getParamUnits(param) {
  if (!hasUnit(param)) return []
  const argKey = getArgKey(param)
  const paramUnits = param.availableUnits || param.available_units
  if (paramUnits && paramUnits.length > 0) return paramUnits
  return getAvailableUnits(argKey)
}

/**
 * Get the default unit from a parameter object
 */
export function getParamDefaultUnit(param) {
  if (!hasUnit(param)) return ''
  const argKey = getArgKey(param)
  return param.defaultUnit || param.default_unit || getDefaultDisplayUnit(argKey)
}

/**
 * Validate if a unit is valid for a parameter type
 */
export function isValidUnit(unit, argKey) {
  const conversions = UNIT_CONVERSIONS[argKey]
  return conversions && Object.prototype.hasOwnProperty.call(conversions, unit)
}

export function formatValueWithUnit(value, unit) {
  if (value === null || value === undefined || value === '') return '-'
  return unit ? `${value} ${unit}` : String(value)
}
