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

import { ref, reactive } from '@vue/composition-api';
import isNumber from 'lodash/isNumber';
import { g as getColWidthAttr } from '../../../chunks/utils3.js';
import '../../../chunks/isFunction-91acade7.js';
import '../../../chunks/isObjectLike-c22c7e3b.js';
import '../../../chunks/_commonjsHelpers-2e6815bd.js';
import '../../../chunks/isNumber-c4eb560e.js';

var findAllChildren = col => {
  var loopQue = [];
  var result = [];
  if (col.children) {
    col.children.forEach(child2 => loopQue.push(child2));
    while (loopQue.length) {
      var child = loopQue.shift();
      if (!child.children || !child.children.length) result.push(child);else child.children.forEach(child2 => loopQue.push(child2));
    }
  }
  return result;
};
function setThWidthListByColumnDrag(dragCol, dragWidth, effectCol, options, callback) {
  var {
    getThWidthList,
    DEFAULT_MIN_WIDTH
  } = options;
  var thWidthList = getThWidthList();
  var dragChildrenCols = findAllChildren(dragCol);
  var effectChildrenCols = findAllChildren(effectCol);
  if (dragChildrenCols.length || effectChildrenCols.length) {
    var _effectCol$resize;
    var oldWidth = 0;
    var oldEffectWidth = 0;
    var notCalculateCols = [];
    var effectColsMinWidth = 0;
    var updateMap = {};
    if (!dragChildrenCols.length) dragChildrenCols.push(dragCol);
    if (!effectChildrenCols.length) effectChildrenCols.push(effectCol);
    dragChildrenCols.forEach(child => {
      oldWidth += thWidthList[child.colKey] || getColWidthAttr(child, "width");
      notCalculateCols.push(child.colKey);
    });
    effectChildrenCols.forEach(child => {
      var _child$resize;
      oldEffectWidth += thWidthList[child.colKey] || getColWidthAttr(child, "width");
      notCalculateCols.push(child.colKey);
      effectColsMinWidth += Math.max(((_child$resize = child.resize) === null || _child$resize === void 0 ? void 0 : _child$resize.minWidth) || DEFAULT_MIN_WIDTH, getColWidthAttr(child, "minWidth") || DEFAULT_MIN_WIDTH);
    });
    dragChildrenCols.forEach(child => {
      updateMap[child.colKey] = thWidthList[child.colKey] / oldWidth * dragWidth;
    });
    var remainWidth = Math.max(effectColsMinWidth, oldWidth + oldEffectWidth - dragWidth, Math.max(getColWidthAttr(effectCol, "minWidth") || DEFAULT_MIN_WIDTH, ((_effectCol$resize = effectCol.resize) === null || _effectCol$resize === void 0 ? void 0 : _effectCol$resize.minWidth) || DEFAULT_MIN_WIDTH));
    effectChildrenCols.forEach(child => {
      var _child$resize2;
      updateMap[child.colKey] = Math.max(((_child$resize2 = child.resize) === null || _child$resize2 === void 0 ? void 0 : _child$resize2.minWidth) || DEFAULT_MIN_WIDTH, getColWidthAttr(child, "minWidth") || DEFAULT_MIN_WIDTH, thWidthList[child.colKey] / oldEffectWidth * remainWidth);
    });
    callback(updateMap, notCalculateCols);
  } else {
    var _effectCol$resize2;
    var _oldWidth = thWidthList[dragCol.colKey] || getColWidthAttr(dragCol, "width");
    var _oldEffectWidth = thWidthList[effectCol.colKey] || getColWidthAttr(effectCol, "width");
    callback({
      [dragCol.colKey]: dragWidth,
      [effectCol.colKey]: Math.max(((_effectCol$resize2 = effectCol.resize) === null || _effectCol$resize2 === void 0 ? void 0 : _effectCol$resize2.minWidth) || DEFAULT_MIN_WIDTH, getColWidthAttr(effectCol, "minWidth") || DEFAULT_MIN_WIDTH, _oldWidth + _oldEffectWidth - dragWidth)
    }, [dragCol.colKey, effectCol.colKey]);
  }
}

var setMissingColumnWidth = (columns, missingWidthCols, thWidthList, tableLayout, actualWidth, tableWidth) => {
  var thMap = thWidthList;
  if (actualWidth < tableWidth) {
    var widthDiff = tableWidth - actualWidth;
    var remainCols = [];
    missingWidthCols.forEach(col => {
      var minWidth = getColWidthAttr(col, "minWidth");
      if (minWidth) {
        thMap[col.colKey] = minWidth;
        widthDiff -= minWidth;
      } else {
        remainCols.push(col);
      }
    });
    if (widthDiff > 0) {
      if (remainCols.length) {
        var avgWidth = widthDiff / remainCols.length;
        remainCols.forEach(col => {
          thMap[col.colKey] = avgWidth;
        });
      } else {
        var _avgWidth = widthDiff / missingWidthCols.length;
        missingWidthCols.forEach(col => {
          thMap[col.colKey] += _avgWidth;
        });
      }
    } else {
      remainCols.forEach(col => {
        thMap[col.colKey] = 100;
      });
    }
  } else if (tableLayout === "fixed") {
    missingWidthCols.forEach(col => {
      thMap[col.colKey] = getColWidthAttr(col, "minWidth") || 100;
    });
  } else {
    var extraWidth = 0;
    missingWidthCols.forEach(col => {
      extraWidth += getColWidthAttr(col, "minWidth") || 100;
    });
    var totalWidth = extraWidth + actualWidth;
    columns.forEach(col => {
      if (!thMap[col.colKey]) {
        var colWidth = getColWidthAttr(col, "minWidth") || 100;
        thMap[col.colKey] = colWidth / totalWidth * tableWidth;
      } else {
        thMap[col.colKey] = thMap[col.colKey] / totalWidth * tableWidth;
      }
    });
  }
};
var setNormalColumnWidth = (columns, thWidthList, actualWidth, tableWidth, notCalculateWidthCols) => {
  var thMap = thWidthList;
  columns.forEach(col => {
    if (notCalculateWidthCols.includes(col.colKey)) return;
    thMap[col.colKey] = thMap[col.colKey] / actualWidth * tableWidth;
  });
};
var setInitialColumnWidth = (missingWidthCols, thWidthList) => {
  var thMap = thWidthList;
  missingWidthCols.forEach(col => {
    thMap[col.colKey] = getColWidthAttr(col, "minWidth") || 100;
  });
};
function recalculateColumnWidth(columns, thWidthList, tableLayout, tableElmWidth, notCalculateWidthCols, callback) {
  var actualWidth = 0;
  var missingWidthCols = [];
  var thMap = {};
  columns.forEach(col => {
    if (!thWidthList[col.colKey]) thMap[col.colKey] = getColWidthAttr(col, "width");else thMap[col.colKey] = thWidthList[col.colKey];
    var originWidth = thMap[col.colKey];
    if (originWidth) actualWidth += originWidth;else missingWidthCols.push(col);
  });
  var tableWidth = tableElmWidth;
  var needUpdate = false;
  if (tableWidth > 0) {
    if (missingWidthCols.length) {
      setMissingColumnWidth(columns, missingWidthCols, thMap, tableLayout, actualWidth, tableWidth);
      needUpdate = true;
    } else {
      if (notCalculateWidthCols.length) {
        var sum = 0;
        notCalculateWidthCols.forEach(colKey => {
          sum += thMap[colKey];
        });
        actualWidth -= sum;
        tableWidth -= sum;
      }
      if (actualWidth !== tableWidth || notCalculateWidthCols.length) {
        setNormalColumnWidth(columns, thMap, actualWidth, tableWidth, notCalculateWidthCols);
        needUpdate = true;
      }
    }
  } else {
    setInitialColumnWidth(missingWidthCols, thMap);
    needUpdate = true;
  }
  if (needUpdate) {
    var addon = 0;
    Object.keys(thMap).forEach(key => {
      var width = thMap[key];
      addon += width - Math.floor(width);
      thMap[key] = Math.floor(width) + (addon > 1 ? 1 : 0);
      if (addon > 1) addon -= 1;
    });
    if (addon > 0.5) thMap[columns[0].colKey] += 1;
  }
  callback(thMap);
}

const DEFAULT_MIN_WIDTH = 80;
const DEFAULT_MAX_WIDTH = 600;
function useColumnResize(tableContentRef, refreshTable, getThWidthList, updateThWidthList) {
  const resizeLineRef = ref();
  const notCalculateWidthCols = ref([]);
  const effectColMap = ref({});
  const setEffectColMap = (nodes, parent) => {
    if (!nodes) return;
    nodes.forEach((n, index) => {
      const parentPrevCol = parent ? effectColMap.value[parent.colKey].prev : nodes[index + 1];
      const parentNextCol = parent ? effectColMap.value[parent.colKey].next : nodes[index - 1];
      const prev = index === 0 ? parentPrevCol : nodes[index - 1];
      const next = index === nodes.length - 1 ? parentNextCol : nodes[index + 1];
      effectColMap.value[n.colKey] = {
        prev,
        next
      };
      setEffectColMap(n.children, n);
    });
  };
  const resizeLineParams = {
    isDragging: false,
    draggingCol: null,
    draggingStart: 0,
    effectCol: null
  };
  const resizeLineStyle = reactive({
    display: "none",
    height: "10px",
    left: "10px",
    bottom: "0"
  });
  const setNotCalculateWidthCols = colKeys => {
    notCalculateWidthCols.value = colKeys;
  };
  const onColumnMouseover = (e, col) => {
    if (!resizeLineRef.value) return;
    const target = e.target.closest("th");
    const targetBoundRect = target.getBoundingClientRect();
    if (!resizeLineParams.isDragging) {
      const distance = 8;
      if (targetBoundRect.right - e.pageX <= distance) {
        const colResizable = col.resizable ?? true;
        if (colResizable) {
          target.style.cursor = "col-resize";
          resizeLineParams.draggingCol = target;
          resizeLineParams.effectCol = "next";
          return;
        }
      } else if (e.pageX - targetBoundRect.left <= distance) {
        const prevEl = target.previousElementSibling;
        if (prevEl) {
          const effectPrevCol = effectColMap.value[col.colKey].prev;
          const colResizable = effectPrevCol.resizable ?? true;
          if (colResizable) {
            target.style.cursor = "col-resize";
            resizeLineParams.draggingCol = prevEl;
            resizeLineParams.effectCol = "prev";
            return;
          }
        }
      }
      target.style.cursor = "";
      resizeLineParams.draggingCol = null;
      resizeLineParams.effectCol = null;
    }
  };
  const onColumnMousedown = (e, col) => {
    var _tableContentRef$valu;
    if (!resizeLineParams.draggingCol) return;
    const getMinMaxColWidth = (col2, effectPrevCol2) => {
      var _targetCol$resize, _targetCol$resize2;
      let targetCol = null;
      if (resizeLineParams.effectCol === "next") targetCol = col2;else targetCol = effectPrevCol2;
      const propMinWidth = isNumber(targetCol.minWidth) ? targetCol.minWidth : parseFloat(targetCol.minWidth);
      return {
        minColWidth: Math.max(((_targetCol$resize = targetCol.resize) === null || _targetCol$resize === void 0 ? void 0 : _targetCol$resize.minWidth) || DEFAULT_MIN_WIDTH, propMinWidth || DEFAULT_MIN_WIDTH),
        maxColWidth: ((_targetCol$resize2 = targetCol.resize) === null || _targetCol$resize2 === void 0 ? void 0 : _targetCol$resize2.maxWidth) || DEFAULT_MAX_WIDTH
      };
    };
    const target = resizeLineParams.draggingCol;
    const targetBoundRect = target.getBoundingClientRect();
    const tableBoundRect = (_tableContentRef$valu = tableContentRef.value) === null || _tableContentRef$valu === void 0 ? void 0 : _tableContentRef$valu.getBoundingClientRect();
    const resizeLinePos = targetBoundRect.right - tableBoundRect.left;
    const colLeft = targetBoundRect.left - tableBoundRect.left;
    const effectNextCol = effectColMap.value[col.colKey].next;
    const effectPrevCol = effectColMap.value[col.colKey].prev;
    const {
      minColWidth,
      maxColWidth
    } = getMinMaxColWidth(col, effectPrevCol);
    const minResizeLineLeft = colLeft + minColWidth;
    const maxResizeLineLeft = colLeft + maxColWidth;
    resizeLineParams.isDragging = true;
    resizeLineParams.draggingStart = e.x;
    if (resizeLineRef !== null && resizeLineRef !== void 0 && resizeLineRef.value) {
      resizeLineStyle.display = "block";
      resizeLineStyle.height = `${tableBoundRect.bottom - targetBoundRect.top}px`;
      resizeLineStyle.left = `${resizeLinePos}px`;
      const parent = tableContentRef.value.parentElement.getBoundingClientRect();
      resizeLineStyle.bottom = `${parent.bottom - tableBoundRect.bottom}px`;
    }
    const onDragEnd = () => {
      if (resizeLineParams.isDragging) {
        let width = Math.ceil(parseInt(resizeLineStyle.left, 10) - colLeft) || 0;
        if (width <= minColWidth) width = minColWidth;else if (width >= maxColWidth) width = maxColWidth;
        if (resizeLineParams.effectCol === "next") {
          setThWidthListByColumnDrag(col, width, effectNextCol, {
            getThWidthList,
            DEFAULT_MIN_WIDTH
          }, (updateMap, notCalculateCols) => {
            updateThWidthList(updateMap);
            setNotCalculateWidthCols(notCalculateCols);
          });
        } else if (resizeLineParams.effectCol === "prev") {
          setThWidthListByColumnDrag(effectPrevCol, width, col, {
            getThWidthList,
            DEFAULT_MIN_WIDTH
          }, (updateMap, notCalculateCols) => {
            updateThWidthList(updateMap);
            setNotCalculateWidthCols(notCalculateCols);
          });
        }
        resizeLineParams.isDragging = false;
        resizeLineParams.draggingCol = null;
        resizeLineParams.effectCol = null;
        target.style.cursor = "";
        resizeLineStyle.display = "none";
        resizeLineStyle.left = "0";
        document.removeEventListener("mousemove", onDragOver);
        document.removeEventListener("mouseup", onDragEnd);
        document.onselectstart = null;
        document.ondragstart = null;
      }
      refreshTable();
    };
    const onDragOver = e2 => {
      if (resizeLineParams.isDragging) {
        const left = resizeLinePos + e2.x - resizeLineParams.draggingStart;
        resizeLineStyle.left = `${Math.min(Math.max(left, minResizeLineLeft), maxResizeLineLeft)}px`;
      }
    };
    document.addEventListener("mouseup", onDragEnd);
    document.addEventListener("mousemove", onDragOver);
    document.onselectstart = () => false;
    document.ondragstart = () => false;
  };
  const recalculateColWidth = (columns, thWidthList, tableLayout, tableElmWidth) => {
    recalculateColumnWidth(columns, thWidthList, tableLayout, tableElmWidth, notCalculateWidthCols.value, widthMap => {
      updateThWidthList(widthMap);
      if (notCalculateWidthCols.value.length) notCalculateWidthCols.value = [];
    });
  };
  return {
    resizeLineRef,
    resizeLineStyle,
    onColumnMouseover,
    onColumnMousedown,
    recalculateColWidth,
    setEffectColMap
  };
}

export { useColumnResize as default };
//# sourceMappingURL=useColumnResize.js.map
