<template>
  <div class="form-design">
    <!--左侧组件库-->
    <div style="width: 350px">
      <div class="components-nav">
        <span @click="libSelect = 0">组件库</span>
      </div>
      <div style="overflow-y: auto;height:calc(100vh - 172px);">
        <div class="components" v-for="(item, i) in baseComponents" :key="i">
          <p>{{ item.name }}</p>
          <ul>
            <draggable
                class="drag"
                :list="item.components"
                :group="{ name: 'form', pull: 'clone', put: false }"
                itemKey="name"
                @start="isStart = true" @end="isStart = false" :clone="clone"
            >
              <template #item="{ element, index }">
                <div class="list-group-item">
                  <li :key="id">
                    <el-icon>
                      <component :is="element.icon"/>
                    </el-icon>
                    <span>{{ element.title }}</span>
                  </li>
                </div>
              </template>
            </draggable>
          </ul>
        </div>
      </div>
    </div>
    <!--中间编辑区-->
    <div class="layout-main">
      <div class="tool-nav">
        <div>
          <el-tooltip class="item" effect="dark" content="撤销" placement="bottom-start">
            <el-icon>
              <RefreshLeft/>
            </el-icon>
          </el-tooltip>
          <el-tooltip class="item" effect="dark" content="恢复" placement="bottom-start">
            <el-icon>
              <RefreshRight/>
            </el-icon>
          </el-tooltip>
        </div>
        <div>
          <el-tooltip class="item" effect="dark" content="预览表单" placement="bottom-start">
            <el-icon @click="viewForms">
              <View/>
            </el-icon>
          </el-tooltip>
          <el-tooltip class="item" effect="dark" content="移动端" placement="bottom-start">
            <el-icon :class="{'select': showMobile}" @click="showMobile = true">
              <Cellphone/>
            </el-icon>
          </el-tooltip>
          <el-tooltip class="item" effect="dark" content="PC端" placement="bottom-start">
            <el-icon :class="{'select': !showMobile}" @click="showMobile = false">
              <Monitor/>
            </el-icon>
          </el-tooltip>
        </div>
      </div>
      <div class="work-form">
        <div :class="{'mobile': showMobile, 'pc': !showMobile}">
          <div :class="{'bd': showMobile}">
            <div :class="{'form-content': showMobile}">
              <div class="form">
                <div class="tip" v-show="formItems.length === 0 && !isStart">👈 请在左侧选择控件并拖至此处</div>
                <draggable class="drag-from" :list="formItems" group="form"
                           :options="{animation: 300, chosenClass:'choose', sort:true}"
                           @start="drag = true; selectFormItem = null" @end="drag = false">
                  <template #item="{ element, index }">
                    <div class="form-item" @click="selectItem(element)"
                         :style="getSelectedClass(element)">
                      <div class="form-header">
                        <p><span v-if="element.props.required">*</span>{{ element.title }}</p>
                        <div class="option">
                          <!--<i class="el-icon-copy-document" @click="copy"></i>-->
                          <!--                          <el-icon  @click="copy">-->
                          <!--                            <CopyDocument/>-->
                          <!--                          </el-icon>-->
                          <el-icon size="25px" @click="delItem(index)">
                            <Close/>
                          </el-icon>
                        </div>
                        <form-design-render :config="element"/>
                      </div>
                    </div>
                  </template>
                </draggable>
              </div>
            </div>
          </div>
        </div>
      </div>
    </div>

    <div class="layout-param" v-if="isShow">
      <div class="tool-nav-r" v-if="selectFormItem">
        <i :class="selectFormItem.icon" style="margin-right: 5px; font-size: medium"></i>
        <span>{{ selectFormItem.title }}</span>
      </div>
      <div v-if="!selectFormItem || forms.length === 0" class="tip">
        😀 选中控件后在这里进行编辑
      </div>
      <div style="text-align:left; padding: 10px" v-else>
        <form-component-config/>
      </div>
    </div>
  </div>

  <el-dialog v-model="viewFormVisible" title="表单预览" width="800px">
    <el-radio-group v-model="formPreviewModel" @change="formPreviewModelChange">
      <el-radio-button label="E">编辑</el-radio-button>
      <el-radio-button label="R">查看</el-radio-button>
    </el-radio-group>
    <form-render v-if="viewFormVisibleRender" ref="form" :form-items="forms" v-model:value="formValue"
                 :is-preview="true" :mode="formPreviewModel"/>
  </el-dialog>
</template>

<script setup>
import draggable from 'vuedraggable';
import FormRender from './FormRender.vue'
import FormDesignRender from './FormDesignRender.vue'
import FormComponentConfig from './FormComponentConfig.vue'
import {ValueType} from "./ComponentsConfigExport";
import {CopyDocument, Close} from '@element-plus/icons-vue'
import {ref, computed, defineExpose} from 'vue'
import {baseComponents} from './ComponentsConfigExport'
import {ElMessage, ElMessageBox} from "element-plus";
import {useProcessStore} from '@/stores/processStore.js'

const processStore = useProcessStore()

const form = ref()
const isStart = ref(false)
const isShow = ref(true)
const showMobile = ref(false)
const formValue = ref({})
const formPreviewModel = ref("E")
const viewFormVisible = ref(false)
const viewFormVisibleRender = ref(true)
const forms = ref(processStore.getDesign().formItems)
const formItems = computed(() => {
  return processStore.getDesign().formItems
})
const selectFormItem = computed({
  get() {
    return processStore.getSelectedFormItem()
  },
  set(val) {
    processStore.setSelectedFormItem(val)
  },
})

const clone = (obj) => {
  obj.id = getId()
  return JSON.parse(JSON.stringify(obj));
}
// const copy = (node, index) => {
//   console.log(node)
//   processStore.getDesign().formItems.push(index + 1, 0,{...node})
// }

const formPreviewModelChange = () => {
  // 卸载
  // viewFormVisibleRender.value= false
  // nextTick(()=>{
  //   // 加载
  //   viewFormVisibleRender.value= true
  // })
}
const delItem = (index) => {
  ElMessageBox.confirm('删除组件将会连带删除包含该组件的条件以及相关设置，是否继续?', '提示', {
    confirmButtonText: '确 定',
    cancelButtonText: '取 消',
    type: 'warning'
  }).then(() => {
    if (processStore.getDesign().formItems[index].name === 'SpanLayout') {
      //删除的是分栏则遍历删除分栏内所有子组件
      processStore.getDesign().formItems[index].props.items.forEach(item => {
        removeFormItemAbout(item)
      })
      processStore.getDesign().formItems[index].props.items.length = 0
    } else {
      removeFormItemAbout(processStore.getDesign().formItems[index])
    }
    processStore.getDesign().formItems.splice(index, 1)
  })
}

const viewForms = () => {
  viewFormVisible.value = true
  formValue.value = {}
}

const removeFormItemAbout = async (item) => {
  processStore.nodeMap.forEach(node => {
    //搜寻条件，进行移除
    if (node.type === 'CONDITION') {
      node.props.groups.forEach(group => {
        let i = group.cids.remove(item.id)
        if (i > -1) {
          //从子条件移除
          group.conditions.splice(i, 1)
        }
      })
    }
    //搜寻权限，进行移除
    if (node.type === 'ROOT' || node.type === 'APPROVAL' || node.type === 'CC') {
      node.props.formPerms.removeByKey('id', item.id)
      if (node.props.formUser === item.id) {
        node.props.formUser = ''
      }
    }
  })
}

const getId = () => {
  return 'field' + (Math.floor(Math.random() * (99999 - 10000)) + 10000).toString()
      + new Date().getTime().toString().substring(5);
}
const getSelectedClass = (element) => {
  return processStore.getSelectedFormItem() && processStore.getSelectedFormItem().id === element.id ?
      'border-left: 4px solid #409eff' : ''
}

const selectItem = (element) => {
  isShow.value = false
  selectFormItem.value = element
  nextTick(() => {
    isShow.value = true
  })
}


const validateItem = (err, titleSet, item) => {
  if (titleSet.has(item.title) && item.name !== 'SpanLayout') {
    err.push(`表单 ${item.title} 名称重复`)
  }
  titleSet.add(item.title)
  if (item.name === 'SelectInput' || item.name === 'MultipleSelect') {
    if (item.props.options.length === 0) {
      err.push(`${item.title} 未设置选项`)
    }
  } else if (item.name === 'TableList') {
    if (item.props.columns.length === 0) {
      err.push(`明细表 ${item.title} 内未添加组件`)
    }
  } else if (item.name === 'SpanLayout') {
    if (item.props.items.length === 0) {
      err.push('分栏内未添加组件')
    } else {
      item.props.items.forEach(sub => validateItem(err, titleSet, sub))
    }
  }
}

const validate = () => {
  let err = []
  if (processStore.getDesign().formItems.length > 0) {
    let titleSet = new Set()
    processStore.getDesign().formItems.forEach(item => {
      //主要校验表格及分栏/选择器/表单名称/是否设置
      validateItem(err, titleSet, item)
    })
  } else {
    err.push('表单为空，请添加组件')
  }
  return err
}


defineExpose({
  validate
})

</script>

<style lang="scss" scoped>

.form-design {
  display: flex;

}

.choose {
  border: 1px dashed #1890FF !important;
}

.process-form {
  //.el-form-item__label {
  //  padding: 0 0;
  //}
}

.components-nav {
  box-sizing: content-box;
  display: flex;
  align-items: center;
  margin: 12px 12px 0;
  height: 28px;
  box-shadow: 0 2px 4px 0 rgba(17, 31, 44, 0.04);
  border: 1px solid #ecedef;
  border-radius: 16px;
  background-color: #fff;

  .selected {
    color: #1890FF;
  }

  .border {
    border-left: 1px solid #f5f6f6;
    border-right: 1px solid #f5f6f6;
  }

  span {
    flex: 1;
    display: flex;
    align-items: center;
    justify-content: center;
    height: 100%;
    font-size: 12px;
    color: rgba(17, 31, 44, 0.72);
    cursor: pointer;

    &:hover {
      color: #1890FF;
    }
  }
}

.components {
  overflow-x: hidden;
  overflow-y: scroll;
  //margin-top: 20px;
  //padding: 0 20px;
  font-size: 12px;
  width: 100%;
  color: rgba(17, 31, 44, 0.85);

  & > p {
    padding: 0 20px;
  }

  .drag {
    margin-left: 20px;
    display: flex;
    flex-wrap: wrap;
    align-items: center;

    li {
      text-align: center;
      display: flex;
      align-items: center;
      width: 124px;
      height: 38px;
      margin-bottom: 12px;
      border: 1px solid transparent;
      border-radius: 8px;
      cursor: grab;
      background-color: #fff;

      &:hover {
        border: 1px solid #1890FF;
        color: #1890FF;
      }

      i {
        margin: 0 12px;
      }
    }

    li:nth-child(odd) {
      margin-right: 8px;
    }
  }
}

.layout-main {
  width: 80%;
  background-color: #feffff;

  .tool-nav {
    font-size: medium;
    padding: 8px 20px;
    background: #fafafb;
    border-bottom: 1px solid #ebecee;

    div:first-child {
      display: inline-block;
      text-align: left;

      i {
        margin-right: 10px
      }
    }

    div:last-child {
      float: right;

      i {
        margin-left: 10px
      }
    }

    i {
      color: #7a7a7a;
      cursor: pointer;

      &:hover {
        color: #4b4b4b;
      }
    }
  }

  .work-form {
    margin: 0 auto;
    //height: calc(100% - 38px);
    overflow-y: auto;
    background: rgb(245, 246, 246);
    border-left: 1px solid rgb(235, 236, 238);
    border-right: 1px solid rgb(235, 236, 238);
    margin-right: -1px;

    .pc {
      margin-top: 4%;
      padding: 0 150px;

      .drag-from {
        height: calc(100vh - 190px);
        background-color: rgb(245, 246, 246);

        .form-item, li {
          cursor: grab;
          background: #ffffff;
          padding: 10px;
          border: 1px solid #ebecee;
          margin: 5px 0;
        }
      }
    }

    .mobile {
      margin-left: auto;
      margin-right: auto;
      width: 360px;
      max-height: 640px;
      margin-top: 4%;
      border-radius: 24px;
      box-shadow: 0 8px 40px 0 rgba(17, 31, 44, 0.12);

      .bd {
        border: 1px solid rgba(17, 31, 44, 0.08);
        border-radius: 24px;
        padding: 10px 10px;
        background-color: #ffffff;

        .form-content {
          padding: 3px 2px;
          border-radius: 14px;
          background-color: #f2f4f5;

          .drag-from {
            width: 100%;
            height: calc(100vh - 190px);
            min-height: 200px;
            max-height: 600px;
          }

          .form {
            overflow-y: auto;
            width: 100%;
            display: inline-block;
            max-height: 640px;

            .form-item, li {
              border: 1px solid #ffffff;
              list-style: none;
              background: #ffffff;
              padding: 10px;
              margin: 5px 0;
              cursor: grab;
            }
          }
        }
      }
    }

    .tip {
      //float: left;
      margin: 0 auto;
      width: 65%;
      max-width: 400px;
      padding: 35px 20px;
      border-radius: 10px;
      border: 1px dashed rgba(25, 31, 37, 0.12);
      margin-top: 50px;
      text-align: center;
      font-size: 14px;
      color: rgb(122, 122, 122);
      z-index: 9999;

      &:hover {
        border: 1px dashed #1890FF;
      }
    }
  }

}

.layout-param {
  width: 300px;
  text-align: center;
  font-size: 14px;
  color: rgb(122, 122, 122);

  .tool-nav-r {
    text-align: left;
    font-size: small;
    border-left: 1px solid #ebecee;
    padding: 8px 20px;
    background: #fafafb;
    border-bottom: 1px solid #ebecee;
  }

  .tip {
    margin-top: 150px;
  }
}

.flip-list-move {
  transition: transform 0.5s;
}

.no-move {
  transition: transform 0s;
}

.select {
  color: #4b4b4b !important;
}

.form-header {
  font-size: small;
  color: #818181;
  text-align: left;
  position: relative;
  background-color: #fff;

  p {
    position: relative;
    margin: 0 0 10px 0;

    span {
      position: absolute;
      left: -8px;
      top: 3px;
      color: rgb(217, 0, 19);
    }
  }

  .option {
    position: absolute;
    top: -10px;
    right: -10px;

    i {
      font-size: large;
      cursor: pointer;
      color: #8c8c8c;
      padding: 5px;

      &:hover {
        color: #f56c6c;
      }
    }
  }
}

::-webkit-scrollbar {
  width: 4px;
  height: 4px;
  background-color: #f8f8f8;
}

::-webkit-scrollbar-thumb {
  border-radius: 16px;
  background-color: #e8e8e8;
}
</style>
