<template>
  <div class="form-dynamic">
    <template v-if="isShowData">
      <div v-if="type === 'form'">
        <el-button
          title="添加"
          type="primary"
          icon="el-icon-plus"
          v-if="addBtn"
          size="mini"
          style="margin-bottom: 20px"
          circle
          @click="handleAddColumn()"
        ></el-button>
        <!-- @mouseenter="$set(row, 'delBtn', true)"
          @mouseleave="$set(row, 'delBtn', false)" -->

        <DynamicScroller
          :items="items"
          v-if="items && items.length"
          :min-item-size="54"
          class="scroll-view"
          key-field="$_keyField"
        >
          <template v-slot="{ item, index, active }">
            <DynamicScrollerItem
              :item="item"
              :active="active"
              :data-index="index"
              :size-dependencies="column"
            >
              <div class="form-dynamic-content" v-if="value[index]">
                <div v-if="optionsIndex" class="index">#{{ index + 1 }}</div>
                <div
                  v-if="delBtn && value[index] && value[index].showDelBtn"
                  class="delBtn"
                >
                  <el-button
                    title="删除"
                    type="danger"
                    icon="el-icon-delete"
                    size="mini"
                    circle
                    @click="handleDelColumn(index)"
                  ></el-button>
                </div>
                <template v-for="(c, cIndex) in column">
                  <div
                    v-if="c.type === 'dynamic'"
                    :key="cIndex"
                    style="width: 100%"
                    class="dynamic-form-container"
                  >
                    <el-form-item
                      :prop="c.prop"
                      :label-width="'0px'"
                      style="display: none"
                    >
                    </el-form-item>
                    <div class="dynamic-form-container_lable">
                      {{ c.label }}
                    </div>
                    <form-dynamic
                      :options="c.children"
                      :dynamic-data="c.dynamicData"
                      v-model="value[index][c.prop]"
                      :is-show-important="isShowImportant"
                    ></form-dynamic>
                  </div>

                  <el-col
                    :xs="c.xs || 24"
                    :sm="c.sm || 24"
                    :md="c.md || 24"
                    :lg="c.lg || c.span || 12"
                    :xl="c.span || 12"
                    :key="cIndex"
                    v-else
                    v-show="
                      c.display &&
                      !value[index]['$_hidden' + c.prop] &&
                      isShowIm(c.importantField)
                    "
                  >
                    <form-item-self
                      :form="value[index]"
                      type="form"
                      :item="c"
                      :columns="column"
                    ></form-item-self>
                  </el-col>
                </template>
              </div>
            </DynamicScrollerItem>
          </template>
        </DynamicScroller>
      </div>
      <vxe-table
        v-else
        :data="value"
        :align="headerAlign"
        resizable
        border
        highlight-hover-row
        max-height="300"
        :sort-config="{ trigger: 'cell' }"
        :scroll-y="{ gt: 10 }"
        class="el-table-self"
        empty-text="暂无数据"
      >
        <!-- :scroll-y="{ gt: 0}"   gt为 0 则虚拟滚动总是启用  -1关闭 -->
        <vxe-column label="add" width="60" v-if="addBtn || delBtn" fixed="left">
          <template #header>
            <el-button
              type="primary"
              icon="el-icon-plus"
              title="添加"
              v-if="addBtn"
              size="mini"
              circle
              @click="handleAddColumn()"
            ></el-button>
          </template>
          <template #default="{ rowIndex }">
            <el-button
              v-if="delBtn && value[rowIndex] && value[rowIndex].showDelBtn"
              type="danger"
              icon="el-icon-delete"
              size="mini"
              title="删除"
              circle
              @click="handleDelColumn(rowIndex)"
            ></el-button>
            <div v-else>{{ rowIndex + 1 }}</div>
          </template>
        </vxe-column>
        <template v-for="(c, cIndex) in column">
          <vxe-column
            :key="cIndex"
            :title="c.label"
            :align="align"
            :min-width="c.width"
            :class-name="c.required ? 'is-required' : ''"
            v-if="isShowIm(c.importantField)"
            :show-overflow="false"
          >
            <template #default="{ rowIndex }">
              <form-item-self
                v-show="c.display && !value[rowIndex]['$_hidden' + c.prop]"
                :form="value[rowIndex]"
                :columns="column"
                type="form"
                :item="c"
                style="margin: 0"
                hidden-label
              ></form-item-self>
            </template>
          </vxe-column>
        </template>
      </vxe-table>
    </template>
    <div v-else>无</div>
  </div>
</template>

<script>
/**
 * @description 自定义子表单
 */
import FormItemSelf from "./FormItemSelf.vue"
import { isObject } from "@/utils/validate"
export default {
  name: "FormDynamic",
  inject: {
    vwForm: {
      default: {},
    },
  },
  props: {
    options: Object, // 配置数据
    dynamicData: Array, //初始数据
    value: {},
    isShowImportant: {
      type: Boolean,
      default: false,
    },
  },
  components: { FormItemSelf },
  data() {
    const {
      addBtn,
      align,
      delBtn,
      headerAlign,
      column,
      index,
      type,
    } = this.$props.options
    const initFieldMap = {}
    column &&
      column.forEach((item) => {
        if (!item.prop) return false
        if (
          item.type === "daterange" ||
          item.type === "dynamic" ||
          item.type === "checkbox" ||
          item.type === "cascader" ||
          (item.type === "select" && item.multiple)
        ) {
          initFieldMap[item.prop] = []
        } else if (
          item.type === "dental-tab" ||
          item.type === "dental-tab-tj"
        ) {
          initFieldMap[item.prop] = {}
        } else {
          initFieldMap[item.prop] = item.value || ""
        }
      })
    return {
      type,
      addBtn,
      align,
      delBtn,
      headerAlign,
      column,
      optionsIndex: index,
      initFieldMap,
    }
  },
  computed: {
    isShowIm() {
      return function (val) {
        return !this.isShowImportant ? true : val
      }
    },
    isShowData() {
      const detail = this.vwForm.detail
      if (!detail) return true
      return !this.isEmpty(this.value, true)
    },
    items() {
      return (
        this.value &&
        this.value.map((item, index) => {
          return {
            ...item,
            $_keyField: index,
          }
        })
      )
    },
  },

  methods: {
    isEmpty(value, flag) {
      let empty = !value
      if (value === 0) empty = false
      else if (Array.isArray(value)) {
        empty = true
        if (value.length > 0) {
          // 有数据 取第一项数据判断是否为空对象
          const firstValue = value[0]
          if (isObject(firstValue)) {
            const isNotEmpty = Object.keys(firstValue).some((key) => {
              if (flag) {
                // 只判断this.column中的数据
                if (
                  this.column.find(
                    (_) => _.type !== "dynamic" && _.prop === key
                  )
                ) {
                  return !this.isEmpty(firstValue[key])
                }
                return false
              }
              return !this.isEmpty(firstValue[key])
            })
            empty = !isNotEmpty
          } else {
            empty = false
          }
        }
      }
      return empty
    },
    handleAddColumn() {
      if (!this.value) {
        this.setValue([])
      }
      this.$nextTick(() => {
        this.value.push({
          ...this.deepClone(this.initFieldMap),
          showDelBtn: true, // 手动添加的可删除
        })
      })
    },
    handleDelColumn($index) {
      this.value.splice($index, 1)
    },
    setValue(value) {
      this.$emit("input", value)
    },
    // 子表单初始化数据
    setDynamicData() {
      if (!this.value || !Array.isArray(this.value)) {
        this.setValue([])
      }
      if (this.dynamicData && this.dynamicData.length > 0) {
        this.$nextTick(() => {
          this.$watch(
            "value",
            (value) => {
              if (!value || value.length === 0) {
                const data = this.deepClone(this.dynamicData)
                data.forEach((item) => {
                  const initFieldMap = this.deepClone(this.initFieldMap)
                  for (let k in initFieldMap) {
                    // if (!item[k] && initFieldMap[k]) {
                    //   item[k] = initFieldMap[k]
                    // }
                    item[k] = item[k] || initFieldMap[k]
                  }
                })
                this.setValue(data)
              }
              // else {
              //   value.forEach((item, index) => {
              //     if (!isObject(item)) {
              //       this.$set(value, index, {})
              //     }
              //   })
              // }
            },
            { immediate: true }
          )
        })
      }
    },
  },
  created() {
    this.setDynamicData()
  },
}
</script>
<style lang="scss" scoped>
::v-deep .el-table__header .is-required {
  .cell::before {
    content: "*";
    color: #f56c6c;
    margin-right: 4px;
  }
}
.scroll-view {
  max-height: 500px;
  overflow: auto;
}
.form-dynamic-content {
  padding: 10px;
  &:hover {
    background-color: #ecf8ff;
    outline: 1px dashed #ccc;
  }

  position: relative;
  display: flex;
  padding-left: 82px;
  flex-wrap: wrap;
  margin-bottom: 20px;
  .index {
    font-size: 18px;
    font-weight: bold;
    position: absolute;
    left: 40px;
  }
  .delBtn {
    position: absolute;
    left: 0;
    width: 28px;
    height: 28px;
    text-align: center;
  }
}
.el-table-self {
  ::v-deep .el-form-item {
    background: transparent !important;
    padding: 0 !important;
  }
  ::v-deep .vxe-cell {
    overflow: visible !important;
    text-overflow: clip !important;
    white-space: normal !important;

    .el-radio-group,
    .el-checkbox-group {
      text-align: left;
    }
  }
}
</style>
