const {
  formatMagnitudeNumber,
  getOption,
  normalizeIndex,
  selectBestUnit
} = require('../calculator-helpers.js')

const KIND_OPTIONS = [
  { key: 'resistor', label: '电阻' },
  { key: 'capacitor', label: '电容' }
]

const RESISTOR_FORMAT_OPTIONS = [
  { key: '3digit', label: '3位' },
  { key: '4digit', label: '4位' },
  { key: 'eia96', label: 'EIA-96' }
]

const CAPACITOR_FORMAT_OPTIONS = [
  { key: '3digit', label: '3位' },
  { key: '4digit', label: '4位' },
  { key: 'eia198', label: 'EIA-198' }
]

const RESISTOR_UNITS = [
  { label: 'mΩ', factor: 1e-3 },
  { label: 'Ω', factor: 1 },
  { label: 'kΩ', factor: 1e3 },
  { label: 'MΩ', factor: 1e6 },
  { label: 'GΩ', factor: 1e9 }
]

const CAPACITOR_UNITS = [
  { label: 'pF', factor: 1e-12 },
  { label: 'nF', factor: 1e-9 },
  { label: 'μF', factor: 1e-6 },
  { label: 'mF', factor: 1e-3 },
  { label: 'F', factor: 1 }
]

const EIA_96_VALUES = [
  100, 102, 105, 107, 110, 113, 115, 118, 121, 124, 127, 130,
  133, 137, 140, 143, 147, 150, 154, 158, 162, 165, 169, 174,
  178, 182, 187, 191, 196, 200, 205, 210, 215, 221, 226, 232,
  237, 243, 249, 255, 261, 267, 274, 280, 287, 294, 301, 309,
  316, 324, 332, 340, 348, 357, 365, 374, 383, 392, 402, 412,
  422, 432, 442, 453, 464, 475, 487, 499, 511, 523, 536, 549,
  562, 576, 590, 604, 619, 634, 649, 665, 681, 698, 715, 732,
  750, 768, 787, 806, 825, 845, 866, 887, 909, 931, 953, 976
]

const EIA_96_MULTIPLIERS = {
  A: 1,
  B: 10,
  C: 100,
  D: 1000,
  E: 10000,
  F: 100000,
  H: 10,
  R: 0.01,
  S: 0.1,
  X: 0.1,
  Y: 0.01,
  Z: 0.001
}

const EIA_198_VALUES = {
  A: 1.0,
  B: 1.1,
  C: 1.2,
  D: 1.3,
  E: 1.5,
  F: 1.6,
  G: 1.8,
  H: 2.0,
  J: 2.2,
  K: 2.4,
  a: 2.5,
  L: 2.7,
  M: 3.0,
  N: 3.3,
  b: 3.5,
  P: 3.6,
  Q: 3.9,
  d: 4.0,
  R: 4.3,
  e: 4.5,
  S: 4.7,
  f: 5.0,
  T: 5.1,
  U: 5.6,
  m: 6.0,
  V: 6.2,
  W: 6.8,
  n: 7.0,
  X: 7.5,
  t: 8.0,
  Y: 8.2,
  y: 9.0,
  Z: 9.1
}

const EIA_198_MULTIPLIERS = {
  0: 1,
  1: 10,
  2: 100,
  3: 1000,
  4: 10000,
  5: 100000,
  6: 1000000,
  7: 10000000,
  8: 0.01,
  9: 0.1
}

function formatNumber(value) {
  return formatMagnitudeNumber(value, { fallbackText: '' })
}

function formatValue(baseValue, units, fallbackIndex = 0) {
  const unit = selectBestUnit(units, baseValue, fallbackIndex).unit

  return `${formatNumber(baseValue / unit.factor)} ${unit.label}`
}

function sanitizeCode(text) {
  return String(text === undefined || text === null ? '' : text).trim().replace(/\s+/g, '')
}

function parseDecimalCode(code, unitName) {
  if (!/^[0-9]*[Rr][0-9]+$/.test(code)) return null

  const normalized = code.replace(/[Rr]/, '.')
  const value = Number(normalized)
  if (!Number.isFinite(value)) throw new Error('编码格式无效')

  return {
    formula: `${code} = ${formatNumber(value)} ${unitName}`,
    value
  }
}

function parseDigitCode(code, significantDigits, unitName) {
  const decimalParsed = parseDecimalCode(code, unitName)
  if (decimalParsed) return decimalParsed

  if (!new RegExp(`^\\d{${significantDigits + 1}}$`).test(code)) {
    throw new Error(`请输入${significantDigits + 1}位数字编码`)
  }

  if (/^0+$/.test(code)) {
    return {
      formula: `${code} = 0 ${unitName}`,
      value: 0
    }
  }

  const significant = Number(code.slice(0, significantDigits))
  const multiplier = Number(code.slice(significantDigits))
  const value = significant * Math.pow(10, multiplier)

  return {
    formula: `${significant} × 10^${multiplier} ${unitName}`,
    value
  }
}

function parseEia96(code) {
  const normalized = code.toUpperCase()
  const match = normalized.match(/^(\d{2})([A-Z])$/)
  if (!match) throw new Error('请输入2位数字加1位字母')

  const valueIndex = Number(match[1])
  const multiplier = EIA_96_MULTIPLIERS[match[2]]
  if (valueIndex < 1 || valueIndex > 96 || multiplier === undefined) {
    throw new Error('EIA-96编码无效')
  }

  const baseValue = EIA_96_VALUES[valueIndex - 1]

  return {
    formula: `${match[1]}=${baseValue}，${match[2]}=×${formatNumber(multiplier)}`,
    value: baseValue * multiplier
  }
}

function parseEia198(code) {
  const match = code.match(/^([A-Za-z])(\d)$/) || code.match(/^(\d)([A-Za-z])$/)
  if (!match) throw new Error('请输入1位字母加1位数字')

  const letter = Number.isNaN(Number(match[1])) ? match[1] : match[2]
  const digit = Number.isNaN(Number(match[1])) ? match[2] : match[1]
  const baseValue = EIA_198_VALUES[letter]
  const multiplier = EIA_198_MULTIPLIERS[digit]
  if (baseValue === undefined || multiplier === undefined) {
    throw new Error('EIA-198编码无效')
  }

  return {
    formula: `${letter}=${formatNumber(baseValue)}，${digit}=×${formatNumber(multiplier)}pF`,
    value: baseValue * multiplier * 1e-12
  }
}

function calculate(kindKey, formatKey, codeText) {
  const code = sanitizeCode(codeText)
  if (!code) {
    return {
      formulaText: '',
      resultText: '--',
      errorText: ''
    }
  }

  try {
    if (kindKey === 'capacitor') {
      const parsed = formatKey === 'eia198'
        ? parseEia198(code)
        : parseDigitCode(code, formatKey === '4digit' ? 3 : 2, 'pF')
      const value = formatKey === 'eia198' ? parsed.value : parsed.value * 1e-12

      return {
        formulaText: parsed.formula,
        resultText: formatValue(value, CAPACITOR_UNITS),
        errorText: ''
      }
    }

    const parsed = formatKey === 'eia96'
      ? parseEia96(code)
      : parseDigitCode(code, formatKey === '4digit' ? 3 : 2, 'Ω')

    return {
      formulaText: parsed.formula,
        resultText: formatValue(parsed.value, RESISTOR_UNITS, 1),
      errorText: ''
    }
  } catch (error) {
    return {
      formulaText: '',
      resultText: '--',
      errorText: error.message || '编码格式无效'
    }
  }
}

function buildState(source = {}) {
  const kindIndex = normalizeIndex(source.smdKindIndex, KIND_OPTIONS, 0)
  const kind = getOption(KIND_OPTIONS, kindIndex)
  const formatOptions = kind.key === 'capacitor' ? CAPACITOR_FORMAT_OPTIONS : RESISTOR_FORMAT_OPTIONS
  const currentFormatKey = source.smdFormatKey || (source.smdFormatOptions && source.smdFormatOptions[source.smdFormatIndex || 0] && source.smdFormatOptions[source.smdFormatIndex || 0].key)
  let formatIndex = formatOptions.findIndex((item) => item.key === currentFormatKey)
  if (formatIndex < 0) formatIndex = normalizeIndex(source.smdFormatIndex, formatOptions, 0)
  const format = getOption(formatOptions, formatIndex)
  const codeText = sanitizeCode(source.smdCodeText)
  const result = calculate(kind.key, format.key, codeText)

  return {
    smdCodeText: codeText,
    smdErrorText: result.errorText,
    smdFormatIndex: formatIndex,
    smdFormatKey: format.key,
    smdFormatOptions: formatOptions,
    smdFormatText: format.label,
    smdFormulaText: result.formulaText,
    smdKindIndex: kindIndex,
    smdKindKey: kind.key,
    smdKindOptions: KIND_OPTIONS,
    smdKindText: kind.label,
    smdResultText: result.resultText
  }
}

function createInitialState() {
  return buildState({
    smdCodeText: '',
    smdFormatIndex: 0,
    smdKindIndex: 0
  })
}

function updateState(state, changedData = {}) {
  return buildState({
    ...state,
    ...changedData
  })
}

module.exports = {
  CAPACITOR_FORMAT_OPTIONS,
  KIND_OPTIONS,
  RESISTOR_FORMAT_OPTIONS,
  createInitialState,
  updateState
}
