<script>
import UploadAttachment from '@/components/UploadAttachment'
import TagSelectSimple from '@/components/TagSelectSimple'
import { getModuleOptions } from '@/api/options'
import { typeOf } from '@/utils'
import dayjs from 'dayjs'

export default {
  name: 'CustomComponent',
  components: { UploadAttachment, TagSelectSimple },
  props: {
    value: {
      require: true,
    },
    type: {
      type: Number,
      require: true,
    },
    unit: {
      type: String,
      default: null,
    },
    isTag: {
      type: Boolean,
      default: false,
    },
    isRequired: {
      type: Boolean,
      default: false,
    },
    defaultValue: {
      type: String,
      default: null,
    },
    config: {
      type: String,
      default: null,
    },
  },
  computed: {
    typeStr() {
      if (this.isTag) return 'tag-select-simple'
      switch (this.type) {
        case 1:
          return 'el-input'
        case 2:
          return 'el-input-number'
        case 3:
          return 'el-select'
        case 4:
          return 'el-cascader'
        case 5:
          return 'el-switch'
        case 6:
          if (this.configObj.type && this.configObj.type == 'picker') return 'el-time-picker'
          else return 'el-time-select'
        case 7:
        case 8:
          return 'el-date-picker'
        case 9:
          return 'el-color-picker'
        case 10:
          return 'upload-attachment'
        default:
          return ''
      }
    },
    configObj() {
      try {
        if (this.config) return JSON.parse(this.config)
        else return {}
      } catch (err) {
        console.error(err)
        return {}
      }
    },
    class() {
      if (this.configObj.class) {
        return this.configObj.class
      } else {
        return 'filter-item'
      }
    },
    style() {
      if (this.configObj.style) {
        if (!this.configObj.style.width) this.configObj.style.width = '360px'
        return this.configObj.style
      } else return { width: '360px' }
    },
    attrs() {
      if (this.configObj.attrs) {
        return this.configObj.attrs
      } else return null
    },
    props() {
      let v
      if (this.value) {
        const reg = /^\{.*\}$|^\[.*\]$/
        if (reg.test(this.value)) {
          try {
            v = JSON.parse(this.value)
          } catch {
            v = null
          }
        } else v = this.value
        if (this.type == 5) v = this.value == 'true'
        if (this.type == 2) v = Number(this.value)
        if (this.type == 6 && this.configObj.type && this.configObj.type == 'picker')
          v = dayjs('2020-01-01 ' + this.value)
      } else v = this.value
      //固定props，不能被配置修改
      let props1 = { value: v, clearable: !this.isRequired }
      //默认props，可以被配置修改
      let props2 = {}
      switch (this.type) {
        case 1:
          break
        case 2:
          break
        case 3:
          break
        case 4:
          props1.options = this.options
          props2.props = { checkStrictly: true, emitPath: false, multiple: false }
          props2.filterable = true
          break
        case 5:
          props2.activeColor = '#13ce66'
          props2.inactiveColor = '#ff4949'
          props2.activeValue = true
          props2.inactiveValue = false
          break
        case 6:
          if (this.configObj.type && this.configObj.type == 'picker') {
            props2.pickerOptions = {
              selectableRange: '00:00:00 - 23:59:59',
            }
            props2.defaultValue = dayjs('2020-01-01 00:00:00')
          } else {
            props2.pickerOptions = {
              start: '00:00',
              step: '00:30',
              end: '23:59',
            }
            props2.defaultValue = '00:00'
          }
          break
        case 7:
          props1.type = 'date'
          props2.valueFormat = 'yyyy-MM-dd'
          break
        case 8:
          props1.type = 'datetime'
          props2.valueFormat = 'yyyy-MM-dd HH:mm:ss'
          break
        case 9:
          break
        case 10:
          props2.limit = 1
          props2.maxSize = 1024 * 1024 * 20
          break
        default:
          break
      }

      if (this.configObj.props) Object.assign(props2, this.configObj.props)
      Object.assign(props2, props1)
      return props2
    },
    domProps() {
      if (this.configObj.domProps) {
        return this.configObj.domProps
      } else return null
    },
  },
  created() {
    if ((this.type == 3 || this.type == 4) && !this.isTag) this.getOptions()
    if (!this.value)
      this.$emit(
        'input',
        Function('"use strict";return (function(dayjs){ return ' + this.defaultValue + '})')()(
          dayjs
        )
      )
  },
  data() {
    return {
      defaultProps: {},
      options: [],
    }
  },
  methods: {
    children(createElement) {
      let c = []
      if (this.type == 3 && this.options.length > 0) {
        this.options.forEach((a) => {
          c.push(
            createElement('el-option', { props: { key: a.value, label: a.label, value: a.value } })
          )
        })
      }
      if (this.configObj.children && this.configObj.children.length > 0) {
        this.options.forEach((a) => {
          c.puch(createElement(a.component, a.config))
        })
      }
      return c
    },
    getOptions(module, type, data) {
      let _module = ''
      let _type = ''
      let _data = {}
      if (module || type || data) {
        _module = module ? module : _module
        _type = type ? type : _type
        _data = data ? data : _data
      } else {
        if (this.configObj.options && this.configObj.options.module)
          _module = this.configObj.options.module
        if (this.configObj.options && this.configObj.options.type)
          _type = this.configObj.options.type
        if (this.configObj.options && this.configObj.options.data)
          _data = this.configObj.options.data
      }
      if (_module || _type) {
          getModuleOptions(_module, _type, _data).then(res => {
            if (res.code === 20000) this.options = res.data.content
          })
          .catch(err => {
            this.options = []
          })
      } else this.options = []
    },
  },
  render(createElement) {
    let _this = this
    return createElement(
      this.typeStr,
      {
        class: this.class,
        style: this.style,
        attrs: this.attrs,
        props: this.props,
        domProps: this.domProps,
        on: {
          input: (value) => {
            let v = ''
            switch (typeOf(value)) {
              case 'Object':
              case 'Array':
                v = JSON.stringify(value)
                break
              case 'Date':
                if (this.type == 6) v = dayjs(value).format('HH:mm:ss')
                else if (this.type == 7) v = dayjs(value).format('YYYY-MM-DD')
                else v = dayjs(value).format('YYYY-MM-DD HH:mm:ss')
                break
              case 'Number':
              case 'Boolean':
                v = String(value)
                break
              default:
                v = value
                break
            }
            _this.$emit('input', v)
          },
        },
      },
      this.children(createElement)
    )
  },
}
</script>