/**
 * A supplementary function to deal with Safari's annoying lack
 * of support for lookbehind in regular expressions.
 * @param text The text to extract
 * @returns A string containing a decimal with at most a single dot
 * and at most a single negative symbol
 */
const NOT_DIGITS = /\D/g
const NOT_DIGITS_NOR_DOT = /[^\d.]/g
// const NOT_DIGITS_NOR_NEGATIVE = /[^\d\-]/g
// const NOT_DIGITS_NOR_NEGATIVE_NOR_DOT = /[^\d\.\-]/g
function extractProperDecimal(text?: string) {
  if (!text) return ''
  let filteredText = text

  // Removes extra dots
  const dotIndex = text.indexOf('.')
  if (dotIndex > -1) {
    filteredText = `${filteredText.slice(0, dotIndex)}.${filteredText.slice(dotIndex + 1).replace(NOT_DIGITS, '')}`
  }

  // Removes extra negative symbols
  const negativeIndex = text.indexOf('-')
  if (negativeIndex > 0) {
    // negative symbol is not the first character, get rid of it
    filteredText = `${filteredText.slice(0, dotIndex)}${filteredText.slice(dotIndex + 1).replace(NOT_DIGITS_NOR_DOT, '')}`
  } else if (negativeIndex === 0) {
    // negative symbol is the first character, get rid of the others
    filteredText = `-${filteredText.slice(dotIndex + 1).replace(NOT_DIGITS_NOR_DOT, '')}`
  }

  return filteredText
}

export function extractNumbers(text?: string) {
  return text ? text.replace(/\D/g, '') : ''
}

export function extractDecimal(text?: string) {
  if (!text) return ''
  const filteredText = extractProperDecimal(text.replace(/[^\d.]/g, ''))
  // .replace(/(?=<\..*)\./g, '')
  if (filteredText === '.') return '0.'
  if (/[^0]/g.test(filteredText)) {
    return filteredText.replace(/^0+(?!\.)/, '')
  }
  return '0'
}

export function extractLetters(text?: string) {
  if (!text) return ''
  return text.replace(/[^A-Za-z]/g, '')
}

export function extractLettersAndNumbers(text?: string) {
  if (!text) return ''
  return text.replace(/[^0-9A-Za-z]/g, '')
}

export function extractCurrency(text?: string) {
  if (!text) return ''
  if (text.startsWith('R$')) {
    // Texto já está no formato BRL
    const filteredText = extractProperDecimal(
      text
        .replace(/[^\d,]/g, '')
        .replace(/[,]/g, '.')
        // .replace(/(?<=\..*)\./g, '')
        .replace(/^0+(?!\.)/, '')
    )
    if (filteredText === '.') return '0.'
    if (/\.\d{3,}$/.test(filteredText)) return filteredText.slice(0, filteredText.length - 1)
    return filteredText
  } else {
    // caso especial para toFixed
    if (/\.\d{0,2}$/.test(text)) return text
    else if (/\.\d{3,}$/.test(text)) return text.slice(0, text.indexOf('.') + 3)
    else return text
  }
}

export function extractCVC(text: string) {
  const filteredText = extractNumbers(text)
  return filteredText.slice(0, 3)
}

export function extractCEP(text: string) {
  const filteredText = extractNumbers(text)
  return filteredText.slice(0, 8)
}

export function extractCPF(text: string) {
  const filteredText = extractNumbers(text)
  return filteredText.slice(0, 11)
}

export function extractCNPJ(text: string) {
  const filteredText = extractNumbers(text)
  return filteredText.slice(0, 14)
}

export function extractCPFCNPJ(text: string) {
  const filteredText = extractNumbers(text)
  return filteredText.slice(0, 14)
}

export function extractPhone(text: string) {
  const filteredText = extractNumbers(text)
  return filteredText.slice(0, 11)
}

export function extractFIPE(text: string) {
  const filteredText = extractNumbers(text)
  return filteredText.slice(0, 7)
}

export function extractUF(text: string) {
  const filteredText = extractLetters(text)
  return filteredText.slice(0, 2).toUpperCase()
}

export function extractLicensePlate(text: string) {
  const filteredText = extractLettersAndNumbers(text)
  return filteredText.slice(0, 7).toUpperCase()
}

export function extractChassis(text: string) {
  const filteredText = extractLettersAndNumbers(text)
  return filteredText.slice(0, 17).toUpperCase()
}

export function extractDate(date: Date) {
  if (date !== null) {
    date.setHours(0, 0, 0, 0)
  }
  return date
}
