/**
 * ldesign v0.2.14
 * (c) 2022/11/2 16:16 built by swimly
 * @license MIT
 */

import Vue from 'vue';
import cloneDeep from 'lodash/cloneDeep';
import get from 'lodash/get';
import lodashSet from 'lodash/set';
import isNil from 'lodash/isNil';
import { CheckCircleFilledIcon, CloseCircleFilledIcon, ErrorCircleFilledIcon } from '@ldesign/icons-vue';
import lodashTemplate from 'lodash/template';
import '../../chunks/index.js';
import mixins from '../../utils/mixins.js';
import getConfigReceiverMixins, { getGlobalIconMixins } from '../config-provider/config-receiver.js';
import { renderLNodeJSX } from '../../utils/render-node.js';
import { validate } from './model.js';
import { FormItemProps } from './props.js';
import { l as log } from '../../chunks/log.js';
import '../../chunks/_commonjsHelpers-2e6815bd.js';
import 'lodash/mergeWith';
import 'lodash';
import '../config-provider/context.js';
import '../../chunks/zh_CN.js';
import '../config-provider/type.js';
import '../../chunks/_commonjsHelpers.js';
import 'lodash/isEmpty';
import 'lodash/isNumber';
import '../../utils/helper.js';
import 'lodash/camelCase';

var VALIDATE_STATUS = /* @__PURE__ */(VALIDATE_STATUS2 => {
  VALIDATE_STATUS2["TO_BE_VALIDATED"] = "not";
  VALIDATE_STATUS2["SUCCESS"] = "success";
  VALIDATE_STATUS2["FAIL"] = "fail";
  return VALIDATE_STATUS2;
})(VALIDATE_STATUS || {});
var _FormItem = mixins(getConfigReceiverMixins("form"), getGlobalIconMixins()).extend({
  name: "LFormItem",
  props: {
    ...FormItemProps
  },
  inject: {
    form: {
      default: void 0
    }
  },
  provide() {
    return {
      tFormItem: this
    };
  },
  data() {
    return {
      errorList: [],
      successList: [],
      verifyStatus: "not" /* TO_BE_VALIDATED */,
      resetValidating: false,
      needResetField: false,
      initialValue: void 0,
      freeShowErrorMessage: void 0
    };
  },
  computed: {
    needErrorMessage() {
      if (this.freeShowErrorMessage !== void 0) return this.freeShowErrorMessage;
      if (typeof this.showErrorMessage === "boolean") return this.showErrorMessage;
      const parent = this.form;
      return parent === null || parent === void 0 ? void 0 : parent.showErrorMessage;
    },
    classes() {
      return [`${this.componentName}__item`, `${this.componentName}-item__${this.name || ""}`, {
        [`${this.componentName}__item-with-help`]: this.help,
        [`${this.componentName}__item-with-extra`]: this.extraNode
      }];
    },
    extraNode() {
      const h = this.$createElement;
      const list = this.errorList;
      if (this.needErrorMessage && list && list[0] && list[0].message) return h("div", {
        "class": `${this.classPrefix}-input__extra`
      }, [list[0].message]);
      if (this.successList.length) return h("div", {
        "class": `${this.classPrefix}-input__extra`
      }, [this.successList[0].message]);
      return null;
    },
    labelClasses() {
      const parent = this.form;
      const labelAlign = isNil(this.labelAlign) ? parent === null || parent === void 0 ? void 0 : parent.labelAlign : this.labelAlign;
      const labelWidth = isNil(this.labelWidth) ? parent === null || parent === void 0 ? void 0 : parent.labelWidth : this.labelWidth;
      return [`${this.componentName}__label`, {
        [`${this.componentName}__label--required`]: this.needRequiredMark,
        [`${this.componentName}__label--colon`]: this.hasColon,
        [`${this.componentName}__label--top`]: this.getLabelContent() && (labelAlign === "top" || !labelWidth),
        [`${this.componentName}__label--left`]: labelAlign === "left" && labelWidth,
        [`${this.componentName}__label--right`]: labelAlign === "right" && labelWidth
      }];
    },
    errorClasses() {
      if (!this.needErrorMessage) return "";
      if (this.verifyStatus === "success" /* SUCCESS */) {
        return this.successBorder ? [this.commonStatusClassName.success, `${this.componentName}--success-border`].join(" ") : this.commonStatusClassName.success;
      }
      const list = this.errorList;
      if (!list.length) return;
      const type = list[0].type || "error";
      return type === "error" ? this.commonStatusClassName.error : this.commonStatusClassName.warning;
    },
    disabled() {
      return this.form.disabled;
    },
    contentClasses() {
      const getErrorClass = this.errorClasses;
      return [`${this.componentName}__controls`, getErrorClass];
    },
    contentStyle() {
      const parent = this.form;
      const labelAlign = isNil(this.labelAlign) ? parent === null || parent === void 0 ? void 0 : parent.labelAlign : this.labelAlign;
      const labelWidth = isNil(this.labelWidth) ? parent === null || parent === void 0 ? void 0 : parent.labelWidth : this.labelWidth;
      let contentStyle = {};
      if (this.getLabelContent() && labelWidth && labelAlign !== "top") {
        if (typeof labelWidth === "number") contentStyle = {
          marginLeft: `${labelWidth}px`
        };else contentStyle = {
          marginLeft: labelWidth
        };
      }
      return contentStyle;
    },
    value() {
      const parent = this.form;
      return parent && parent.data && get(parent.data, this.name);
    },
    hasColon() {
      const parent = this.form;
      return !!(parent && parent.colon && this.getLabelContent());
    },
    needRequiredMark() {
      const requiredMark = this.$props.requiredMark ?? this.form.requiredMark ?? this.global.requiredMark;
      const isRequired = this.innerRules.filter(rule => rule.required).length > 0;
      return requiredMark || (requiredMark ?? isRequired);
    },
    innerRules() {
      var _this$rules;
      const parent = this.form;
      if ((_this$rules = this.rules) !== null && _this$rules !== void 0 && _this$rules.length) return this.rules || [];
      if (!this.name) return [];
      const index = String(this.name || "").lastIndexOf(".") || -1;
      const pRuleName = String(this.name || "").slice(index + 1);
      return get(parent === null || parent === void 0 ? void 0 : parent.rules, this.name) || get(parent === null || parent === void 0 ? void 0 : parent.rules, pRuleName) || [];
    },
    errorMessages() {
      return this.form.errorMessage ?? this.global.errorMessage;
    }
  },
  watch: {
    value() {
      this.validate("change");
    }
  },
  created() {
    this.addWatch();
  },
  mounted() {
    this.initialValue = cloneDeep(this.value);
    this.form.$emit("form-item-created", this);
  },
  beforeDestroy() {
    this.form.$emit("form-item-destroyed", this);
  },
  methods: {
    addWatch() {
      if (this.disabled === void 0) return;
      this.$watch("disabled", val => {
        this.$nextTick(() => {
          this.setChildrenDisabled(val, this.$children);
        });
      }, {
        immediate: true
      });
    },
    setChildrenDisabled(disabled, children) {
      children.forEach(item => {
        var _this$form$controlled, _item$$children;
        if ((_this$form$controlled = this.form.controlledComponents) !== null && _this$form$controlled !== void 0 && _this$form$controlled.includes(item.$options.name)) item.$data.formDisabled = disabled;
        if ((_item$$children = item.$children) !== null && _item$$children !== void 0 && _item$$children.length) this.setChildrenDisabled(disabled, item.$children);
      });
    },
    setValidateMessage(validateMessage) {
      if (!validateMessage || !Array.isArray(validateMessage)) return;
      if (validateMessage.length === 0) {
        this.errorList = [];
        this.verifyStatus = "success" /* SUCCESS */;
        return;
      }
      this.errorList = validateMessage;
      this.verifyStatus = "fail" /* FAIL */;
    },

    async validate(trigger) {
      let showErrorMessage = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true;
      let source = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : "submit-event";
      this.freeShowErrorMessage = source === "submit-function" ? showErrorMessage : void 0;
      this.resetValidating = true;
      const {
        errorList,
        resultList,
        successList,
        rules,
        allowSetValue
      } = await this.analysisValidateResult(trigger);
      if (allowSetValue) {
        this.errorList = errorList;
        this.successList = successList;
      }
      if (rules.length) this.verifyStatus = errorList.length ? "fail" /* FAIL */ : "success" /* SUCCESS */;else this.verifyStatus = "not" /* TO_BE_VALIDATED */;
      if (this.needResetField) this.resetHandler();
      this.resetValidating = false;
      return {
        [this.name]: errorList.length === 0 ? true : resultList
      };
    },
    async validateOnly(trigger) {
      const {
        errorList,
        resultList
      } = await this.analysisValidateResult(trigger);
      return {
        [this.name]: errorList.length === 0 ? true : resultList
      };
    },
    async analysisValidateResult(trigger) {
      const result = {
        successList: [],
        errorList: [],
        rules: [],
        resultList: [],
        allowSetValue: false
      };
      result.rules = trigger === "all" ? this.innerRules : this.innerRules.filter(item => (item.trigger || "change") === trigger);
      if (this.innerRules.length && !result.rules.length) return result;
      result.allowSetValue = true;
      result.resultList = await validate(this.value, result.rules);
      result.errorList = result.resultList.filter(item => item.result !== true).map(item => {
        Object.keys(item).forEach(key => {
          if (typeof item.message === "undefined" && this.errorMessages[key]) {
            const compiled = lodashTemplate(this.errorMessages[key]);
            const name = typeof this.label === "string" ? this.label : this.name;
            item.message = compiled({
              name,
              validate: item[key]
            });
          }
        });
        return item;
      });
      result.successList = result.resultList.filter(item => item.result === true && item.message && item.type === "success");
      return result;
    },
    getLabelContent() {
      if (typeof this.label === "function") return this.label(this.$createElement);
      if (typeof this.$scopedSlots.label === "function") return this.$scopedSlots.label(null);
      return this.label;
    },
    getLabel() {
      const h = this.$createElement;
      const parent = this.form;
      const labelWidth = isNil(this.labelWidth) ? parent === null || parent === void 0 ? void 0 : parent.labelWidth : this.labelWidth;
      const labelAlign = isNil(this.labelAlign) ? parent === null || parent === void 0 ? void 0 : parent.labelAlign : this.labelAlign;
      if (Number(labelWidth) === 0) return;
      let labelStyle = {};
      if (labelWidth && labelAlign !== "top") {
        if (typeof labelWidth === "number") labelStyle = {
          width: `${labelWidth}px`
        };else labelStyle = {
          width: labelWidth
        };
      }
      return h("div", {
        "class": this.labelClasses,
        "style": labelStyle
      }, [h("label", {
        "attrs": {
          "for": this.for
        }
      }, [this.getLabelContent()])]);
    },
    getDefaultIcon() {
      const h = this.$createElement;
      const resultIcon = Icon => h("span", {
        "class": `${this.componentName}__status`
      }, [h(Icon)]);
      const list = this.errorList;
      const {
        CheckCircleFilledIcon: CheckCircleFilledIcon$1,
        CloseCircleFilledIcon: CloseCircleFilledIcon$1,
        ErrorCircleFilledIcon: ErrorCircleFilledIcon$1
      } = this.useGlobalIcon({
        CheckCircleFilledIcon: CheckCircleFilledIcon,
        CloseCircleFilledIcon: CloseCircleFilledIcon,
        ErrorCircleFilledIcon: ErrorCircleFilledIcon
      });
      if (this.verifyStatus === "success" /* SUCCESS */) return resultIcon(CheckCircleFilledIcon$1);
      if (list && list[0]) {
        const type = list[0].type || "error";
        const icon = {
          error: CloseCircleFilledIcon$1,
          warning: ErrorCircleFilledIcon$1
        }[type] || CheckCircleFilledIcon$1;
        return resultIcon(icon);
      }
      return null;
    },
    getIcon(statusIcon, slotStatusIcon, props2) {
      const h = this.$createElement;
      const resultIcon = otherContent => h("span", {
        "class": `${this.componentName}__status`
      }, [otherContent]);
      if (statusIcon === true) return this.getDefaultIcon();
      if (typeof statusIcon === "function") return resultIcon(statusIcon(this.$createElement, props2));
      if (typeof slotStatusIcon === "function") return resultIcon(slotStatusIcon(null));
      return null;
    },
    getSuffixIcon() {
      const parent = this.form;
      const {
        statusIcon
      } = this;
      const slotStatusIcon = this.$scopedSlots.statusIcon;
      const parentStatusIcon = parent.statusIcon;
      const parentSlotStatusIcon = parent.$scopedSlots.statusIcon;
      if (statusIcon === false) return;
      let resultIcon = this.getIcon(statusIcon, slotStatusIcon);
      if (resultIcon) return resultIcon;
      if (resultIcon === false) return;
      resultIcon = this.getIcon(parentStatusIcon, parentSlotStatusIcon, this.$props);
      if (resultIcon) return resultIcon;
    },
    getEmptyValue() {
      const parent = this.form;
      const type = Object.prototype.toString.call(get(parent.data, this.name));
      let emptyValue;
      if (type === "[object String]") emptyValue = "";
      if (type === "[object Array]") emptyValue = [];
      if (type === "[object Object]") emptyValue = {};
      return emptyValue;
    },
    resetField() {
      let resetType = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : "initial";
      const parent = this.form;
      if (!this.name && this.label) {
        log.warn("Form", "name is required for validating.");
        return;
      }
      const tResetType = resetType || parent.resetType;
      if (tResetType === "empty") lodashSet(parent.data, this.name, this.getEmptyValue());
      if (tResetType === "initial") lodashSet(parent.data, this.name, this.initialValue);
      Vue.nextTick(() => {
        if (this.resetValidating) this.needResetField = true;else this.resetHandler();
      });
    },
    resetHandler() {
      this.needResetField = false;
      this.errorList = [];
      this.successList = [];
      this.verifyStatus = "not" /* TO_BE_VALIDATED */;
    }
  },

  render() {
    const h = arguments[0];
    const helpNode = renderLNodeJSX(this, "help");
    return h("div", {
      "class": this.classes
    }, [this.getLabel(), h("div", {
      "class": this.contentClasses,
      "style": this.contentStyle
    }, [h("div", {
      "class": `${this.componentName}__controls-content`
    }, [this.$slots.default, this.getSuffixIcon()]), helpNode && h("div", {
      "class": `${this.classPrefix}-input__help`
    }, [helpNode]), this.extraNode])]);
  }
});

export { VALIDATE_STATUS, _FormItem as default };
//# sourceMappingURL=form-item.js.map
