<template>
  <div class="comp-content">
    <Dialog
      v-model="diaVisible"
      diaTitle="列表字段设置"
      top="2vh"
      width="80%"
      height="80%"
      body-class="table-form-dia"
      show-footer
      @close="closeFun"
    >
      <div class="content">
        <div class="toper">
          <div class="total">共{{ tableData.length }}个列表字段</div>
          <div class="add-btn">
            <el-button type="primary" plain @click="previewVisible = true">预览列表</el-button>
            <el-button type="primary" :icon="Plus" @click="addFun">新增字段</el-button>
          </div>
        </div>
        <div class="table">
          <vxe-table
            ref="vxeTableRef"
            :data="tableData"
            height="100%"
            :row-config="{
              drag: true
            }"
            @row-dragend="rowDragendFun"
          >
            <vxe-column type="seq" fixed="left" width="70" drag-sort />
            <vxe-column field="key" title="字段值" fixed="left" align="center" header-align="center" :min-width="120">
              <template #default="{ row }">
                <el-input v-model="row.key" placeholder="请输入" clearable />
              </template>
            </vxe-column>
            <vxe-column field="title" title="字段名称" fixed="left" align="center" header-align="center" :min-width="120">
              <template #default="{ row }">
                <el-input v-model="row.title" placeholder="请输入" clearable />
              </template>
            </vxe-column>
            <vxe-column field="type" title="字段类型" align="center" header-align="center" :min-width="100">
              <template #default="{ row }">
                <el-select v-model="row.type" placeholder="请选择">
                  <el-option label="默认" :value="1" />
                  <el-option label="扩展" :value="2" />
                </el-select>
              </template>
            </vxe-column>
            <vxe-column field="inputMode" title="表单输入类型" align="center" header-align="center" :min-width="130">
              <template #default="{ row }">
                <el-select v-model="row.inputMode" placeholder="请选择">
                  <el-option label="输入框" value="input" />
                  <el-option label="文本域" value="textarea" />
                  <el-option label="数字框" value="inputNumber" />
                  <el-option label="单选" value="select" />
                  <el-option label="多选" value="multipleSelect" />
                  <el-option label="单选框" value="radio" />
                  <el-option label="多选框" value="checkbox" />
                  <el-option label="日期" value="date" />
                  <el-option label="日期范围" value="daterange" />
                  <el-option label="上传图片" value="uploadImg" />
                  <el-option label="选择文件" value="choseFile" />
                  <el-option label="人员" value="userSelect" />
                  <el-option label="项目" value="projectSelect" />
                  <el-option label="人员(多选)" value="userSelectMultiple" />
                  <el-option label="项目(多选)" value="projectSelectMultiple" />
                  <el-option label="审核模版" value="approveList" />
                  <el-option label="插槽" value="slot" />
                </el-select>
              </template>
            </vxe-column>
            <vxe-column field="formOptions" title="表单配置" align="center" header-align="center" :min-width="150">
              <template #default="{ row }">
                <el-input-number v-if="row.inputMode === 'inputNumber'" v-model="row.formOptions" :min="1" :step="1" placeholder="步长" />
                <el-input v-else-if="['select', 'multipleSelect', 'radio', 'checkbox'].includes(row.inputMode)" v-model="row.formOptions" placeholder="请输入字典名称" clearable />
                <el-input-number v-else-if="row.inputMode === 'choseFile'" v-model="row.formOptions" :min="0" :step="1" step-strictly placeholder="个数限制" />
                <span v-else>/</span>
              </template>
            </vxe-column>
            <vxe-column field="inForm" title="表单中显示" align="center" header-align="center" :min-width="90">
              <template #default="{ row }">
                <el-switch v-model="row.inForm" />
              </template>
            </vxe-column>
            <vxe-column field="validate" title="输入正则" align="center" header-align="center" :min-width="120">
              <template #default="{ row }">
                <el-select v-model="row.validate" placeholder="请选择" multiple clearable>
                  <el-option label="必填" value="required" />
                  <el-option label="校验手机号" value="phone" />
                  <el-option label="校验邮箱" value="email" />
                  <el-option label="不允许特殊字符" value="hasNoSpecialChar" />
                  <el-option label="长度限制20" value="length20" />
                  <el-option label="长度限制100" value="length100" />
                </el-select>
              </template>
            </vxe-column>
            <vxe-column field="isShow" title="表格中显示" align="center" header-align="center" :min-width="90">
              <template #default="{ row }">
                <el-switch v-model="row.isShow" />
              </template>
            </vxe-column>
            <vxe-column field="tableSearch" title="表格搜索" align="center" header-align="center" :min-width="90">
              <template #default="{ row }">
                <el-switch v-model="row.tableSearch" />
              </template>
            </vxe-column>
            <vxe-column field="disabled" title="不可编辑" align="center" header-align="center" :min-width="90">
              <template #default="{ row }">
                <el-switch v-model="row.disabled" />
              </template>
            </vxe-column>
            <vxe-column field="width" title="表格列宽" align="center" header-align="center" :min-width="180">
              <template #default="{ row }">
                <el-input v-model="row.width" placeholder="请输入（auto, px, %）" clearable />
              </template>
            </vxe-column>
            <vxe-column field="tableActions" title="操作" fixed="right" width="65" align="center" header-align="center">
              <template #default="{ row }">
                <div class="actions">
                  <el-link type="danger" @click="delFun(row)">移除</el-link>
                </div>
              </template>
            </vxe-column>
          </vxe-table>
        </div>
      </div>
      <template #footer>
        <div>
          <el-button @click="closeFun">关闭</el-button>
          <el-button type="primary" @click="updateFun">确定</el-button>
        </div>
      </template>
    </Dialog>
    <Dialog v-model="previewVisible" diaTitle="预览" width="500" height="70%">
      <div class="form">
        <el-form :model="formData" label-width="auto">
          <el-form-item v-for="(item, index) in tableData" :key="index" v-show="item.inForm" :label="item.title">
            <template v-if="item.inForm">
              <FormItem :item="item" :form="formData">
                <template v-for="(name) in Object.keys($slots)" :key="name" #[name]="scope">
                  <slot :name="name" v-bind="scope" />
                </template>
              </FormItem>
            </template>
          </el-form-item>
        </el-form>
      </div>
    </Dialog>
  </div>
</template>

<script setup lang="ts">
import { ref, watch } from 'vue';
import { ElMessage } from 'element-plus';
import { Plus } from '@element-plus/icons-vue';
import Dialog from '@/components/common/dialog/index.vue';
import FormItem from './formItem.vue';
import { getFormConfigureApi, updateFormConfigureApi } from '@/api/system/systemData';

interface Props {
  modelValue: boolean;
  name: string;
}

const props = withDefaults(defineProps<Props>(), {
  modelValue: false,
  name: '',
});

const emit = defineEmits(['update:modelValue', 'update']);
const diaVisible = ref(false);
const previewVisible = ref(false);
const formData = ref<any>({});
const tableData = ref<any>([]);
const vxeTableRef = ref<any>();

watch(() => props.modelValue, (val: boolean) => {
  diaVisible.value = val;
  if (val) {
    getHeadDataFun();
  }
});

const getHeadDataFun = () => {
  const params = {
    formName: props.name,
  };
  getFormConfigureApi(params).then((res: any) => {
    if (res.code === 200) {
      const formConfig = JSON.parse(res.data.formConfig || '[]');
      tableData.value = formConfig;
    }
  });
};

const addFun = () => {
  tableData.value.push({
    title: '',
    key: '',
    isShow: false,
    inputMode: 'input',
    type: 2,
    inForm: false,
    width: '',
    _X_ROW_KEY: new Date().getTime(), // 覆盖vxe-table默认属性_X_ROW_KEY，避免警添加时重复警告
  });
};

const updateFun = () => {
  const build: any[] = [];
  tableData.value.forEach((item: any) => {
    if (item.key && item.title) {
      build.push(item);
    }
  });
  const params = {
    formName: props.name,
    formConfig: JSON.stringify(build),
  };
  updateFormConfigureApi(params).then((res: any) => {
    if (res.code === 200) {
      ElMessage.success('操作成功');
      closeFun();
      emit('update');
    }
  });
};

const delFun = (data: any) => {
  tableData.value.some((item: any, index: number) => {
    if (item.key === data.key) {
      tableData.value.splice(index, 1);
      return true;
    }
  });
};

const rowDragendFun = () => {
  tableData.value = vxeTableRef.value.getFullData();
};

const closeFun = () => {
  emit('update:modelValue', false);
};
</script>

<style lang="scss">
.table-form-dia {
  height: 75vh;
  .content {
    height: 100%;
    .toper {
      display: flex;
      align-items: center;
      justify-content: space-between;
      height: 48px;
      padding-bottom: var(--padding-normal);
      .total {
        color: var(--el-text-color-secondary);
      }
      .add-btn {
        text-align: right;
      }
    }
    .table {
      flex: 1;
      height: calc(100% - 48px);
      .actions {
        &::after {
          content: '';
          position: absolute;
          top: 0;
          bottom: 0;
          left: 0;
          width: 1px;
          background-color: var(--el-text-color-primary);
          filter: blur(5px);
        }
      }
    }
  }
}
</style>
