/**
 * ldesign v0.2.22
 * (c) 2022/12/7 16:21 built by swimly
 * @license MIT
 */

import { h as helper } from '../../../chunks/helper.js';
import { defineComponent, toRefs, ref, computed, watch } from '@vue/composition-api';
import get from 'lodash/get';
import lodashSet from 'lodash/set';
import isFunction from 'lodash/isFunction';
import { Edit1Icon } from '@ldesign/icons-vue';
import '../../../chunks/index.js';
import { useGlobalIcon } from '../../../hooks/useGlobalIcon.js';
import { validate } from '../../form/model.js';
import { renderCell } from './tr.js';
import { l as log } from '../../../chunks/log.js';
import '../../../chunks/_commonjsHelpers.js';
import '../../../chunks/_commonjsHelpers-fe796db6.js';
import '../../../hooks/useConfig.js';
import '../../config-provider/useConfig.js';
import '../../config-provider/context.js';
import 'lodash/merge';
import 'lodash/mergeWith';
import '../../../chunks/zh_CN.js';
import '../../config-provider/type.js';
import 'lodash/isEmpty';
import 'lodash/isNumber';
import '../../../utils/helper.js';
import 'lodash/camelCase';
import 'lodash/upperFirst';
import 'lodash/isString';
import 'lodash/pick';
import '../../../hooks/useLazyLoad.js';
import '../../../chunks/observe.js';
import '../utils.js';
import 'lodash/isObject';
import '../hooks/useFixed.js';
import 'lodash/debounce';
import '../../../chunks/helper2.js';
import '../../../chunks/defineProperty-19da3d4c.js';
import '../../../utils/dom.js';
import 'vue';
import 'raf';
import '../../../utils/easing.js';
import '../hooks/useClassName.js';
import '../props.js';
import '../hooks/useRowspanAndColspan.js';
import './ellipsis.js';
import '../../../utils/render-node.js';
import 'lodash';
import '../../tooltip/index.js';
import '../../../utils/map-props.js';
import '../../../utils/withInstall.js';
import 'lodash/capitalize';
import '../../../config.js';
import '../../tooltip/tooltip.js';
import '../../popup/props.js';
import '../../popup/popup.js';
import '@popperjs/core';
import '../../../chunks/set-style.js';
import '../../config-provider/config-receiver.js';
import '../../../utils/mixins.js';
import '../../popup/container.js';
import '../../tooltip/props.js';
import '../../tooltip/style/css.js';
import '../../tooltip/type.js';

var EditableCell = defineComponent({
  name: "TableEditableCell",
  props: {
    row: Object,
    rowIndex: Number,
    col: Object,
    colIndex: Number,
    oldCell: [Function, String],
    tableBaseClass: Object,
    cellEmptyContent: [Function, String],
    editable: {
      type: Boolean,
      default: void 0
    },
    readonly: {
      type: Boolean
    },
    errors: {
      type: Array,
      default: void 0
    },
    onChange: Function,
    onValidate: Function,
    onRuleChange: Function
  },
  setup(props, context) {
    const {
      row,
      col
    } = toRefs(props);
    const tableEditableCellRef = ref(null);
    const isEdit = ref(props.col.edit?.defaultEditable || false);
    const editValue = ref();
    const errorList = ref();
    const {
      Edit1Icon: Edit1Icon$1
    } = useGlobalIcon({
      Edit1Icon: Edit1Icon
    });
    const currentRow = computed(() => {
      const newRow = {
        ...row.value
      };
      col.value && lodashSet(newRow, col.value.colKey, editValue.value);
      return newRow;
    });
    const cellParams = computed(() => ({
      rowIndex: props.rowIndex,
      colIndex: props.colIndex,
      col: props.col,
      row: props.row
    }));
    const cellNode = computed(() => {
      const node = renderCell({
        row: currentRow.value,
        col: {
          ...col.value,
          cell: props.oldCell
        },
        rowIndex: props.rowIndex,
        colIndex: props.colIndex
      }, context.slots, {
        cellEmptyContent: props.cellEmptyContent
      });
      return node;
    });
    const componentProps = computed(() => {
      const {
        edit
      } = col.value;
      if (!edit) return {};
      const editProps = isFunction(edit.props) ? edit.props({
        ...cellParams.value,
        editedRow: currentRow.value
      }) : {
        ...edit.props
      };
      delete editProps.onChange;
      delete editProps.value;
      edit.abortEditOnEvent?.forEach(item => {
        delete editProps[item];
      });
      return editProps;
    });
    const isAbortEditOnChange = computed(() => {
      const {
        edit
      } = col.value;
      if (!edit) return false;
      return Boolean(edit.abortEditOnEvent?.includes("onChange"));
    });
    const validateEdit = trigger => new Promise(resolve => {
      const params = {
        result: [{
          ...cellParams.value,
          errorList: [],
          value: editValue.value
        }],
        trigger
      };
      const rules = isFunction(col.value.edit.rules) ? col.value.edit.rules(cellParams.value) : col.value.edit.rules;
      if (!col.value.edit || !rules || !rules.length) {
        props.onValidate?.(params);
        resolve(true);
        return;
      }
      validate(editValue.value, rules).then(result => {
        const list = result?.filter(t => !t.result);
        params.result[0].errorList = list;
        props.onValidate?.(params);
        if (!list || !list.length) {
          resolve(true);
        } else {
          errorList.value = list;
          resolve(list);
        }
      });
    });
    const isSame = (a, b) => {
      if (typeof a === "object" && typeof b === "object") return JSON.stringify(a) === JSON.stringify(b);
      return a === b;
    };
    const updateAndSaveAbort = function (outsideAbortEvent) {
      for (var _len = arguments.length, args = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
        args[_key - 1] = arguments[_key];
      }
      validateEdit("self").then(result => {
        if (result !== true) return;
        const oldValue = get(row.value, col.value.colKey);
        if (!isSame(editValue.value, oldValue)) {
          editValue.value = oldValue;
          outsideAbortEvent?.(...args);
        }
        const timer = setTimeout(() => {
          isEdit.value = false;
          errorList.value = [];
          clearTimeout(timer);
        }, 0);
      });
    };
    const listeners = computed(() => {
      const {
        edit
      } = col.value;
      const isCellEditable = props.editable === void 0;
      if (!isEdit.value || !isCellEditable) return;
      if (!edit?.abortEditOnEvent?.length) return {};
      const tListeners = {};
      const outsideAbortEvent = edit?.onEdited;
      edit.abortEditOnEvent.forEach(itemEvent => {
        if (itemEvent === "onChange") return;
        const eventName = itemEvent.slice(2, 3).toLocaleLowerCase() + itemEvent.slice(3);
        tListeners[eventName] = function () {
          for (var _len2 = arguments.length, args = new Array(_len2), _key2 = 0; _key2 < _len2; _key2++) {
            args[_key2] = arguments[_key2];
          }
          updateAndSaveAbort(outsideAbortEvent, {
            ...cellParams.value,
            trigger: itemEvent,
            newRowData: currentRow.value
          }, ...args);
        };
      });
      return tListeners;
    });
    const onEditChange = function (val) {
      editValue.value = val;
      const params = {
        ...cellParams.value,
        value: val,
        editedRow: {
          ...props.row,
          [props.col.colKey]: val
        }
      };
      props.onChange?.(params);
      props.onRuleChange?.(params);
      const isCellEditable = props.editable === void 0;
      if (isCellEditable && isAbortEditOnChange.value) {
        const outsideAbortEvent = col.value.edit?.onEdited;
        for (var _len3 = arguments.length, args = new Array(_len3 > 1 ? _len3 - 1 : 0), _key3 = 1; _key3 < _len3; _key3++) {
          args[_key3 - 1] = arguments[_key3];
        }
        updateAndSaveAbort(outsideAbortEvent, {
          ...cellParams.value,
          trigger: "onChange",
          newRowData: currentRow.value
        }, ...args);
      }
    };
    const documentClickHandler = e => {
      if (!col.value.edit || !col.value.edit.component) return;
      if (!isEdit.value) return;
      if (e.path?.includes(tableEditableCellRef.value?.$el)) return;
      for (let i = 0, len = e.path.length; i < len; i++) {
        const node = e.path[i];
        if (node.classList?.value?.includes("popup__content")) return;
      }
      const outsideAbortEvent = col.value.edit.onEdited;
      updateAndSaveAbort(outsideAbortEvent, {
        ...cellParams.value,
        trigger: "document",
        newRowData: currentRow.value
      });
    };
    const cellValue = computed(() => get(row.value, col.value.colKey));
    watch(cellValue, cellValue2 => {
      let val = cellValue2;
      if (typeof val === "object" && val !== null) val = Array.isArray(val) ? [...val] : {
        ...val
      };
      editValue.value = val;
    }, {
      immediate: true
    });
    watch(isEdit, isEdit2 => {
      const isCellEditable = props.editable === void 0;
      if (!col.value.edit || !col.value.edit.component || !isCellEditable) return;
      if (isEdit2) document.addEventListener("click", documentClickHandler);else document.removeEventListener("click", documentClickHandler);
    }, {
      immediate: true
    });
    watch(() => [props.editable, props.row, props.col, props.rowIndex, props.colIndex], _ref => {
      let [editable] = _ref;
      if (editable === false) {
        editValue.value = cellValue.value;
      } else {
        props.onRuleChange?.({
          ...cellParams.value,
          value: cellValue.value,
          editedRow: row.value
        });
      }
    }, {
      immediate: true
    });
    watch(() => props.errors, errors => {
      errorList.value = errors;
    });
    return {
      editValue,
      isEdit,
      cellNode,
      isAbortEditOnChange,
      listeners,
      componentProps,
      tableEditableCellRef,
      errorList,
      onEditChange,
      Edit1Icon: Edit1Icon$1,
      cellParams
    };
  },
  render() {
    const h = arguments[0];
    if (this.readonly) return h("div", [this.cellNode]);
    if (this.editable === void 0 && !this.isEdit || this.editable === false) {
      const {
        Edit1Icon
      } = this;
      return h("div", {
        "class": this.tableBaseClass?.cellEditable,
        "on": {
          "click": e => {
            this.isEdit = true;
            e.stopPropagation();
          }
        }
      }, [this.cellNode, this.col.edit?.showEditIcon !== false && h(Edit1Icon, {
        "attrs": {
          "size": "12px"
        }
      })]);
    }
    const Component = this.col.edit?.component;
    if (!Component) {
      log.error("Table", "edit.component is required.");
      return null;
    }
    const errorMessage = this.errorList?.[0]?.message;
    return h("div", {
      "class": this.tableBaseClass?.cellEditWrap,
      "on": {
        "click": e => {
          e.stopPropagation();
        }
      }
    }, [h(Component, helper([{
      "ref": "tableEditableCellRef",
      "attrs": {
        "status": errorMessage ? this.errorList?.[0]?.type || "error" : void 0,
        "tips": errorMessage
      }
    }, {
      "props": this.componentProps
    }, {}, {
      "on": this.listeners
    }, {
      "attrs": {
        "value": this.editValue
      },
      "on": {
        "change": this.onEditChange
      }
    }]))]);
  }
});

export { EditableCell as default };
//# sourceMappingURL=editable-cell.js.map
