/* eslint-disable no-shadow */
/* eslint-disable no-unused-expressions */
/* eslint-disable no-use-before-define */
/* eslint-disable no-continue */
import { keys } from 'vuetify/lib/util/helpers'
import { colorToInt, intToHex, colorToHex } from 'vuetify/lib/util/colorUtils'
import * as sRGB from 'vuetify/lib/util/color/transformSRGB'
import * as LAB from 'vuetify/lib/util/color/transformCIELAB'

export function parse (theme, isItem = false, variations = true) {
  const {
    anchor,
    ...variant
  } = theme
  const colors = Object.keys(variant)
  const parsedTheme = {}

  for (let i = 0; i < colors.length; ++i) {
    const name = colors[i]
    const value = theme[name]
    if (value == null) continue

    if (!variations) {
      parsedTheme[name] = {
        base: intToHex(colorToInt(value))
      }
    } else if (isItem) {
      /* istanbul ignore else */
      if (name === 'base' || name.startsWith('lighten') || name.startsWith('darken')) {
        parsedTheme[name] = colorToHex(value)
      }
    } else if (typeof value === 'object') {
      parsedTheme[name] = parse(value, true, variations)
    } else {
      parsedTheme[name] = genVariations(name, colorToInt(value))
    }
  }

  if (!isItem) {
    parsedTheme.anchor = anchor || parsedTheme.base || parsedTheme.primary.base
  }

  return parsedTheme
}
/**
 * Generate the CSS for a base color (.primary)
 */

const genBaseColor = (name, value) => `
.v-application .${name} {
  background-color: ${value} !important;
  border-color: ${value} !important;
}
.v-application .${name}--text {
  color: ${value} !important;
  caret-color: ${value} !important;
}`
/**
 * Generate the CSS for a variant color (.primary.darken-2)
 */

const genVariantColor = (name, variant, value) => {
  const [type, n] = variant.split(/(\d)/, 2)
  return `
.v-application .${name}.${type}-${n} {
  background-color: ${value} !important;
  border-color: ${value} !important;
}
.v-application .${name}--text.text--${type}-${n} {
  color: ${value} !important;
  caret-color: ${value} !important;
}`
}

const genColorVariableName = (name, variant = 'base') => `--v-${name}-${variant}`

const genColorVariable = (name, variant = 'base') => `var(${genColorVariableName(name, variant)})`

export function genStyles (theme, cssVar = false) {
  const {
    anchor,
    ...variant
  } = theme
  const colors = Object.keys(variant)
  if (!colors.length) return ''
  let variablesCss = ''
  let css = ''
  const aColor = cssVar ? genColorVariable('anchor') : anchor
  css += `.v-application a { color: ${aColor}; }`
  cssVar && (variablesCss += `  ${genColorVariableName('anchor')}: ${anchor};\n`)

  for (let i = 0; i < colors.length; ++i) {
    const name = colors[i]
    const value = theme[name]
    css += genBaseColor(name, cssVar ? genColorVariable(name) : value.base)
    cssVar && (variablesCss += `  ${genColorVariableName(name)}: ${value.base};\n`)
    const variants = keys(value)

    for (let i = 0; i < variants.length; ++i) {
      const variant = variants[i]
      const variantValue = value[variant]
      if (variant === 'base') continue
      css += genVariantColor(name, variant, cssVar ? genColorVariable(name, variant) : variantValue)
      cssVar && (variablesCss += `  ${genColorVariableName(name, variant)}: ${variantValue};\n`)
    }
  }

  if (cssVar) {
    variablesCss = `:root {\n${variablesCss}}\n\n`
  }

  return variablesCss + css
}
export function genVariations (name, value) {
  const values = {
    base: intToHex(value)
  }

  for (let i = 5; i > 0; --i) {
    values[`lighten${i}`] = intToHex(lighten(value, i))
  }

  for (let i = 1; i <= 4; ++i) {
    values[`darken${i}`] = intToHex(darken(value, i))
  }

  return values
}
export function lighten (value, amount) {
  const lab = LAB.fromXYZ(sRGB.toXYZ(value))
  lab[0] += amount * 10
  return sRGB.fromXYZ(LAB.toXYZ(lab))
}
export function darken (value, amount) {
  const lab = LAB.fromXYZ(sRGB.toXYZ(value))
  lab[0] -= amount * 10
  return sRGB.fromXYZ(LAB.toXYZ(lab))
}
