function toText(value) {
  return String(value === undefined || value === null ? '' : value).trim()
}

function stripHexPrefix(value) {
  return toText(value).replace(/^0x/i, '')
}

function normalizeHexText(value) {
  return toText(value)
    .replace(/0x/gi, '')
    .replace(/[\s,;:_-]/g, ' ')
    .replace(/\s+/g, ' ')
    .trim()
    .toUpperCase()
}

function compactHexText(value) {
  return toText(value)
    .replace(/0x/gi, '')
    .replace(/[\s,;:_-]/g, '')
    .toUpperCase()
}

function validateHexText(value, options = {}) {
  const withoutPrefix = toText(value).replace(/0x/gi, '')
  const compact = withoutPrefix.replace(/[\s,;:_-]/g, '')
  const emptyMessage = options.emptyMessage || '请输入十六进制数据'
  const invalidMessage = options.invalidMessage || '只支持十六进制字符'
  const oddLengthMessage = options.oddLengthMessage || '十六进制长度必须为偶数'

  if (!compact) return emptyMessage
  if (/[^0-9a-fA-F\s,;:_-]/.test(withoutPrefix)) return invalidMessage
  if (compact.length % 2 !== 0) return oddLengthMessage

  return ''
}

function parseHexBytes(value) {
  const compact = compactHexText(value)
  const bytes = []

  for (let index = 0; index < compact.length; index += 2) {
    bytes.push(parseInt(compact.slice(index, index + 2), 16) & 0xFF)
  }

  return bytes
}

function normalizeHexUnitText(value, fallback = '') {
  const text = stripHexPrefix(value).toUpperCase()

  return text || fallback
}

function normalizeHexWordText(value, fallback = '') {
  return normalizeHexUnitText(value, fallback)
}

function normalizeHexDwordText(value, fallback = '') {
  return normalizeHexUnitText(value, fallback)
}

function validateHexWordText(value, label) {
  const text = normalizeHexWordText(value)
  if (!text) return `${label}请输入十六进制`
  if (!/^[0-9A-F]+$/i.test(text)) return `${label}只支持十六进制`
  if (text.length > 4) return `${label}最多 4 位十六进制`

  return ''
}

function validateHexDwordText(value, label) {
  const text = normalizeHexDwordText(value)
  if (!text) return `${label}请输入十六进制`
  if (!/^[0-9A-F]+$/i.test(text)) return `${label}只支持十六进制`
  if (text.length > 8) return `${label}最多 8 位十六进制`

  return ''
}

function parseHexNumber(value, label = '数值', maxValue = 0xFFFF) {
  const text = normalizeHexWordText(value)

  if (!text || !/^[0-9A-F]+$/i.test(text)) {
    throw new Error(`${label}请输入十六进制数值`)
  }

  const parsedValue = parseInt(text, 16)
  if (parsedValue > maxValue) {
    throw new Error(`${label}超出范围`)
  }

  return parsedValue
}

function parseHexDword(value, label = '地址') {
  return parseHexNumber(value, label, 0xFFFFFFFF)
}

function parseHexByte(value, label = '从机地址') {
  const text = normalizeHexWordText(value)

  if (!/^[0-9A-F]{1,2}$/i.test(text)) {
    throw new Error(`${label}需为 00 - FF`)
  }

  return parseInt(text, 16)
}

function normalizeHexByte(value, fallback = '00') {
  const fallbackText = normalizeHexWordText(fallback, '00')
  const text = normalizeHexWordText(value)

  if (!/^[0-9A-F]{1,2}$/i.test(text)) {
    return parseInt(fallbackText || '0', 16).toString(16).toUpperCase().padStart(2, '0')
  }

  return parseInt(text, 16).toString(16).toUpperCase().padStart(2, '0')
}

module.exports = {
  compactHexText,
  normalizeHexDwordText,
  normalizeHexByte,
  normalizeHexText,
  normalizeHexWordText,
  parseHexByte,
  parseHexBytes,
  parseHexDword,
  parseHexNumber,
  stripHexPrefix,
  validateHexDwordText,
  validateHexText,
  validateHexWordText
}
