<template>
  <el-dialog
    class="dialog-just-form"
    :visible="dialogVisible"
    @close="handleClose"
    :destroy-on-close="false"
    :close-on-click-modal="configs.clickModalToClose ?? false"
  >
    <!-- 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">
          <!-- 通过多个 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 || col.forceDisabled"
              v-model="dataForm[col.prop]"
              clearable
              :disabled="detailMode || col.forceDisabled"
              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-date-picker v-if="col.datetime" v-model="dataForm[col.prop]" :disabled="detailMode" v-bind="col.elparams" />

            <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",
  components: {},
  props: {
    configs: {
      type: Object,
      default: () => ({
        clickModalToClose: false,
        forms: null,
      }),
    },
    dialogVisible: {
      type: Boolean,
      default: false,
    },
    // 特殊需求
    // bomCode: {
    //   type: String,
    //   default: "x",
    // },
  },
  inject: ["urls"],
  data() {
    const dataForm = {};
    const delayList = [];

    this.configs.form.rows.forEach((row) => {
      row.forEach((col) => {
        dataForm[col.prop] = col.default ?? null;

        if (col.fetchData && typeof col.fetchData === "function") {
          if (col.delayRequest) delayList.push(col);
          // let doRequest = null;
          // if (col.fetchData.length) {
          //   console.log(`this.bomCode '${this.bomCode}'`);
          //   // 如果有参数
          //   doRequest = col.fetchData.bind(this.bomCode);
          // } else doRequest = col.fetchData;
          else
            col.fetchData().then(({ data: res }) => {
              if (res.code === 0) {
                if ("list" in res.data) {
                  this.$set(
                    col,
                    "options",
                    res.data.list.map((i) => ({
                      label: col.optionLabelProp ? i[col.optionLabelProp] : i.name,
                      value: col.optionValue ? i[col.optionValue] : i.id,
                    }))
                  );
                } else if (Array.isArray(res.data)) {
                  this.$set(
                    col,
                    "options",
                    res.data.map((i) => ({
                      label: col.optionLabelProp ? i[col.optionLabelProp] : i.name,
                      value: col.optionValue ? i[col.optionValue] : i.id,
                    }))
                  );
                } else {
                  console.log("请检查返回的数据类型");
                }
              } else {
                col.options.splice(0);
              }
            });
        }
      });
    });
    return {
      loadingStatus: false,
      dataForm,
      detailMode: false,
      baseDialogConfig: null,
      delayList,
    };
  },
  computed: {
    uploadHeaders() {
      return {
        token: Cookies.get("token") || "",
      };
    },
  },
  methods: {
    handleFilelistUpdate(newFilelist) {
      // TODO: 直接访问 .files 可能不太合适
      this.dataForm.files = newFilelist.map((file) => ({
        id: file.id,
        name: file.name,
        url: file.url,
        typeCode: file.typeCode,
      }));
      // 更新请求
      if ("id" in this.dataForm && this.dataForm.id !== null && this.dataForm.id !== undefined) this.addOrUpdate("PUT");
      else
        this.$notify({
          title: "等待保存",
          message: "已添加文件，请手动点击保存！",
          type: "warning",
          duration: 2500,
        });
    },

    /** 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(
        () => {
          Object.keys(this.dataForm).forEach((key) => {
            if (excludeId && key === "id") return;
            this.dataForm[key] = null;
          });
          console.log("[DialogJustForm resetForm()] clearing form...");
          this.$refs.dataForm.clearValidate();
          this.$emit("dialog-closed"); // 触发父组件销毁自己
        },
        immediate ? 0 : 200
      );
    },

    init(row) {
      this.loadingStatus = true;
      // id 和 混料机 ID 混料订单号 和 配方id
      const { id, code, blender, bomId } = row;

      // console.log(" { id, code, blender } = row;", row);

      if (this.$refs.dataForm) {
        this.$refs.dataForm.clearValidate();
      }

      this.delayList.forEach((col) => {
        // console.log("delay fetch", col);
        // 需要延迟获取异步数据的 col 配置
        if (col.fetchDataParam in row) {
          // console.log("delay row ", row, row[col.fetchDataParam]);
          col.fetchData(row[col.fetchDataParam]).then(({ data: res }) => {
            if (res.code === 0) {
              if ("list" in res.data) {
                this.$set(
                  col,
                  "options",
                  res.data.list.map((i) => ({
                    label: col.optionLabelProp ? i[col.optionLabelProp] : i.name,
                    value: col.optionValue ? i[col.optionValue] : i.id,
                  }))
                );
              } else if (Array.isArray(res.data)) {
                this.$set(
                  col,
                  "options",
                  res.data.map((i) => ({
                    label: col.optionLabelProp ? i[col.optionLabelProp] : i.name,
                    value: col.optionValue ? i[col.optionValue] : i.id,
                  }))
                );
              } else {
                console.log("请检查返回的数据类型");
              }
            } else {
              col.options.splice(0);
            }

            this.loadingStatus = false;
          });
        }
      });

      this.detailMode = false;

      this.dataForm.id = id || null;
      this.dataForm.blender = blender;
      this.dataForm.code = code;
      this.dataForm.bomId = bomId;
      if (!this.delayList.length) this.loadingStatus = false;
    },

    /** handlers */
    handleSelectChange(col, eventValue) {
      // console.log("[dialog] select change: ", col, eventValue);
      this.$forceUpdate();
    },

    handleSwitchChange(val) {
      console.log("[dialog] switch change: ", val, this.dataForm);
    },

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

    addOrUpdate(method = "POST") {
      this.$refs.dataForm.validate((passed, result) => {
        if (passed) {
          this.loadingStatus = true;

          const { id, blender, bomId } = this.dataForm;

          return this.$http
            .get(this.urls.changeBlender, { params: { id, blender, bomId } })
            .then(({ data: res }) => {
              this.loadingStatus = false;
              if (res.code === 0) {
                this.$message.success("更新成功");
                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("请核查字段信息");
        }
      });
    },

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

      if ("name" in payload) {
        switch (payload.name) {
          case "cancel":
            this.handleClose();
            break;
          case "update":
            this.addOrUpdate();
            break;
        }
      } else {
        console.log("[x] 不是这么用的! 缺少name属性");
      }
    },

    handleUploadChange(file, fileList) {
      console.log("[Upload] handleUploadChange...", file, fileList);
    },

    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,
.el-date-editor {
  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); */
}
</style>
