<script>
import linkPickModal from "./linkPickModal.vue";
import { save, show, index, destroy } from "@/api/system/baseForm";
import { getparameter } from "@/api/system/dictionary";
import { domMap } from "@/const/inputType";
import { addPropsMap } from "@/const/addProps";
import { deepCopy } from "@/utils";
import validation from '@/const/validation';
export default {
  components: {
    linkPickModal,
  },
  props: {
    formInfo: {
      type: Array,
      default: () => [],
    },
    tableName: String,
  },
  render(h) {
    return h("div", [
      h(
        "el-dialog",
        {
          props: {
            title: "新增",
            visible: this.dialogVisible,
            width: "80vw",
            "close-on-click-modal": false
          },
          on: {
            "update:visible": (val) => {
              this.dialogVisible = val;
            },
          },
        },
        [
          h(
            "el-scrollbar",
            {
              style: {
                height: "58vh",
              },
            },

            [
              h(
                "el-form",
                {
                  ref: "elForm",
                  class: "form-body",
                  props: {
                    model: this.form,
                    labelWidth: "100px",
                    rules: this.rules,
                    labelPosition: "top",
                    size: "small",
                  },
                },
                (() => {
                  let dom = [];
                  this.formInfo
                    .filter((i) => i.form_show)
                    .forEach((i, index) => {
                      dom.push(
                        h(
                          "el-form-item",
                          {
                            ref: `elFormItem${i.field}`,
                            style: {
                              width: "100%",
                            },
                            props: {
                              label: i.name,
                              prop: i.field,
                              required:
                                i.validation instanceof Array
                                  ? !!i.validation.find((i) => i === "required")
                                  : false,
                            },
                          },
                          this.$scopedSlots[i.field]
                            ? this.$scopedSlots[i.field]({
                              fieldInfo: i,
                              form: this.form,
                              file: this.file,
                            })
                            : i._relations &&
                            i.edit_input !== "file" &&
                            i.edit_input !== "files"
                              ? [
                                h(
                                  "el-input",
                                  {
                                    attrs: {
                                      placeholder: i.help || `请选择${i.name}`,
                                    },
                                    props: {
                                      readonly: true,
                                      value:
                                        (this.pickModalText[i.field]),
                                    },
                                    on: {
                                      ['focus']:e => {
                                        this.pickedLinkField.field = i.field;
                                        this.pickedLinkField.linkType =
                                          i._relations.link_relation;
                                        this.pickedLinkField.linkTableName =
                                          i._relations.link_table_name;
                                        this.pickedLinkField.originalRows =
                                          this.originalForm[
                                            i._relations.link_with_name
                                            ];
                                        this.$refs["linkPickModal"].show();
                                      }
                                    },
                                  }
                                ),
                              ]
                              : [
                                h(
                                  domMap.get(i.edit_input),
                                  {
                                    ref: `elEdit_${i.field}`,
                                    style: {
                                      width: "100%",
                                    },
                                    props: {
                                      ...addPropsMap.get(i.edit_input),
                                      ...this.extraProps(i),
                                      placeholder: i.help,
                                      value: this.form[i.field],
                                    },
                                    attrs: {
                                      placeholder: i.help || `请填写${i.name}`,
                                    },
                                    on: {
                                      [this.getEventType(i.edit_input)]: (
                                        e
                                      ) => {
                                        if (i.field) {
                                          this.form[i.field] = e;
                                          this.form = Object.assign(
                                            {},
                                            this.form
                                          );
                                        }
                                      },
                                    },
                                    scopedSlots:
                                      i.edit_input === "file" ||
                                      i.edit_input === "files"
                                        ? {
                                          file: (scope) => {
                                            let { file } = scope;
                                            return [
                                              h("div", {}, [
                                                h("i", {
                                                  class: {
                                                    "el-icon-circle-check":
                                                      file.status ===
                                                      "success",
                                                    "el-icon-loading":
                                                      file.status ===
                                                      "uploading",
                                                  },
                                                  style: {
                                                    color:
                                                      file.status ===
                                                      "success"
                                                        ? "green"
                                                        : "",
                                                  },
                                                }),
                                                h(
                                                  "a",
                                                  {
                                                    attrs: {
                                                      href: file.url,
                                                      download: file.name,
                                                    },
                                                    class: {
                                                      "uploaded-a":
                                                        file.status ===
                                                        "success",
                                                    },
                                                    style: {
                                                      padding: "0 4px",
                                                    },
                                                  },
                                                  file.name
                                                ),
                                              ]),
                                              h("i", {
                                                class: "el-icon-close",
                                                on: {
                                                  ["click"]: () =>
                                                    this.fileRemoveHandler(
                                                      file,
                                                      i.field
                                                    ),
                                                },
                                              }),
                                            ];
                                          },
                                        }
                                        : "",
                                  },
                                  this.optionsRender(h, i)
                                ),
                              ]
                        )
                      );
                    });
                  return dom;
                })()
              ),
            ]
          ),
          h("template", { slot: "footer" }, [
            h(
              "el-button",
              {
                on: {
                  click: () => (this.dialogVisible = false),
                },
              },
              "取 消"
            ),
            h(
              "el-button",
              {
                props: {
                  type: "warning",
                  plain: true,
                },
                on: {
                  click: () => this.init(),
                },
              },
              "重 置"
            ),
            h(
              "el-button",
              {
                props: {
                  type: "primary",
                },
                on: {
                  click: this.submit,
                },
              },
              "确 定"
            ),
          ]),
        ]
      ),
      h("linkPickModal", {
        ref: "linkPickModal",
        props: {
          linkType: this.pickedLinkField.linkType,
          linkTableName: this.pickedLinkField.linkTableName,
          field: this.pickedLinkField.field,
          originalRows: this.pickedLinkField.originalRows,
        },
        on: {
          ["confirm"]: ({ field, value, text }) => {
            this.form[field] = value;
            this.pickModalText[field] = text;
            this.pickModalText = Object.assign({},this.pickModalText)
            console.log(this.pickModalText)
          },
        },
      }),
    ]);
  },
  data() {
    return {
      id: "",
      type: "add",
      dialogVisible: false,
      form: {},
      originalForm: {},
      rules: {},
      file: {},

      pickedLinkField: {
        linkType: "",
        linkTableName: "",
        field: "",
        originalRows: [],
      },
      pickModalText: {}
    };
  },
  methods: {
    fileRemoveHandler(file, field) {
      this.file[field] = this.file[field].filter((item) => item !== file);
      this.file = Object.assign({}, this.file);
    },
    //on事件类别获取
    getEventType(info) {
      if (info === "checkbox") {
        return "change";
      }
      return "input";
    },

    //渲染一些组件内部需要选项等
    optionsRender(h, info) {
      if (info.edit_input === "checkbox" || info.edit_input === "radio") {
        return info._params && info._params instanceof Array
          ? info._params.map((i) =>
            h("el-option", {
              props: {
                label:
                  i.key || i.value || i.name || i.no || i.mingcheng || i.id,
                value: info._relations
                  ? i[info._relations.foreign_key]
                  : i.value,
              },
            })
          )
          : [];
      }
      if (info.edit_input === "file" || info.edit_input === "files") {
        return [
          h(
            "el-button",
            {
              slot: "trigger",
              props: {
                size: "small",
                type: "primary",
              },
            },
            "选取文件"
          ),
          h(
            "el-button",
            {
              style: {
                "margin-left": "10px",
              },
              props: {
                size: "small",
                type: "success",
              },
              on: {
                ["click"]: (e) => {
                  this.$refs[`elEdit_${info.field}`].submit();
                },
              },
            },
            "上传到服务器"
          ),
          h(
            "div",
            {
              class: "el-upload__tip",
              slot: "tip",
            },
            "文件不超过500kb"
          ),
        ];
      }
    },

    extraProps(info) {
      let props = {};
      if (info.edit_input === "file" || info.edit_input === "files") {
        props.fileList = this.file[info.field];
        props.beforeUpload = (file) => {
          if (file.size / 1000 > 500) {
            this.$message({
              type: "warning",
              message: "上传图片大小超过500kb！",
            });
            return false;
          }
        };

        props.onSuccess = (response, file, fileList) => {
          this.file[info.field] = fileList;
        };

        props.onRemove = (file, fileList) => {
          this.file[info.field] = fileList;
        };

        props.onError = (err, file, fileList) => {
          this.file[info.field] = fileList;
          this.$message({
            type: "warning",
            message: err,
          });
        };
      }
      return props;
    },

    init() {
      for (let key in this.form) {
        if (this.form[key] instanceof Array) {
          this.form[key] = [];
        } else {
          this.form[key] = "";
        }
      }
      this.$refs["elForm"].clearValidate();
    },
    show() {
      this.dialogVisible = true;
    },
    hidden() {
      this.dialogVisible = false;
    },
    setType(type = "add") {
      let types = ["add", "editor", "renew"];
      if (types.includes(type)) {
        this.type = type;
      } else {
        console.warn("Unknown type: " + type);
      }
    },
    setId(id) {
      if (typeof id == "number") {
        this.id = id;
      } else {
        console.error("error typeof id: " + typeof id);
      }
    },

    async getDetail() {
      const res = await show({ id: this.id, table_name: this.tableName });
      this.$integrateData(this.form, res);
      this.form = Object.assign({}, this.form);

      this.formInfo.forEach((i) => {
        if (i && (i.edit_input === "file" || i.edit_input === "files")) {
          if (i._relations && i._relations.link_with_name) {
            res[i._relations.link_with_name]
              ? (this.file[i.field] =
                res[i._relations.link_with_name] instanceof Array
                  ? res[i._relations.link_with_name].map((i) => {
                    return {
                      name: i?.original_name,
                      url: i?.url,
                      response: i,
                    };
                  })
                  : [
                    {
                      name: res[i._relations.link_with_name]?.original_name,
                      url: res[i._relations.link_with_name]?.url,
                      response: res[i._relations.link_with_name],
                    },
                  ])
              : (this.file[i.field] =[]);
          } else {
            this.file[i.field] = res[`${i.field}_upload_details`]
          }

          return
        }
        if (i && (i._relations?.link_relation === 'newHasMany' || i._relations?.link_relation === 'hasMany')) {
          this.form[i.field] = res[i._relations.link_with_name].map(j => j[i._relations.custom_form_field])

          this.pickModalText[i.field] = res[i._relations.link_with_name]?.map((j) => j[i._relations.custom_form_field])?.toString()
        }
        if (i && (i._relations?.link_relation === 'newHasOne' || i._relations?.link_relation === 'hasOne')) {
          this.pickModalText[i.field] = (res[
              i._relations.link_with_name
              ]?.name ||
            res[
              i._relations.link_with_name
              ]?.mingcheng ||
            res[
              i._relations.link_with_name
              ]?.no ||
            res[
              i._relations.link_with_name
              ]?.id || res[i.field])
        }
      });

      this.originalForm = deepCopy(res);
    },

    submit() {
      let promiseAll = [];
      if (this.type === "add" || this.type === "renew") {
        if (this.form.hasOwnProperty("id")) {
          delete this.form.id;
        }
      }
      if (this.type === "editor") {
        Object.defineProperty(this.form, "id", {
          value: this.id,
          enumerable: true,
          configurable: true,
          writable: true,
        });
      }
      this.$refs["elForm"].validate((validate) => {
        if (validate) {
          let copyForm = deepCopy(this.form);
          this.formInfo.forEach((info) => {
            if (
              info._relations?.link_relation === "newHasMany" ||
              info._relations?.link_relation === "hasMany"
            ) {
              if (this.originalForm[info._relations.link_with_name]) {
                this.originalForm[info._relations.link_with_name].map((i) => {
                  promiseAll.push(
                    destroy({
                      id: i.id,
                      table_name: info._relations.link_table_name,
                    })
                  );
                });
              }
            }

            // if (copyForm[info._relations?.link_with_name]?.length > 0) {
            //   delete copyForm[info.field];
            // }
            if (
              info._relations?.link_relation === "newHasMany" ||
              info._relations?.link_relation === "hasMany"
            ) {
              copyForm[info._relations.link_with_name] = copyForm[
                info.field
                ] instanceof Array ? copyForm[
                info.field
                ]?.map((i) => {
                return {
                  [info._relations.custom_form_field]: i,
                  //...copyRelation,
                };
              }) : '';

              delete copyForm[info.field];
            }
            if (
              info._relations?.link_relation === "newHasOne" ||
              info._relations?.link_relation === "hasOne"
            ) {
              if (info.edit_input === "file") {
                copyForm[info.field] = this.file[info.field] ? this.file[info.field][0]?.response?.id : '';
              } else {
                // let copyRelation = deepCopy(
                //   info._params.find(
                //     (param) => param.id == this.form[info.field]
                //   )
                // );
                // if (copyRelation) {
                //   delete copyRelation.id;
                //   copyForm[info._relations.link_with_name] = [
                //     {
                //       id: this.form[info._relations?.link_with_name]?.id,
                //       [info.field === "shenhebumen"
                //         ? "dept_id"
                //         : info._relations.foreign_key]: this.form[info.field],
                //       ...copyRelation,
                //     },
                //   ];
                // }
              }

              //delete copyForm[info.field];
            }
            if (!copyForm[info._relations?.link_with_name]) {
              delete copyForm[info._relations?.link_with_name];
            }
            if (info.edit_input === "files") {
              copyForm[info.field] = this.file[
                info.field
                ]?.map((i) => i?.response?.id);
            }
            // if (info._relations?.link_with_name) {
            //   if (info.edit_input === "files" || info.edit_input === "file") {
            //     this.form[info._relations.link_with_name] = this.file[info.field].map(i => i?.response);
            //     delete this.form[info.field]
            //   } else {
            //     this.form[info._relations.link_with_name] = this.form[info.field] instanceof Array ? this.form[info.field].map(i => {
            //       return info._params.find(param => i === param[info._relations.foreign_key])
            //     }) : [info._params.find(param => this.form[info.field] === param[info._relations.foreign_key])]
            //     delete this.form[info.field]
            //   }
            // }
          });

          promiseAll.push(
            save(Object.assign(copyForm, { table_name: this.tableName }))
          );
          Promise.all(promiseAll).then((res) => {
            this.$Message.success({
              content: `${(this.type === "add" || this.type === "renew") ? "新增" : "编辑"}成功`,
            });
            this.$emit("refresh");
            this.hidden();
          });
        }
      });
    },
  },
  computed: {},
  watch: {
    formInfo: {
      handler: function (newVal) {
        this.form = {};
        this.rules = {};
        this.file = {};
        newVal.forEach((i) => {
          if (i.field) {
            this.form[i.field] = "";
            if (
              i.validation instanceof Array &&
              i.validation.length > 0
            ) {
              this.rules[i.field] = []
              i.validation.forEach((j) => {
                if (j === "required") {
                  this.rules[i.field].push({ required: true, message: `请填写${i.name}` })
                } else {
                  this.rules[i.field].push({
                    validator: (rule, value, callback) => {
                      if (value === '') {
                        callback()
                        return
                      }
                      if (validation.get(j).test(value)) {
                        callback()
                      } else {
                        callback(new Error(`${i.name}验证不通过`))
                      }
                    },
                    trigger: 'blur'
                  })
                }
              })
            }
            if (i.edit_input === "files") {
              this.form[i.field] = [];
            }
            if (i.edit_input === "files" || i.edit_input === "file") {
              this.file[i.field] = [];
            }
            if (i.edit_input === "checkbox") {
              this.form[i.field] = [];
            }
          }
        });
      },
      //immediate: true,
    },
    dialogVisible(val) {
      if (val) {
        if (this.type === "editor" || this.type === "renew") {
          this.$nextTick(() => this.getDetail());
        }
      } else {
        this.originalForm = {};
        this.file = {};
        this.id = "";
        this.type = "";
        this.init();
        this.$refs["elForm"].clearValidate();
        delete this.form.id;
      }
    },
  },
};
</script>

<style scoped lang="scss">
:root {
  --column-num: 2;
}
.uploaded-a {
  color: red;
  text-decoration: none;
  transition: all 0.2s;
}

.uploaded-a:hover {
  color: red;
  text-decoration: underline;
}
.form-body {
  padding-right: 20px;
  display: grid;
  grid-row-gap: 10px;
  grid-column-gap: 40px;
  grid-template-columns: repeat(var(--column-num), 1fr);
}
</style>
