<template>
  <el-dialog
    class="dialog-just-form"
    :visible="dialogVisible"
    @close="handleClose"
    :destroy-on-close="false"
    :close-on-click-modal="configs.clickModalToClose ?? true"
    :fullscreen="fullscreen"
  >
    <!-- title  -->
    <div slot="title" class="dialog-title">
      <h1 class="">
        {{ detailMode ? "查看详情" : dataForm.id ? "编辑" : "新增" }}
      </h1>
    </div>

    <!-- form  -->
    <el-form ref="dataForm" :model="dataForm" v-loading="loadingStatus">
      <el-row v-for="(row, rowIndex) in configs.form.rows" :key="'row_' + rowIndex" :gutter="20">
        <el-col v-for="(col, colIndex) in row" :key="colIndex" :span="24 / row.length" :class="{ h0: col.hidden }">
          <!-- 通过多个 col === null 可以控制更灵活的 span 大小 -->
          <el-form-item v-if="col !== null" :label="col.label" :prop="col.prop" :rules="col.rules || null">
            <el-input v-if="col.input" v-model="dataForm[col.prop]" clearable :disabled="detailMode" v-bind="col.elparams" />
            <el-cascader
              v-if="col.cascader"
              v-model="dataForm[col.prop]"
              :options="col.options"
              :disabled="detailMode"
              v-bind="col.elparams"
            ></el-cascader>
            <el-select
              v-if="col.select"
              v-model="dataForm[col.prop]"
              clearable
              :disabled="detailMode"
              v-bind="col.elparams"
              @change="handleSelectChange(col, $event)"
            >
              <el-option v-for="(opt, optIdx) in col.options" :key="'option_' + optIdx" :label="opt.label" :value="opt.value" />
            </el-select>
            <el-switch
              v-if="col.switch"
              v-model="dataForm[col.prop]"
              :active-value="col.activeValue ?? 1"
              :inactive-value="col.activeValue ?? 0"
              @change="handleSwitchChange"
              :disabled="detailMode"
            />
            <el-input v-if="col.textarea" type="textarea" v-model="dataForm[col.prop]" :disabled="detailMode" v-bind="col.elparams" />
            <el-upload
              v-if="col.upload"
              :key="'upload_' + Math.random()"
              :action="col.actionUrl"
              :file-list="col.fileList"
              :disabled="detailMode || !dataForm.id"
              :on-change="handleUploadChange"
              v-bind="col.elparams"
              :headers="uploadHeaders"
            >
              <el-button type="primary" size="small">选择文件</el-button>
              <div slot="tip" class="el-upload__tip">只能上传jpg/png文件，且不超过500kb</div>
            </el-upload>
            <div class="" v-if="col.component" style="margin: 42px 0 0">
              <!-- 下面这个 component 几乎是为 富文本 quill 定制的了... TODO：后续可能会根据业务需求创建新的版本  -->
              <component
                :is="col.component"
                :key="'component_' + col.prop"
                @update:modelValue="handleComponentModelUpdate(col.prop, $event)"
                :modelValue="dataForm[col.prop]"
                :mode="detailMode ? 'detail' : dataForm.id ? 'edit' : 'create'"
              />
            </div>
            <!-- add more...  -->
          </el-form-item>
        </el-col>
      </el-row>
    </el-form>

    <!-- footer  -->
    <div slot="footer">
      <template v-for="(operate, index) in configs.form.operations">
        <el-button v-if="showButton(operate)" :key="'operation_' + index" :type="operate.type" @click="handleBtnClick(operate)">{{
          operate.label
        }}</el-button>
      </template>
      <el-button @click="handleBtnClick({ name: 'cancel' })">取消</el-button>
    </div>
  </el-dialog>
</template>

<script>
import { pick as __pick } from "@/utils/filters";
import Cookies from "js-cookie";

export default {
  name: "DialogJustForm",
  props: {
    configs: {
      type: Object,
      default: () => ({
        clickModalToClose: true,
        forms: null,
      }),
    },
    dialogVisible: {
      type: Boolean,
      default: false,
    },
    fullscreen: {
      type: Boolean,
      default: false
    }
  },
  inject: ["urls"],
  data() {
    const dataForm = {};
    this.configs.form.rows.forEach((row) => {
      row.forEach((col) => {
        dataForm[col.prop] = col.default ?? null;

        if (col.fetchData)
          col.fetchData().then(({ data: res }) => {
            if (res.code === 0 && res.data.list) {
              this.$set(
                col,
                "options",
                res.data.list.map((i) => ({ label: i.name, value: i.id }))
              );
            } else {
              col.options.splice(0);
            }
          });
      });
    });
    return {
      loadingStatus: false,
      dataForm,
      detailMode: false,
      baseDialogConfig: null,
    };
  },
  computed: {
    uploadHeaders() {
      return {
        token: Cookies.get("token") || "",
      };
    },
  },
  methods: {
    /** utitilities */
    showButton(operate) {
      const notDetailMode = !this.detailMode;
      const showAlways = operate.showAlways ?? false;
      const editMode = operate.showOnEdit && this.dataForm.id;
      const addMode = !operate.showOnEdit && !this.dataForm.id;
      const permission = operate.permission ? this.$hasPermission(operate.permission) : true;
      return notDetailMode && (showAlways || ((editMode || addMode) && permission));
    },

    resetForm(excludeId = false, immediate = false) {
      setTimeout(
        () => {
          console.log("[Dialog Just Form] clearing form...");
          Object.keys(this.dataForm).forEach((key) => {
            if (excludeId && key === "id") return;
            this.dataForm[key] = null;
          });
          console.log("[Dialog Just Form] cleared form...", this.dataForm);
          this.$refs.dataForm.clearValidate();
          this.$emit("dialog-closed"); // 触发父组件销毁自己
        },
        immediate ? 0 : 200
      );
    },

    /** init **/
    init(parentId, detailMode) {
      if (this.$refs.dataForm) {
        this.$refs.dataForm.clearValidate();
      }

      this.detailMode = detailMode ?? false;
      this.$nextTick(() => {
        this.dataForm.parentId = parentId || null;
      });
    },

    handleComponentModelUpdate(propName, { subject, payload: { data } }) {
      this.dataForm[propName] = JSON.stringify(data);
      console.log("[DialogJustForm] handleComponentModelUpdate", this.dataForm[propName]);
    },

    handleBtnClick(payload) {
      console.log("btn click payload: ", payload);

      if ("name" in payload) {
        switch (payload.name) {
          case "cancel":
            this.handleClose();
            break;
          case "reset":
            this.resetForm(true, true); // true means exclude id, immediate execution
            break;
          case "add":
          case "update": {
            this.$refs.dataForm.validate((passed, result) => {
              if (passed) {
                // 如果通过验证
                this.loadingStatus = true;
                const method = payload.name === "add" ? "POST" : "PUT";
                this.$http({
                  url: this.urls.base,
                  method,
                  data: this.dataForm,
                })
                  .then(({ data: res }) => {
                    console.log("[add&update] res is: ", res);
                    this.loadingStatus = false;
                    if (res.code === 0) {
                      this.$message.success(payload.name === "add" ? "添加成功" : "更新成功");
                      this.$emit("refreshDataList");
                      this.handleClose();
                    } else {
                      this.$message({
                        message: `${res.code}: ${res.msg}`,
                        type: "error",
                        duration: 2000,
                      });
                    }
                  })
                  .catch((errMsg) => {
                    this.$message.error("参数错误：" + errMsg);
                    if (this.loadingStatus) this.loadingStatus = false;
                  });
              } else {
                // 没有通过验证
                // this.$message.error(JSON.stringify(result));
                this.$message.error("请核查字段信息");
              }
            });
          }
        }
      }
    },

    handleClose() {
      this.resetForm();
      this.$emit("update:dialogVisible", false);
    },
  },
};
</script>

<style scoped>
.dialog-just-form >>> .el-dialog__body {
  /* padding-top: 16px !important;
  padding-bottom: 16px !important; */
  padding-top: 0 !important;
  padding-bottom: 0 !important;
}

.el-select,
.el-cascader {
  width: 100% !important;
}

.dialog-just-form >>> .el-dialog__header {
  padding: 10px 20px 10px;
  /* background: linear-gradient(to bottom, rgba(0, 0, 0, 0.25), white); */
}

.h0 {
  height: 0;
  width: 0;
}
</style>
