<template>
  <!--    属性编辑      -->
  <a-card>
    <template v-if="editorPropertiesConfig === 'unregistered'">
      <p>所选组件并未注册</p>
    </template>
    <template v-else>
      <!--    组件名    -->
      <template v-if="editorPropertiesConfig.name">
        <div class="select_title">
          <span style="font-size: 1.2em; margin-right: 10%; font-weight: bold">组件名</span>
          <a-tag
            v-if="editorPropertiesConfig.name || editorPropertiesConfig.id"
            :color="determineComponentColorAndText(editorPropertiesConfig.type).color">
            {{ determineComponentColorAndText(editorPropertiesConfig.type).text }}
          </a-tag>
        </div>
        <h4>{{ editorPropertiesConfig.name }}</h4>
      </template>
      <template v-else-if="editorPropertiesConfig.id">
        <div class="select_title">
          <span style="font-size: 1.2em; margin-right: 10%; font-weight: bold">组件ID</span>
          <a-tag
            style="height: 100%"
            v-if="editorPropertiesConfig.name || editorPropertiesConfig.id"
            :color="determineComponentColorAndText(editorPropertiesConfig.type).color">
            {{ determineComponentColorAndText(editorPropertiesConfig.type).text }}
          </a-tag>
        </div>
        <h4>{{ editorPropertiesConfig.id }}</h4>
      </template>
      <!--    切换    -->
      <a-menu v-model="editorPanelCurrent" mode="horizontal" @click="() => null">
        <a-menu-item key="properties">属性</a-menu-item>
        <a-menu-item key="events" :disabled="disableEventEditor">事件</a-menu-item>
      </a-menu>
      <!--    属性编辑    -->
      <div v-if="editorPanelCurrent[0] === 'properties'">
        <!--    组件属性编辑    -->
        <div v-if="editorPropertiesConfig.props !== undefined">
          <div v-if="editorPropertiesConfig.type === 'tabs'" style="border: 2px solid rgba(0,0,0,0.2); padding: 10%; margin: 5%">
            <p>标签</p>
            <template v-for="(tab, tabIndex) in editorPropertiesConfig.body">
              <div :key="tab.key" style="border-bottom: 1px solid rgb(200,229,255)">
                标签名: <a-input :default-value="tab.label" @change="handleTabPropChange($event, tabIndex, 'label')"/>
              </div>
            </template>
            <a-button icon="plus" @click="addNewTab"/>
          </div>
          <div v-if="editorPropertiesConfig.span">
            栅格数:
            <a-row>
              <a-col :span="16">
                <a-slider
                  :id="editorPropertiesConfig.id"
                  :max="24"
                  :min="1"
                  v-model="editorPropertiesConfig.span"
                  @change="changeSpan" />
              </a-col>
              <a-col :span="7">
                <a-input-number v-model="editorPropertiesConfig.span" :min="1" :max="24" style="margin-left: 16px; width: 100%" />
              </a-col>
            </a-row>
          </div>
          <template v-for="(value,key) in editorPropertiesConfig.props">
            <div :key="editorPropertiesConfig.id + '_' + key">
              <a-tooltip>
                <template slot="title" v-if="resolveEditorPropsLabel(editorPropertiesConfig.type, key).desc">
                  {{ resolveEditorPropsLabel(editorPropertiesConfig.type, key).desc }}
                </template>
                {{ resolveEditorPropsLabel(editorPropertiesConfig.type, key).label }}
                <span v-if="resolveEditorPropsLabel(editorPropertiesConfig.type, key).required" style="color: red">*</span>
                :
              </a-tooltip>
              <a-input :default-value="value" @change="editorPropertiesInputChange($event, key)"/>
            </div>
          </template>
        </div>
        <!--    行属性编辑    -->
        <div v-if="editorPropertiesConfig.config !== undefined">
          <div>
            垂直对齐方式:
            <a-select style="width: 100%" @change="rowPropertiesAlignChange" :default-value="editorPropertiesConfig.config.align">
              <a-select-option value="top">
                顶部对齐
              </a-select-option>
              <a-select-option value="middle">
                居中对齐
              </a-select-option>
              <a-select-option value="bottom">
                底部对齐
              </a-select-option>
            </a-select>
          </div>
          <div>
            栅格间隔:
            <a-input :default-value="editorPropertiesConfig.config.gutter" @change="rowPropertiesGutterChange($event)"/>
          </div>
          <div>
            水平排列方式:
            <a-select style="width: 100%" @change="rowPropertiesJustifyChange" :default-value="editorPropertiesConfig.config.justify">
              <a-select-option value="start">
                对齐开始
              </a-select-option>
              <a-select-option value="end">
                对齐结尾
              </a-select-option>
              <a-select-option value="center">
                居中
              </a-select-option>
              <a-select-option value="space-around">
                空隙环绕
              </a-select-option>
              <a-select-option value="space-between">
                空隙间隔
              </a-select-option>
            </a-select>
          </div>
        </div>
      </div>
      <!--    事件编辑    -->
      <div v-else-if="editorPanelCurrent[0] === 'events' && showEventEditor">
        <template v-if="editorPropertiesConfig.onEvent !== undefined">
          <a-collapse v-model="eventCollapseActive">
            <a-collapse-panel
              v-for="(eventConfig,eventType) in editorPropertiesConfig.onEvent"
              :key="eventType"
              :header="resolveEventType(eventType)">
              <div v-for="(singleEvent,singleEventIndex) in eventConfig" :key="singleEventIndex" class="singleEvent">
                <p>
                  <span style="color:rgb( 24,144,255)">{{ resolveEventName(singleEvent) }}</span>
                </p>
                <!--    事件 编辑/删除 按钮    -->
                <div style="display: flex; justify-content: space-evenly">
                  <a-icon type="edit" theme="twoTone" class="edit_icon" @click="editEventIconClick(eventType,singleEventIndex)"/>
                  <a-popconfirm title="确认删除" ok-text="确认删除" cancel-text="取消" @confirm="removeEventClick(eventType,singleEventIndex)" @cancel="() => null">
                    <a-icon type="delete" theme="twoTone" class="edit_icon"/>
                  </a-popconfirm>
                </div>
              </div>
            </a-collapse-panel>
          </a-collapse>
        </template>
        <a-button v-if="editorPropertiesConfig.id !== undefined" @click="addEvent">添加事件</a-button>
        <p v-else>您未选择任何组件</p>
      </div>
    </template>
  </a-card>
</template>

<script>

import * as lowcodeUtils from '@vue2-client/utils/lowcode/lowcodeUtils'
import lowcodeLog from '@vue2-client/utils/lowcode/lowcodeLog'

export default {
  name: 'LowCodeEditorPanel',
  props: {
    // 用于保存右侧编辑组件的属性
    // eslint-disable-next-line vue/require-default-prop
    editorPropertiesConfig: {
      type: Object,
      require: true
    },
    disableEventEditor: {
      type: Boolean,
      default: false
    }
  },
  methods: {
    refresh () {
      this.showEventEditor = false
      this.$nextTick(() => {
        this.showEventEditor = true
      })
    },
    // 根据组件类型，返回标签颜色和文字
    determineComponentColorAndText (type) {
      switch (type) {
        case 'container':
          return {
            color: 'blue',
            text: '容器'
          }
        case 'container_page':
          return {
            color: 'blue',
            text: '容器'
          }
        case 'row':
          return {
            color: 'orange',
            text: '行'
          }
        case 'tabs':
          return {
            color: 'cyan',
            text: '标签页'
          }
        default:
          return {
            color: 'green',
            text: '组件'
          }
      }
    },
    // 修改标签名
    handleTabPropChange (event, index, type) {
      // 找到目标配置
      const targetConfig = lowcodeUtils.getComponentConfig(this.editorPropertiesConfig.id, this.config.page)
      // 新输入的值
      targetConfig.body[index][type] = event.target.value
    },
    // 添加新标签
    addNewTab () {
      // 找到目标配置
      const targetConfig = lowcodeUtils.getComponentConfig(this.editorPropertiesConfig.id, this.config.page)
      const pageId = lowcodeUtils.nanoidWithoutSymbol(2)
      targetConfig.body.push({
        key: targetConfig.body.length.toString(),
        label: targetConfig.body.length.toString(),
        type: 'tab',
        body: {
          type: 'container_page',
          span: 24,
          id: 'container_' + lowcodeUtils.nanoidWithoutSymbol(6),
          page: [
            {
              id: 'container_page_' + pageId,
              type: 'page',
              body: [
                {
                  id: 'container_page_' + pageId + '_0',
                  type: 'row',
                  config: {
                    align: 'top',
                    gutter: 0,
                    justify: 'start'
                  },
                  body: [
                    {
                      type: 'container',
                      selected: false,
                      span: 24,
                      id: 'container_' + lowcodeUtils.nanoidWithoutSymbol(6),
                      props: {}
                    }
                  ]
                }
              ]
            }
          ]
        }
      })
    },
    // 事件编辑器中，点击编辑按钮
    editEventIconClick (eventType, eventIndex) {
      // 找到目标配置
      const targetConfig = lowcodeUtils.getComponentConfig(this.editorPropertiesConfig.id, this.config.page)
      // 将目标对应的配置赋值到事件编辑器缓存
      this.eventEditorContent = { ...targetConfig.onEvent[eventType][eventIndex] }
      this.eventEditorContent.emitType = eventType
      this.eventEditorCurrent = {
        type: eventType,
        index: eventIndex
      }
      this.$store.commit('setEventEditorContent', this.eventEditorContent)
      this.$emit('openModal', 'eventEditor')
    },
    // 删除事件
    removeEventClick (eventType, eventIndex) {
      const targetConfig = lowcodeUtils.getComponentConfig(this.editorPropertiesConfig.id, this.config.page)
      targetConfig.onEvent[eventType].splice(eventIndex, 1)
      if (targetConfig.onEvent[eventType].length === 0) {
        delete targetConfig.onEvent[eventType]
      }
      this.$forceUpdate()
    },
    // 添加事件
    addEvent () {
      this.$emit('openModal', 'eventEditor')
    },
    resolveEventType (eventType) {
      if (eventType === 'lifeCycle') {
        return '生命周期函数'
      } else {
        return eventType
      }
    },
    resolveEventName (eventConfig) {
      if (eventConfig.emitType === 'lifeCycle') {
        return eventConfig.lifeCycle
      } else {
        switch (eventConfig.eventType) {
          case 'runFunction':
            return '调用组件方法'
          case 'changeProps':
            return '修改组件Props'
          case 'runLogic':
            return '发送请求'
          case 'log':
            return '打印日志'
          case 'customJSFunction':
            return '自定义JS'
          case 'showModal':
            return '修改组件显隐'
          case 'showDraw':
            return '修改组件显隐'
        }
      }
    },
    // 行修改Justify
    rowPropertiesJustifyChange (justify) {
      const target = lowcodeUtils.getRowConfigById(this.editorPropertiesConfig.id, this.config)
      target.config.justify = justify
    },
    // 行修改Align
    rowPropertiesAlignChange (align) {
      const target = lowcodeUtils.getRowConfigById(this.editorPropertiesConfig.id, this.config)
      target.config.align = align
    },
    // 行修改Gutter
    rowPropertiesGutterChange (event) {
      const target = lowcodeUtils.getRowConfigById(this.editorPropertiesConfig.id, this.config)
      target.config.gutter = Number(event.target.value)
    },
    // 组件属性编辑
    editorPropertiesInputChange (event, key) {
      this.$emit('controlRender', false)
      // 如果当前有定时器，清除该定时器，并设置新的定时器
      // 也就是说：每次操作间隔指定时间后才会触发更新
      // 如果在此期间又进行了操作，则重新开始计时
      if (this.inputTimeout) {
        clearTimeout(this.inputTimeout)
      }
      this.inputTimeout = setTimeout(() => {
        const target = lowcodeUtils.getComponentConfig(this.editorPropertiesConfig.id, this.config.page)
        lowcodeLog('组件属性修改', '触发更新', target.id, true, false)
        // 拿到组件注册的配置
        const editorConfig = lowcodeUtils.getEditorConfigById(this.editorPropertiesConfig.id, this.config.page)
        // 根据类型，将input框中的内容赋值
        if (editorConfig.properties[key].type === 'object') {
          target.props[key] = JSON.parse(event.target.value)
        } else if (editorConfig.properties[key].type === 'string') {
          target.props[key] = event.target.value
        } else if (editorConfig.properties[key].type === 'boolean') {
          const input = event.target.value.toLowerCase()
          target.props[key] = input === 'true' || input !== '0'
        }
        this.$emit('controlRender', true)
      }, 1500)
    },
    // span属性通过input框修改
    changeSpan (event) {
      this.editorPropertiesConfig.span = event
    },
    // 通过组件类型和key解析出该key对应的中文定义
    resolveEditorPropsLabel (type, key) {
      // 获取配置中的定义
      const def = lowcodeUtils.getEditorConfigByType(type)
      const propsDef = def.properties
      const targetDef = propsDef[key]
      if (!targetDef.label) {
        targetDef.label = key
      } else {
        targetDef.label = targetDef.label + '(' + key + ')'
      }
      if (!targetDef.desc) {
        targetDef.desc = '未配置该参数的说明！'
      }
      return targetDef
    },
  },
  data () {
    return {
      // 控制右侧编辑器切换标签页
      editorPanelCurrent: ['properties'],
      // 控制右侧事件编辑刷新
      showEventEditor: true,
      // 当前激活的是组件事件中哪一类触发属性，对应事件编辑中的手风琴面板
      eventCollapseActive: undefined,
      // 事件编辑弹框内容回显
      eventEditorContent: {},
      // 编辑属性时用到的定时器
      inputTimeout: undefined,
    }
  },
  computed: {
    config () {
      return this.$store.state.lowCode.config
    }
  }
}
</script>

<style scoped lang="less">
.select_title {
  width: 100%;
  justify-content: space-between;
  display: flex;
  align-items: center;
  margin-bottom: 3%
}
.singleEvent {
  border: black dashed 1px;
  padding: 10%;
  margin-bottom: 3%;
}
.edit_icon:hover {
  cursor: pointer;
}
</style>
