const removeHash = (hex: string) => (hex.charAt(0) === '#' ? hex.slice(1) : hex)

function parseHex(nakedHex: string) {
  const isShort = (
    nakedHex.length === 3
    || nakedHex.length === 4
  )

  const twoDigitHexR = isShort ? `${nakedHex.slice(0, 1)}${nakedHex.slice(0, 1)}` : nakedHex.slice(0, 2)
  const twoDigitHexG = isShort ? `${nakedHex.slice(1, 2)}${nakedHex.slice(1, 2)}` : nakedHex.slice(2, 4)
  const twoDigitHexB = isShort ? `${nakedHex.slice(2, 3)}${nakedHex.slice(2, 3)}` : nakedHex.slice(4, 6)
  const twoDigitHexA = ((isShort ? `${nakedHex.slice(3, 4)}${nakedHex.slice(3, 4)}` : nakedHex.slice(6, 8)) || 'ff')

  // const numericA = +((parseInt(a, 16) / 255).toFixed(2));

  return {
    r: twoDigitHexR,
    g: twoDigitHexG,
    b: twoDigitHexB,
    a: twoDigitHexA,
  }
}

const hexToDecimal = (hex: string) => Number.parseInt(hex, 16)

function hexesToDecimals({
  r,
  g,
  b,
  a,
}) {
  return {
    r: hexToDecimal(r),
    g: hexToDecimal(g),
    b: hexToDecimal(b),
    a: +((hexToDecimal(a) / 255).toFixed(2)),
  }
}

const isNumeric = n => !Number.isNaN(Number.parseFloat(n)) && Number.isFinite(n)

function formatRgb(decimalObject: any, parameterA: any) {
  const {
    r,
    g,
    b,
    a: parsedA,
  } = decimalObject
  const a = isNumeric(parameterA) ? parameterA : parsedA

  return `rgba(${r}, ${g}, ${b}, ${a})`
}

/**
 * Turns an old-fashioned css hex color value into a rgb color value.
 *
 * If you specify an alpha value, you'll get a rgba() value instead.
 *
 * @param hex value to convert. ('123456'. '#123456', ''123', '#123')
 * @param a value to apply. (optional) ('0.5', '0.25')
 * @return rgb or rgba value. ('rgb(11, 22, 33)'. 'rgba(11, 22, 33, 0.5)')
 */
export function hexToRgba(hex: string, a: any) {
  const hashlessHex = removeHash(hex)
  const hexObject = parseHex(hashlessHex)
  const decimalObject = hexesToDecimals(hexObject)

  return formatRgb(decimalObject, a)
}
