<!--
 * @Author: 曹捷
 * @Date: 2021-04-29 11:31:44
 * @LastEditors: 曹捷
 * @LastEditTime: 2021-10-28 09:41:54
 * @Description: form表单 代码生成
-->
<template>
  <a-layout class="h100 form-panel   body">
    <a-layout-sider class="body b-r" width="260">
      <div class="components-list">
        <div v-for="(item, listIndex) in leftComponents" :key="listIndex">
          <div class="components-title">
            {{ item.title }}
          </div>
          <draggable class="components-draggable" :list="item.list" item-key="key" :group="{ name: 'componentsGroup', pull: 'clone', put: false }" :clone="cloneComponent" draggable=".components-item"
            :sort="false" @end="onEnd">
            <template #item="{ element }">
              <div class="components-item" @click="addComponent(element)">
                <div class="components-body">
                  <i class="iconfont " :class="'icon-'+element.__config__.tagIcon"></i>
                  {{ element.__config__.label }}
                </div>
              </div>
            </template>
          </draggable>
        </div>
      </div>
    </a-layout-sider>
    <a-layout>
      <a-layout-header class="body b-b   p-l-0 p-r-0" :style="{ height: '45px' }">
        <slot></slot>
        <!-- <a-page-header class="form-panel-head h100" title="" @back="$router.go(-1)">
          <template #extra>
            <div class="menu-right flex-c">
              <a-button type="link" block class="m-r-10" @click="importData">
                <i class="iconfont icon-upload2 p-r-5"></i>
                导入脚本
              </a-button>
              <a-button type="link" block class="m-r-10" @click="downloadVue">
                <i class="iconfont icon-download p-r-5"></i>
                导出Vue文件
              </a-button>
              <a-button type="link" block @click="removeAll">清空</a-button>
            </div>
          </template>
        </a-page-header> -->
      </a-layout-header>
      <a-layout-content class="body">
        <a-row :gutter="[formConf.gutterX, formConf.gutterY]" style="    overflow: hidden;">
          <a-col :span="24">
            <a-form class="drag-form" :rules="rules" :layout="formConf.layout" :model="formData" :label-col="{span: formConf.labelCol}" :labelAlign="formConf.labelAlign"
              :wrapper-col="{span:formConf.wrapperCol}">
              <obit-scrollbar class="h100">
                <draggable class="drawing-board  " item-key="key" :list="drawingList" :animation="340" group="componentsGroup">
                  <template #item="{ element }">
                    <draggableItemVue :formData="formData" @copyItem="copyItem" @remove="removeItem" @activeItem="activeFormItem" :active-id="activeId" :item-info="element">
                    </draggableItemVue>
                  </template>
                </draggable>
              </obit-scrollbar>
            </a-form>
          </a-col>
        </a-row>

      </a-layout-content>
    </a-layout>
    <a-layout-sider class="body b-l" width="350">
      <rightPanelVue :formData="formData" @changeActive="updateActive" :activeData="activeData" :formConf="formConf">
      </rightPanelVue>
    </a-layout-sider>
  </a-layout>
  <input id="copyNode" type="hidden">
  <importScriptVue @import="saveImportInfo" v-model:visible="importVisable"></importScriptVue>
</template>

<script>
import { computed, getCurrentInstance, provide, reactive, toRefs } from 'vue'
import { leftComponents, formConf, relation } from './../gconfig'
import rightPanelVue from './right-panel.vue'
import draggable from 'vuedraggable'
import HtmlParse from '../modules/formHtml'
import { util } from './../../../entery'
import draggableItemVue from '../components/draggable-item.vue'
import { message } from 'ant-design-vue';
import importScriptVue from '../components/importScript.vue'
export default {
  components: { rightPanelVue, draggable, draggableItemVue, importScriptVue },
  setup (props, context) {
    let { proxy } = getCurrentInstance()
    let _data = reactive({
      formData: {},
      leftComponents,
      formConf: util.util.cloneObj(formConf),
      drawingList: [],
      activeData: {},
      activeId: '',
      idKey: 100,
      importVisable: false,
      importInfo: ''
    })
    provide('formConf', _data.formConf)
    let _computed = {
      // 验证  规则   动态生成
      rules: computed(() => {
        let rules = {}
        let data = _data.drawingList
        data.forEach(element => {
          let arr = []
          if (element.__config__.required) {
            let obj = { required: true, message: `请输入${element.__config__.label}` }
            if (element.type) {
              obj.type = element.type
            }
            arr.push(obj)
          }
          if (element.__config__.regList && element.__config__.regList.length > 0) {
            arr = arr.concat(element.__config__.regList)
          }
          rules[element.key] = arr
        });
        return rules
      })
    }
    let _methods = {
      importData () {
        _data.importVisable = true
      },
      /**
       * 根据导入的规则  自动生成代码
       */
      autoGenearte (item, infoList) {
        _data.formConf.modulesName = item.functionName
        let name = item.className
        _data.formConf.fileName = name.replace(name[0], name[0].toLowerCase()) + 'Add'
        let arr = util.util.cloneObj(infoList.filter(el => el.edit))
        console.log('🚀 ~ file: form-panel.vue ~ line 141 ~ autoGenearte ~ arr', arr)
        let listConfig = [].concat(...leftComponents.map(item => item.list))
        let list = []
        arr.forEach(element => {
          let htmlType = element.dictType ? 'obit-dict' : element.htmlType
          let item = listConfig.find(ele => ele.__config__.tag === relation[htmlType])
          item = util.util.cloneObj(item ? item : listConfig[0])
          item.key = element.javaField
          item.__config__.label = element.columnComment
          item.placeholder += element.columnComment
          item.__config__.required = element.required
          if (element.htmlType === 'selectM') {
            item.multiple = true
          } else if (element.htmlType === 'radio') {
            item.componentType = 'radio'
          }
          if (element.dictType) {
            item.componentType = element.htmlType === 'radio' ? 'radio' : 'select'
            item.dictCode = element.dictType
          }
          const clone = this.cloneComponent(item)
          list.push(clone)
        })
        _data.drawingList = list
        this.activeFormItem(list[list.length - 1])
      },
      /**
       * 自动导入脚本
       */
      saveImportInfo (importValue) {
        let arr = importValue.split('\n')
        let listConfig = [].concat(...leftComponents.map(item => item.list))
        arr.forEach(element => {
          let itemArr = element.trim().split(' ')
          itemArr[0] = util.util.toHump(itemArr[0])
          itemArr[1] = itemArr[1].toLowerCase()
          let item = listConfig.find(ele => ele.__config__.tag === relation[itemArr[1]])
          console.log(itemArr[1], relation[itemArr[1]])
          item = util.util.cloneObj(item ? item : listConfig[0])
          item.key = itemArr[0]
          item.__config__.label = itemArr[2]
          item.placeholder += itemArr[2]
          _methods.addComponent(item)
        });
        message.success('批量导入成功 恭喜你');
      },
      /**
       * 下载Vue文件
       */
      downloadVue () {
        let html = new HtmlParse({
          formConf: util.util.cloneObj(_data.formConf),
          drawingList: util.util.cloneObj(_data.drawingList),
          rules: _computed.rules.value
        })
        html.download()
      },
      /**
       * 复制代码
       */
      copyCode () {
        let html = new HtmlParse({
          formConf: util.util.cloneObj(_data.formConf),
          drawingList: util.util.cloneObj(_data.drawingList),
          rules: _computed.rules.value
        })

      },
      copyItem () {
        let item = util.util.cloneObj(_data.activeData)
        item.key = 'filed'
        _methods.addComponent(item)
      },
      removeItem () {
        let index = _data.drawingList.findIndex(ele => ele.key === _data.activeId)
        _data.drawingList.splice(index, 1)
      },
      /**
       * 更新当前节点信息
       */
      updateActive (item) {
        let index = _data.drawingList.findIndex(ele => ele.key === _data.activeId)
        _data.drawingList[index] = item
        _data.activeData = item
      },
      removeAll () {
        proxy.$confirm({
          title: '警告',
          content: '是否清空',
          cancelText: '取消',
          okText: '确认',
          onOk () {
            _data.drawingList = []
          }
        })
      },
      activeFormItem (currentItem) {
        _data.activeData = currentItem
        _data.activeId = currentItem.key
      },
      addComponent (item) {
        const clone = this.cloneComponent(item)
        _data.drawingList.push(clone)
        this.activeFormItem(clone)
      },
      onEnd (obj) {
        console.log('🚀 ~ file: form-panel.vue ~ line 70 ~ onEnd ~ obj', obj)
      },
      cloneComponent (origin) {
        const clone = util.util.cloneObj(origin)
        const config = clone.__config__
        config.span = _data.formConf.span // 生成代码时，会根据span做精简判断
        if (clone.key === 'filed') {
          clone.key += _data.idKey
          _data.idKey++
        }
        clone.placeholder !== undefined && (clone.placeholder += config.label)
        return clone
      },
    }
    _data.drawingList.push(_methods.cloneComponent(leftComponents[0].list[0]))
    _methods.activeFormItem(_data.drawingList[0])
    return {
      ...toRefs(_data),
      ..._methods,
      ..._computed
    }
  }
}
</script>

<style lang="less" scoped>
@selectedColor: #f6f7ff;
@lighterBlue: #409eff;
.form-panel {
  .drag-form {
    height: calc(100vh - 45px);
  }
  .drawing-board {
    width: 100%;
    display: flex;
    flex-flow: row wrap;
  }
  .form-panel-head {
    padding: 0 24px;
  }
  .components-list {
    padding: 8px;
    box-sizing: border-box;
    height: 100%;
    .components-item {
      display: inline-block;
      width: 48%;
      margin: 1%;
      transition: transform 0ms !important;
    }
  }
  .components-draggable {
    padding-bottom: 20px;
  }
  .components-title {
    font-size: 14px;
    color: #222;
    margin: 6px 2px;
    .svg-icon {
      color: #666;
      font-size: 18px;
    }
  }

  .components-body {
    padding: 2px 10px;
    background: @selectedColor;
    font-size: 12px;
    cursor: move;
    border: 1px dashed @selectedColor;
    border-radius: 3px;
    .svg-icon {
      color: #777;
      font-size: 15px;
    }
    &:hover {
      border: 1px dashed #787be8;
      color: #787be8;
      .svg-icon {
        color: #787be8;
      }
    }
  }
}
</style>