<template>
  <el-form ref="formDom" :model="field" :class="[{'label-gray': labelGray}]" :label-position="labelPosition" element-loading-text="加载中，请稍候" :label-width="label_width" >
    <el-row :gutter="gutter">
      <template v-for="item in form_item" :key="item.prop">
        <el-col v-if="!form_hidden[item.prop]" :span="item.col || 24">
          <component :is="'htmlComponent'" v-if="item.type === 'html'" :prop="item" />
          <el-form-item v-else :label="item.label" :prop="item.prop" :rules="item.rules">
            <!--自定义label-->
            <template v-if="item.label_html" #label>
              <span class="custom-label">
                <div>
                  <span style="position: relative;">
                    <label class="form-center" v-html="item.label_html.label || ''" />
                    <em v-if="item.label_html.spot" class="spot"></em>
                  </span>
                </div>
                <span :class="item.label_html.suffix_class" @click="item.label_html.suffix_callback && item.label_html.suffix_callback(item)" v-html="item.label_html.suffix_text || ''" />
              </span>
            </template>
            <!--动态组件-->
            <div v-show="control" style="width:100%">
              <component :is="item.type + 'Component'" v-if="item.type !== 'slot'" v-model:value="field[item.prop]" v-model:second-value="field[item.secondprop]" v-model:select-value="field[item.selProp]" :data="item" :header="item" :disabled="disabled[item.prop]" @callback="componentCallback" />
              <!--插槽-->
              <template v-else>
                <slot :name="item.slot_name" />
                <span v-if="item.tip" class="tip">{{ item.tip }}</span>
              </template>
            </div>
            <div v-show="!control">
              <slot v-if="item.slot_text" :name="item.slot_text" />
              <span v-else>{{ fieldText[item.prop] || '--' }}</span>
            </div>
          </el-form-item>
        </el-col>
      </template>
    </el-row>
    <!-- button -->
      <div :class="['form-button', {'dialog-footer': dialog}]">
        <template v-if="form_button && form_button.length > 0">
          <template v-for="button in form_button" :key="button.key">
            <template v-if="!button.hidden">
            <CdButton v-if="button.key === 'submit'" :loading="load || loading" margin="0 0 0 16px" :type="button.type" @click="button.callback ? button.callback() : handlerFormValidate()">
              {{ button.label }}
            </CdButton>
            <CdButton v-else-if="button.key === 'cancel'" margin="0 0 0 16px" border @click="button.callback ? button.callback() : handlerFormCancel()">
              {{ button.label }}
            </CdButton>
            <CdButton v-else :type="button.type" margin="0 0 0 16px" @click="button.callback && button.callback()">{{ button.label }}</CdButton>
            </template>
          </template>
        </template>
      </div>
  </el-form>
</template>

<script>
import { defineAsyncComponent, onBeforeUnmount, reactive, ref, watch } from "vue";
import { checkDataType } from "../common";
// hook
import { rulesHook } from "./hook/rulesHook";
import { relationHook } from "./hook/relationHook";
// props
import { props } from "./props";
// require import components
const files = require.context("@/cd-components/cd-control", true, /\index.vue$/);
const modules = {};
files.keys().forEach((key) => {
  const name = key.split("/");
  modules[name[1] + "Component"] = files(key).default || files(key);
});
export default {
  name: "BasisForm",
  components: {
    ...modules,
    CdButton: defineAsyncComponent(() => import("../cd-button")),
  },
  props,
  emits: ["callback", "cancel"],
  setup(props, { emit }) {
    const { InitRules } = rulesHook();
    const { HiddenItem, DisabledItem } = relationHook();
    // 校验规则处理
    const form_item = reactive(InitRules(props.item));
    const label_width = ref(props.labelWidth);
    const form_button = reactive(props.button);
    const form_disabled = reactive(props.disabled);
    const load = ref(false)
    let form_hidden = ref({});
    watch(() => props.hidden, (value) => {
      form_hidden.value = value
    })
    // 表单提交验证
    const formDom = ref(null);
    const handlerFormValidate = () => {
      formDom.value.validate((valid) => {
        if(valid) {
          if (checkDataType().isFunction(props.beforeChange)) {
            load.value = true
            props.beforeChange().then(() => {
              load.value = false
            }).catch(() => {
              load.value = false
            })
            return false
          }
          emit("callback")
        }
      });

      
    };
    const handlerFormCancel = () => {
      handlerFormReset()
      emit("cancel");
    };
    /**
     * 重置表单
     */
    const handlerFormReset = () => {
      formDom.value.resetFields();
    };
    // change 事件
    const componentCallback = (params) => {};

    /**
     * 生命周期
     */
    onBeforeUnmount(() => {
      form_hidden.value = {}
      handlerFormReset()
    })
    
    return {
      form_item,
      label_width,
      form_button,
      form_hidden,
      form_disabled,
      formDom,
      load,
      handlerFormValidate,
      handlerFormCancel,
      handlerFormReset,
      componentCallback,
    };
  },
};
</script>
<style lang="scss" scoped>
.form-button {
  width: 100%;
}
.form-left {
  text-align: left;
}
.form-center {
  text-align: center;
}
.form-right {
  text-align: right;
}
.custom-label {
  position: relative;
  > span {
    float: right;
  }
}
::v-deep .color-lable-danger {
  width: 6px;
  height: 6px;
  background: #ff6060;
  border-radius: 50%;
  position: absolute;
  right: -7px;
  top: 7px;
}
:deep(.el-input__wrapper) {
  border-radius: 0;
}
</style>
