// eslint-disable-next-line no-unused-vars
import Vue from 'vue'
import lowcodeLog from '@vue2-client/utils/lowcode/lowcodeLog'
import { uuid } from '@vue2-client/utils/util'
export default {
  props: {
    // 组件ID用于注册组件到Map中
    mixinComponentId: {
      type: String,
      required: false,
      default: uuid()
    },
    // 所有Props的集合
    propsData: {
      type: Object,
      default: () => {}
    },
    // 钩子函数
    lifeCycleFunction: {
      type: Array,
      default: undefined
    }
  },
  data () {
    return {
      // 组件暴露给低代码平台的变量
      // 该变量由各个组件选择性暴露
      // 比如XFormTable可以将点击action后，该行信息保存在此变量中，便于其他组件调用
      // 使用$lowCodeSetData来修改此变量的值
      dataForLowCode: {}
    }
  },
  methods: {
    // 处理目标为本组件的通信
    handleComponentCommunication (actionType, data, targetKey = undefined, eventOriginalVM = undefined) {
      lowcodeLog(
        ` 事件数据：${data},\n 目标key：${targetKey}`,
        '响应组件接收到事件',
        actionType,
        false,
        true
      )
      switch (actionType) {
        case 'changeValue':
          this.handleComponentChangeValue(data, targetKey)
          break
        case 'log':
          this.handleComponentLog(data)
          break
      }
    },
    handleComponentLog (data) {
      console.warn('vm', this)
      console.warn('data', data)
    },
    handleComponentChangeValue (data, targetKey = undefined) {
      if (targetKey) {
        this[targetKey] = data
        return
      }

      const keys = Object.keys(data)
      keys.forEach(key => {
        this[key] = data[key]
      })
    },
    // 处理本组件发出的事件
    $lowCodeEmit (eventType, data) {
      // emit的时候大概率需要传递给外层一个值，所以将其保存后再emit
      this.dataForLowCode[eventType] = data
      if (this.mixinComponentId) {
        this.$emit('onEvent', data, eventType, this.mixinComponentId)
      }
    },
    // 保存值到变量中供低代码平台调用
    $lowCodeSetData (key, value) {
      this.dataForLowCode[key] = value
    },
    // 解析传入的钩子函数并执行
    resolveLifeCycleFunctionAndRun (lifeCycleName) {
      if (this.lifeCycleFunction && this.lifeCycleFunction.length > 0) {
        this.lifeCycleFunction.forEach(param => {
          if (param.lifeCycleName === lifeCycleName) {
            // eslint-disable-next-line no-eval
            const receivedFunction = eval('(' + param.functionStr + ')')
            receivedFunction(this)
          }
        })
      }
    }
  },
  created () {
    this.resolveLifeCycleFunctionAndRun('created')
  },
  beforeMount () {
    this.resolveLifeCycleFunctionAndRun('beforeMount')
  },
  mounted () {
    this.resolveLifeCycleFunctionAndRun('mounted')
    if (this.mixinComponentId) {
      this.$emit('componentDidMounted', this, this.mixinComponentId)
    }
  },
  beforeUpdate () {
    this.resolveLifeCycleFunctionAndRun('beforeUpdate')
  },
  updated () {
    this.resolveLifeCycleFunctionAndRun('updated')
  },
  beforeDestroy () {
    this.resolveLifeCycleFunctionAndRun('beforeDestroy')
  },
  destroyed () {
    this.resolveLifeCycleFunctionAndRun('destroyed')
  },
  supportedEventType: [
    'changeValue',
    'log'
  ],
}
