import { domMap } from "@/const/inputType";
import { addPropsMap } from "@/const/addProps";

export class CreateDialog {
  replaces;
  self;
  $createElement;
  options;
  constructor(self, replaces = [], options) {
    /*
      replace = [
        {
          key: '',
          label: '',
          render: () => {}
        }
      ]
     */
    this.self = self;
    this.$createElement = self.$createElement;
    this.replaces = replaces;
    this.options = options;
  }
  getEventType(info) {
    if (info === "checkbox") {
      return "change";
    }
    return "input";
  }
  fileRemoveHandler(file, field) {
    let that = this.self;
    that.file[field] = that.file[field].filter((item) => item !== file);
    that.file = Object.assign({}, that.file);
  }
  extraProps(info) {
    let that = this.self;
    let props = {};
    if (info.edit_input === "file" || info.edit_input === "files") {
      props.fileList = that.file[info.field];
      props.beforeUpload = (file) => {
        if (file.size / 1000 > 500) {
          that.$message({
            type: "warning",
            message: "上传图片大小超过500kb！",
          });
          return false;
        }
      };

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

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

      props.onError = (err, file, fileList) => {
        that.file[info.field] = fileList;
        that.$message({
          type: "warning",
          message: err,
        });
      };
    }
    return props;
  }
  optionsRender(h, info) {
    let that = this.self;
    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.name ||
                  i.mingcheng ||
                  i.label ||
                  i.key ||
                  i.value ||
                  i.id ||
                  i.no,
                value: i.id || 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) => {
                that.$refs[`elEdit_${info.field}`].submit();
              },
            },
          },
          "上传到服务器"
        ),
        h(
          "div",
          {
            class: "el-upload__tip",
            slot: "tip",
          },
          "文件不超过500kb"
        ),
      ];
    }
  }
  render() {
    let that = this.self;
    const h = this.$createElement;

    return h(
      "el-dialog",
      {
        class: "dialog",
        ref: "dialog",
        props: {
          top: "8vh",
          title: that.title
            ? that.title
            : that.type === "add"
            ? "新增"
            : "编辑",
          visible: that.dialogVisible,
          width: this.options?.width ? this.options.width : "800px",
          "append-to-body": true
        },
        on: {
          "update:visible": (val) => {
            that.dialogVisible = val;
          },
        },
      },
      [
        h(
          "el-scrollbar",
          {
            style: {
              height: "58vh",
            },
          },
          [
            h(
              "el-form",
              {
                class: "form-body",
                ref: "elForm",
                style: {
                  "padding-right": "12px",
                },
                props: {
                  model: that.form,
                  labelWidth: "80px",
                  rules: that.rules,
                  labelPosition: "right",
                  size: "small",
                },
              },
              (() => {
                let dom = [];
                (this.options?.formInfo ? this.options.formInfo : that.formInfo)
                  .filter((i) => i.form_show)
                  .forEach((i, index) => {
                    let replace = this.replaces.find((j) => j.key === i.field);

                    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,
                          },
                        },
                        replace && replace.render
                          ? [replace.render]
                          : [
                            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: that.form[i.field],
                                  readonly: that.type === "show",
                                  //disabled: that.type === 'show',
                                },
                                attrs: {
                                  placeholder: i.help || `请填写${i.name}`,
                                },
                                on: {
                                  [this.getEventType(i.edit_input)]: (
                                    e
                                  ) => {
                                    if (i.field) {
                                      that.form[i.field] = e;
                                      that.form = Object.assign(
                                        {},
                                        that.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)
                            ),
                          ]
                      )
                    );
                  });

                this.replaces.forEach((replace) => {
                  let info = that.formInfo.find((i) => i.field === replace.key);
                  if (!info) {
                    if (replace.label) {
                      dom.push(
                        h(
                          "el-form-item",
                          {
                            ref: `elFormItem${replace.key}`,
                            style: {
                              width: "100%",
                              ...replace.rowStyle,
                            },
                            props: {
                              label: replace.label,
                              prop: replace.key,
                            },
                          },
                          [replace.render]
                        )
                      );
                    } else {
                      dom.push(replace.render);
                    }
                  }
                });
                return dom;
              })()
            ),
          ]
        ),
        h("template", { slot: "footer" }, [
          h(
            "el-button",
            {
              props: {
                size: "mini",
              },
              on: {
                click: () => (that.dialogVisible = false),
              },
            },
            "取 消"
          ),
          h(
            "el-button",
            {
              props: {
                type: "warning",
                plain: true,
                size: "mini",
              },
              on: {
                click: () => that.init(),
              },
            },
            "重 置"
          ),
          h(
            "el-button",
            {
              props: {
                type: "primary",
                size: "mini",
              },
              on: {
                click: that.submit,
              },
            },
            "确 定"
          ),
        ]),
      ]
    );
  }
}
