<template>
  <el-color-picker
    class="theme-picker"
    popper-class="theme-picker-dropdown"
    v-model="theme"
  />
</template>

<script>
import { createNamespacedHelpers } from 'vuex'
const { mapMutations } = createNamespacedHelpers('framework')

const version = require('element-ui/package.json').version // element-ui version from node_modules
const ORIGINAL_THEME = '#409EFF' // element的原始颜色，不要改
const DEFAULT_THEME = '#4992fc' // 本项目默认颜色, 用于重置
export default {
  data () {
    return {
      chalk: '', // content of theme-chalk css
      theme: ORIGINAL_THEME
    }
  },
  watch: {
    theme (val, oldVal) {
      if (typeof val !== 'string') return
      if (val === '#FFFFFF' || val === '#000000') {
        this.theme = val = DEFAULT_THEME
      }
      const themeCluster = this.getThemeCluster(val.replace('#', ''))
      const originalCluster = this.getThemeCluster(oldVal.replace('#', ''))
      // console.log('themeCluster =', themeCluster)
      // console.log('originalCluster =', originalCluster)
      const getHandler = (variable, id) => {
        return () => {
          const originalCluster = this.getThemeCluster(ORIGINAL_THEME.replace('#', ''))
          const newStyle = this.updateStyle(this[variable], originalCluster, themeCluster)
          let styleTag = document.getElementById(id)
          if (!styleTag) {
            styleTag = document.createElement('style')
            styleTag.setAttribute('id', id)
            document.head.appendChild(styleTag)
          }
          styleTag.innerText = newStyle
        }
      }
      const chalkHandler = getHandler('chalk', 'chalk-style')
      if (!this.chalk) {
        const url = `https://unpkg.com/element-ui@${version}/lib/theme-chalk/index.css`
        this.getCSSString(url, chalkHandler, 'chalk')
      } else {
        chalkHandler()
      }
      const styles = [].slice.call(document.querySelectorAll('style'))
        .filter(style => {
          const text = style.innerText
          return new RegExp(oldVal, 'i').test(text) && !/Chalk Variables/.test(text)
        })
      styles.forEach(style => {
        const { innerText } = style
        if (typeof innerText !== 'string') return
        style.innerText = this.updateStyle(innerText, originalCluster, themeCluster)
      })

      if (oldVal !== ORIGINAL_THEME) {
        this.$message({
          message: '换肤成功',
          type: 'success'
        })
      }

      this.changeTheme(val)
    }
  },
  methods: {
    ...mapMutations(['changeTheme']),
    updateStyle (style, oldCluster, newCluster) {
      let newStyle = style
      oldCluster.forEach((color, index) => {
        newStyle = newStyle.replace(new RegExp(color, 'ig'), newCluster[index])
      })
      return newStyle
    },
    getCSSString (url, callback, variable) {
      this.$https.get(url)
        .then(data => {
          const url = `https://unpkg.com/element-ui@${version}/lib/theme-chalk/`
          // @font-face{font-family:element-icons;src:url(fonts/element-icons.woff) format("woff"),url(fonts/element-icons.ttf) format("truetype");font-weight:400;font-style:normal}
          // 若不替换@fontface就需要先引入原始element-ui样式，这里又获取网络样式替换主题色，再补加style，造成重复渲染资源浪费，调试时也需要注意重复的css样式；若不引入原始样式，则图标无法加载。
          this[variable] = data.replace(/(@font-face{.*url\()([^)]+)(\).*url\()([^)]+)(\)[^}]+})/, `$1${url}$2$3${url}$4$5`)
          // .replace(/el-table tr{background-color:#fff}/, 'el-table tr{background-color:#ecf5ff}')
            .replace('.el-table--striped .el-table__body tr.el-table__row--striped td{background:#FAFAFA}', '.el-table--striped .el-table__body tr.el-table__row--striped td{background:#f5faff}') // tint 0.95 表格斑马线
            .replace('.el-table--enable-row-hover .el-table__body tr:hover>td{background-color:#f5f7fa}', '.el-table--enable-row-hover .el-table__body tr:hover>td {background-color:#ecf5ff}') // tint 0.90 表格 hover
            // 激活的菜单颜色
            .replace('.el-submenu.is-active .el-submenu__title{border-bottom-color:#409EFF}', '.el-submenu.is-active .el-submenu__title{border-bottom-color:#409EFF;color:#409EFF} .el-submenu.is-active .el-submenu__title i{color:inherit}')
            .replace('.el-menu-item:not(.is-disabled):hover{outline:0;color:#303133}', '.el-menu-item:not(.is-disabled):hover{outline:0;color:#303133;background-color:#ecf5ff}') // tint 0.90 menu hover
            .replace('.el-menu--horizontal>.el-menu-item.is-active{border-bottom:2px solid #409EFF;color:#303133', '.el-menu--horizontal>.el-menu-item.is-active{border-bottom:2px solid #409EFF;color:#409EFF')
            .replace('>.el-submenu__title{color:#303133}', '>.el-submenu__title{color:#409EFF}')
          this[variable] += `.el-collapse .el-collapse-item__header {background: #ecf5ff}` // tint 0.90 面板头
          callback()
        })
    },
    getThemeCluster (theme) {
      const tintColor = (color, tint) => {
        let red = parseInt(color.slice(0, 2), 16)
        let green = parseInt(color.slice(2, 4), 16)
        let blue = parseInt(color.slice(4, 6), 16)
        if (tint === 0) { // when primary color is in its rgb space
          return [red, green, blue].join(',')
        } else {
          red += Math.round(tint * (255 - red))
          green += Math.round(tint * (255 - green))
          blue += Math.round(tint * (255 - blue))
          red = red.toString(16)
          green = green.toString(16)
          blue = blue.toString(16)
          return `#${red}${green}${blue}`
        }
      }
      const shadeColor = (color, shade) => {
        let red = parseInt(color.slice(0, 2), 16)
        let green = parseInt(color.slice(2, 4), 16)
        let blue = parseInt(color.slice(4, 6), 16)
        red = Math.round((1 - shade) * red)
        green = Math.round((1 - shade) * green)
        blue = Math.round((1 - shade) * blue)
        red = red.toString(16)
        green = green.toString(16)
        blue = blue.toString(16)
        return `#${red}${green}${blue}`
      }
      const clusters = [theme]
      for (let i = 0; i <= 19; i++) {
        clusters.push(tintColor(theme, Number((i / 20).toFixed(2))))
      }
      clusters.push(shadeColor(theme, 0.1))
      return clusters
    }
  },
  created () {
    this.theme = this.$store.state.framework.theme
  },
  mounted () {
    const clearBtn = document.querySelector('.el-color-dropdown__link-btn')
    clearBtn.innerText = '重置'
    clearBtn.addEventListener('click', (e) => {
      e.stopPropagation()
      this.theme = DEFAULT_THEME
    })
  }
}
</script>

<style lang="scss">
.theme-picker .el-color-picker__trigger {
  width: 36px;
  height: 36px;
  vertical-align: middle;

  /*修改原 element trigger 及子元素的样式*/
  border: none;

  .el-color-picker__color {
    border-color: #fff;
    border-radius: 5px;

    .el-color-picker__color-inner {
      border-radius: 5px;
    }
  }
}

/*.theme-picker-dropdown .el-color-dropdown__link-btn {*/
  /*display: none;*/
/*}*/
</style>
