export default {
  methods: {
    getCssCustomProperties() {
      if (process.client) {
        const cssCustomProperties = {}
        const sheets = document.styleSheets
        let cssText = ''
        for (let i = sheets.length - 1; i > -1; i--) {
          const rules = sheets[i].cssRules
          for (let j = rules.length - 1; j > -1; j--) {
            if (rules[j].selectorText === '.ie-custom-properties') {
              // eslint-disable-next-line prefer-destructuring
              cssText = rules[j].cssText
              break
            }
          }

          if (cssText) {
            break
          }
        }

        // eslint-disable-next-line unicorn/prefer-string-slice
        cssText = cssText.substring(cssText.lastIndexOf('{') + 1, cssText.lastIndexOf('}'))

        cssText.split(';').forEach(property => {
          if (property) {
            const name = property.split(': ')[0]
            const value = property.split(': ')[1]
            if (name && value) {
              cssCustomProperties[`--${name.trim()}`] = value.trim()
            }
          }
        })
        return cssCustomProperties
      } else {
        return null
      }
    },
    deepObjectsMerge(target, source) {
      // Iterate through `source` properties and if an `Object` set property to merge of `target` and `source` properties
      for (const key of Object.keys(source)) {
        if (source[key] instanceof Object) {
          Object.assign(source[key], this.deepObjectsMerge(target[key], source[key]))
        }
      }

      // Join `target` and modified `source`
      Object.assign(target || {}, source)
      return target
    },
    getColor(rawProperty, element = process.client ? document.body : null) {
      const property = `--${rawProperty}`
      const style = this.getStyle(property, element)
      return style || rawProperty
    },
    getStyle(property, element = process.client ? document.body : null) {
      if (process.client) {
        const minIEVersion = 10
        const isIE1x = () => Boolean(document.documentMode) && document.documentMode >= minIEVersion
        const isCustomProperty = property => property.match(/^--.*/i)
        ///
        let style

        if (isCustomProperty(property) && isIE1x()) {
          const cssCustomProperties = this.getCssCustomProperties()
          style = cssCustomProperties[property]
        } else {
          style = window.getComputedStyle(element, null).getPropertyValue(property).replace(/^\s/, '')
        }

        return style
      } else {
        return null
      }
    },
    hexToRgb(color) {
      if (typeof color === 'undefined') {
        throw new TypeError('Hex color is not defined')
      }

      const hex = color.match(/^#(?:[0-9a-f]{3}){1,2}$/i)

      if (!hex) {
        throw new Error(`${color} is not a valid hex color`)
      }

      let r
      let g
      let b

      if (color.length === 7) {
        r = parseInt(color.slice(1, 3), 16)
        g = parseInt(color.slice(3, 5), 16)
        b = parseInt(color.slice(5, 7), 16)
      } else {
        r = parseInt(color.slice(1, 2), 16)
        g = parseInt(color.slice(2, 3), 16)
        b = parseInt(color.slice(3, 5), 16)
      }

      return `rgba(${r}, ${g}, ${b})`
    },
    hexToRgba(color, opacity = 100) {
      if (typeof color === 'undefined') {
        throw new TypeError('Hex color is not defined')
      }

      const hex = color.match(/^#(?:[0-9a-f]{3}){1,2}$/i)

      if (!hex) {
        throw new Error(`${color} is not a valid hex color`)
      }

      let r
      let g
      let b

      if (color.length === 7) {
        r = parseInt(color.slice(1, 3), 16)
        g = parseInt(color.slice(3, 5), 16)
        b = parseInt(color.slice(5, 7), 16)
      } else {
        r = parseInt(color.slice(1, 2), 16)
        g = parseInt(color.slice(2, 3), 16)
        b = parseInt(color.slice(3, 5), 16)
      }

      return `rgba(${r}, ${g}, ${b}, ${opacity / 100})`
    },
    makeUid() {
      const key = Math.random().toString(36).substr(2)
      return 'uid-' + key
    },
    omitByKeys(originalObject, keys) {
      const newObj = {}
      const objKeys = Object.keys(originalObject)
      for (let i = 0; i < objKeys.length; i++) {
        !keys.includes(objKeys[i]) && (newObj[objKeys[i]] = originalObject[objKeys[i]])
      }
      return newObj
    },
    pickByKeys(originalObject, keys) {
      const newObj = {}
      for (let i = 0; i < keys.length; i++) {
        newObj[keys[i]] = originalObject[keys[i]]
      }
      return newObj
    },
    rgbToHex(color) {
      if (typeof color === 'undefined') {
        throw new TypeError('Hex color is not defined')
      }

      if (color === 'transparent') {
        return '#00000000'
      }

      const rgb = color.match(/^rgba?[\s+]?\([\s+]?(\d+)[\s+]?,[\s+]?(\d+)[\s+]?,[\s+]?(\d+)[\s+]?/i)

      if (!rgb) {
        throw new Error(`${color} is not a valid rgb color`)
      }

      const r = `0${parseInt(rgb[1], 10).toString(16)}`
      const g = `0${parseInt(rgb[2], 10).toString(16)}`
      const b = `0${parseInt(rgb[3], 10).toString(16)}`

      return `#${r.slice(-2)}${g.slice(-2)}${b.slice(-2)}`
    }
  }
}
