"use strict";
Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toStringTag]: { value: "Module" } });
const types = require("../../../utils/types.js");
const fixedSizeGrid = require("../../virtual-list/src/components/fixed-size-grid.js");
const dynamicSizeGrid = require("../../virtual-list/src/components/dynamic-size-grid.js");
const utils = require("./utils.js");
const tokens = require("./tokens.js");
const grid = require("./grid.js");
const header = require("./components/header.js");
const Vue = require("vue");
const shared_esmBundler = require("../../../../../@vue/shared/dist/shared.esm-bundler.js");
const COMPONENT_NAME = "ElTableV2Grid";
const useTableGrid = (props) => {
  const headerRef = Vue.ref();
  const bodyRef = Vue.ref();
  const scrollLeft = Vue.ref(0);
  const totalHeight = Vue.computed(() => {
    const { data, rowHeight, estimatedRowHeight } = props;
    if (estimatedRowHeight) return;
    return data.length * rowHeight;
  });
  const fixedRowHeight = Vue.computed(() => {
    const { fixedData, rowHeight } = props;
    return ((fixedData == null ? void 0 : fixedData.length) || 0) * rowHeight;
  });
  const headerHeight = Vue.computed(() => utils.sum(props.headerHeight));
  const gridHeight = Vue.computed(() => {
    const { height } = props;
    return Math.max(0, height - Vue.unref(headerHeight) - Vue.unref(fixedRowHeight));
  });
  const hasHeader = Vue.computed(() => {
    return Vue.unref(headerHeight) + Vue.unref(fixedRowHeight) > 0;
  });
  const itemKey = ({ data, rowIndex }) => data[rowIndex][props.rowKey];
  function onItemRendered({ rowCacheStart, rowCacheEnd, rowVisibleStart, rowVisibleEnd }) {
    var _a;
    (_a = props.onRowsRendered) == null ? void 0 : _a.call(props, {
      rowCacheStart,
      rowCacheEnd,
      rowVisibleStart,
      rowVisibleEnd
    });
  }
  function resetAfterRowIndex(index, forceUpdate2) {
    var _a;
    (_a = bodyRef.value) == null ? void 0 : _a.resetAfterRowIndex(index, forceUpdate2);
  }
  function scrollTo(leftOrOptions, top) {
    const header$ = Vue.unref(headerRef);
    const body$ = Vue.unref(bodyRef);
    if (shared_esmBundler.isObject(leftOrOptions)) {
      header$ == null ? void 0 : header$.scrollToLeft(leftOrOptions.scrollLeft);
      scrollLeft.value = leftOrOptions.scrollLeft;
      body$ == null ? void 0 : body$.scrollTo(leftOrOptions);
    } else {
      header$ == null ? void 0 : header$.scrollToLeft(leftOrOptions);
      scrollLeft.value = leftOrOptions;
      body$ == null ? void 0 : body$.scrollTo({
        scrollLeft: leftOrOptions,
        scrollTop: top
      });
    }
  }
  function scrollToTop(scrollTop) {
    var _a;
    (_a = Vue.unref(bodyRef)) == null ? void 0 : _a.scrollTo({ scrollTop });
  }
  function scrollToRow(row, strategy) {
    const body = Vue.unref(bodyRef);
    if (!body) return;
    const prevScrollLeft = scrollLeft.value;
    body.scrollToItem(row, 0, strategy);
    if (prevScrollLeft) scrollTo({ scrollLeft: prevScrollLeft });
  }
  function forceUpdate() {
    var _a, _b;
    (_a = Vue.unref(bodyRef)) == null ? void 0 : _a.$forceUpdate();
    (_b = Vue.unref(headerRef)) == null ? void 0 : _b.$forceUpdate();
  }
  Vue.watch(() => props.bodyWidth, () => {
    var _a;
    if (types.isNumber(props.estimatedRowHeight)) (_a = bodyRef.value) == null ? void 0 : _a.resetAfter({ columnIndex: 0 }, false);
  });
  return {
    bodyRef,
    forceUpdate,
    fixedRowHeight,
    gridHeight,
    hasHeader,
    headerHeight,
    headerRef,
    totalHeight,
    itemKey,
    onItemRendered,
    resetAfterRowIndex,
    scrollTo,
    scrollToTop,
    scrollToRow,
    scrollLeft
  };
};
const TableGrid = /* @__PURE__ */ Vue.defineComponent({
  name: COMPONENT_NAME,
  props: grid.tableV2GridProps,
  setup(props, { slots, expose }) {
    const { ns } = Vue.inject(tokens.TableV2InjectionKey);
    const { bodyRef, fixedRowHeight, gridHeight, hasHeader, headerRef, headerHeight, totalHeight, forceUpdate, itemKey, onItemRendered, resetAfterRowIndex, scrollTo, scrollToTop, scrollToRow, scrollLeft } = useTableGrid(props);
    Vue.provide(tokens.TABLE_V2_GRID_INJECTION_KEY, scrollLeft);
    Vue.onActivated(async () => {
      var _a;
      await Vue.nextTick();
      const scrollTop = (_a = bodyRef.value) == null ? void 0 : _a.states.scrollTop;
      scrollTop && scrollToTop(Math.round(scrollTop) + 1);
    });
    expose({
      forceUpdate,
      totalHeight,
      scrollTo,
      scrollToTop,
      scrollToRow,
      resetAfterRowIndex
    });
    const getColumnWidth = () => props.bodyWidth;
    return () => {
      const { cache, columns, data, fixedData, useIsScrolling, scrollbarAlwaysOn, scrollbarEndGap, scrollbarStartGap, style, rowHeight, bodyWidth, estimatedRowHeight, headerWidth, height, width, getRowHeight, onScroll } = props;
      const isDynamicRowEnabled = types.isNumber(estimatedRowHeight);
      const Grid = isDynamicRowEnabled ? dynamicSizeGrid.default : fixedSizeGrid.default;
      const _headerHeight = Vue.unref(headerHeight);
      return Vue.createVNode("div", {
        "role": "table",
        "class": [ns.e("table"), props.class],
        "style": style
      }, [Vue.createVNode(Grid, {
        "ref": bodyRef,
        "data": data,
        "useIsScrolling": useIsScrolling,
        "itemKey": itemKey,
        "columnCache": 0,
        "columnWidth": isDynamicRowEnabled ? getColumnWidth : bodyWidth,
        "totalColumn": 1,
        "totalRow": data.length,
        "rowCache": cache,
        "rowHeight": isDynamicRowEnabled ? getRowHeight : rowHeight,
        "width": width,
        "height": Vue.unref(gridHeight),
        "class": ns.e("body"),
        "role": "rowgroup",
        "scrollbarStartGap": scrollbarStartGap,
        "scrollbarEndGap": scrollbarEndGap,
        "scrollbarAlwaysOn": scrollbarAlwaysOn,
        "onScroll": onScroll,
        "onItemRendered": onItemRendered,
        "perfMode": false
      }, { default: (params) => {
        var _a;
        const rowData = data[params.rowIndex];
        return (_a = slots.row) == null ? void 0 : _a.call(slots, {
          ...params,
          columns,
          rowData
        });
      } }), Vue.unref(hasHeader) && Vue.createVNode(header.default, {
        "ref": headerRef,
        "class": ns.e("header-wrapper"),
        "columns": columns,
        "headerData": data,
        "headerHeight": props.headerHeight,
        "fixedHeaderData": fixedData,
        "rowWidth": headerWidth,
        "rowHeight": rowHeight,
        "width": width,
        "height": Math.min(_headerHeight + Vue.unref(fixedRowHeight), height)
      }, {
        dynamic: slots.header,
        fixed: slots.row
      })]);
    };
  }
});
exports.default = TableGrid;
