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

'use strict';

Object.defineProperty(exports, '__esModule', { value: true });

var helper = require('../../../chunks/helper.js');
var VueCompositionAPI = require('@vue/composition-api');
var get = require('lodash/get');
var lodashSet = require('lodash/set');
var isFunction = require('lodash/isFunction');
var iconsVue = require('@ldesign/icons-vue');
var log = require('../../../chunks/log.js');
var hooks_useGlobalIcon = require('../../../hooks/useGlobalIcon.js');
var components_form_model = require('../../form/model.js');
var components_table_core_tr = require('./tr.js');
require('../../../chunks/_commonjsHelpers-fe796db6.js');
require('../../config-provider/useConfig.js');
require('../../config-provider/context.js');
require('lodash/merge');
require('lodash/mergeWith');
require('../../../chunks/zh_CN.js');
require('../../../chunks/_commonjsHelpers.js');
require('lodash/isEmpty');
require('lodash/isNumber');
require('../../../utils/helper.js');
require('lodash/camelCase');
require('lodash/upperFirst');
require('lodash/isString');
require('lodash/pick');
require('../../../hooks/useLazyLoad.js');
require('../../../chunks/observe.js');
require('../utils.js');
require('lodash/isObject');
require('../hooks/useFixed.js');
require('lodash/debounce');
require('../../../chunks/helper2.js');
require('../../../utils/dom.js');
require('vue');
require('raf');
require('../../../utils/easing.js');
require('../hooks/useClassName.js');
require('../props.js');
require('../hooks/useRowspanAndColspan.js');
require('./ellipsis.js');
require('../../../utils/render-node.js');
require('lodash');
require('../../tooltip/index.js');
require('../../../utils/map-props.js');
require('../../../utils/withInstall.js');
require('lodash/capitalize');
require('../../../config.js');
require('../../tooltip/tooltip.js');
require('../../popup/props.js');
require('../../popup/popup.js');
require('@popperjs/core');
require('../../../chunks/set-style.js');
require('../../config-provider/config-receiver.js');
require('../../../utils/mixins.js');
require('../../popup/container.js');
require('../../tooltip/props.js');

function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }

var get__default = /*#__PURE__*/_interopDefaultLegacy(get);
var lodashSet__default = /*#__PURE__*/_interopDefaultLegacy(lodashSet);
var isFunction__default = /*#__PURE__*/_interopDefaultLegacy(isFunction);

var EditableCell = VueCompositionAPI.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
    } = VueCompositionAPI.toRefs(props);
    const tableEditableCellRef = VueCompositionAPI.ref(null);
    const isEdit = VueCompositionAPI.ref(props.col.edit?.defaultEditable || false);
    const editValue = VueCompositionAPI.ref();
    const errorList = VueCompositionAPI.ref();
    const {
      Edit1Icon
    } = hooks_useGlobalIcon.useGlobalIcon({
      Edit1Icon: iconsVue.Edit1Icon
    });
    const currentRow = VueCompositionAPI.computed(() => {
      const newRow = {
        ...row.value
      };
      col.value && lodashSet__default["default"](newRow, col.value.colKey, editValue.value);
      return newRow;
    });
    const cellParams = VueCompositionAPI.computed(() => ({
      rowIndex: props.rowIndex,
      colIndex: props.colIndex,
      col: props.col,
      row: props.row
    }));
    const cellNode = VueCompositionAPI.computed(() => {
      const node = components_table_core_tr.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 = VueCompositionAPI.computed(() => {
      const {
        edit
      } = col.value;
      if (!edit) return {};
      const editProps = isFunction__default["default"](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 = VueCompositionAPI.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__default["default"](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;
      }
      components_form_model.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__default["default"](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 = VueCompositionAPI.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 = VueCompositionAPI.computed(() => get__default["default"](row.value, col.value.colKey));
    VueCompositionAPI.watch(cellValue, cellValue2 => {
      let val = cellValue2;
      if (typeof val === "object" && val !== null) val = Array.isArray(val) ? [...val] : {
        ...val
      };
      editValue.value = val;
    }, {
      immediate: true
    });
    VueCompositionAPI.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
    });
    VueCompositionAPI.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
    });
    VueCompositionAPI.watch(() => props.errors, errors => {
      errorList.value = errors;
    });
    return {
      editValue,
      isEdit,
      cellNode,
      isAbortEditOnChange,
      listeners,
      componentProps,
      tableEditableCellRef,
      errorList,
      onEditChange,
      Edit1Icon,
      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.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.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
      }
    }]))]);
  }
});

exports["default"] = EditableCell;
//# sourceMappingURL=editable-cell.js.map
