import { useEffect, useRef, useState } from "react";
import { DATA_HOOKS } from "../data-hooks.js";
import styles from "./smart-block-editor-scss.js";
const useSmartBlockDrag = (wrapperRef, editor, smartBlockId) => {
  const [dropCursorPosition, setDropCursorPosition] = useState(null);
  const smartBlockIdRef = useRef(smartBlockId);
  smartBlockIdRef.current = smartBlockId;
  useEffect(() => {
    const wrapper = wrapperRef.current;
    if (!wrapper || !editor) {
      return;
    }
    let pendingDragCellId = null;
    let activeDragCellId = null;
    let dragGhost = null;
    const isDraggingSmartBlockCell = (event) => activeDragCellId !== null || event.dataTransfer?.types.includes("application/smart-block-cell") === true;
    const handleMouseDown = (event) => {
      const handle = event.target.closest("[data-smart-block-cell-handle]");
      const cellElement = handle?.closest("[data-smart-block-cell]");
      pendingDragCellId = cellElement?.getAttribute("data-smart-block-cell") ?? null;
    };
    const handleDragStart = (event) => {
      if (!pendingDragCellId || !event.dataTransfer) {
        return;
      }
      const cellElement = [...wrapper.querySelectorAll("[data-smart-block-cell]")].find(
        (cell) => cell.getAttribute("data-smart-block-cell") === pendingDragCellId
      );
      if (!cellElement) {
        return;
      }
      editor.commands.selectSmartBlockCell(pendingDragCellId);
      dragGhost = createDragGhost(cellElement);
      const rect = cellElement.getBoundingClientRect();
      event.dataTransfer.effectAllowed = "move";
      event.dataTransfer.setDragImage(dragGhost, rect.width / 2, 0);
      event.dataTransfer.setData("application/smart-block-cell", pendingDragCellId);
      activeDragCellId = pendingDragCellId;
    };
    const handleDragEnd = () => {
      pendingDragCellId = null;
      activeDragCellId = null;
      if (dragGhost) {
        dragGhost.remove();
        dragGhost = null;
      }
    };
    const handleDragOver = (event) => {
      if (!isDraggingSmartBlockCell(event)) {
        return;
      }
      event.preventDefault();
      const wrapperRect = wrapper.getBoundingClientRect();
      const cells = [...wrapper.querySelectorAll("[data-smart-block-cell]")];
      const point = findInsertionPoint(
        cells,
        wrapperRect,
        event.clientX - wrapperRect.left,
        event.clientY - wrapperRect.top
      );
      if (point) {
        setDropCursorPosition({
          left: point.cursorLeft,
          top: point.cursorTop,
          height: point.cursorHeight
        });
      }
    };
    const handleDrop = (event) => {
      if (!isDraggingSmartBlockCell(event)) {
        return;
      }
      event.stopPropagation();
      event.preventDefault();
      setDropCursorPosition(null);
      const sourceCellId = event.dataTransfer?.getData("application/smart-block-cell") || activeDragCellId;
      if (!sourceCellId) {
        return;
      }
      const wrapperRect = wrapper.getBoundingClientRect();
      const cells = [...wrapper.querySelectorAll("[data-smart-block-cell]")];
      const point = findInsertionPoint(
        cells,
        wrapperRect,
        event.clientX - wrapperRect.left,
        event.clientY - wrapperRect.top
      );
      editor.commands.moveSmartBlockCell(
        sourceCellId,
        point?.insertBeforeCellId ?? null,
        smartBlockIdRef.current
      );
      activeDragCellId = null;
    };
    const handleDragLeave = (event) => {
      if (wrapper.contains(event.relatedTarget)) {
        return;
      }
      setDropCursorPosition(null);
    };
    wrapper.addEventListener("mousedown", handleMouseDown);
    wrapper.addEventListener("dragstart", handleDragStart);
    wrapper.addEventListener("dragend", handleDragEnd);
    wrapper.addEventListener("dragover", handleDragOver);
    wrapper.addEventListener("drop", handleDrop);
    wrapper.addEventListener("dragleave", handleDragLeave);
    return () => {
      wrapper.removeEventListener("mousedown", handleMouseDown);
      wrapper.removeEventListener("dragstart", handleDragStart);
      wrapper.removeEventListener("dragend", handleDragEnd);
      wrapper.removeEventListener("dragover", handleDragOver);
      wrapper.removeEventListener("drop", handleDrop);
      wrapper.removeEventListener("dragleave", handleDragLeave);
      if (dragGhost) {
        dragGhost.remove();
        dragGhost = null;
      }
    };
  }, [editor]);
  return { dropCursorPosition };
};
const buildCellAreas = (cells, wrapperRect) => {
  return cells.map((cell, index) => {
    const rect = cell.getBoundingClientRect();
    const prevCell = index > 0 ? cells[index - 1].getBoundingClientRect() : null;
    const rawLeft = rect.left - wrapperRect.left;
    return {
      left: index === 0 ? rawLeft : rawLeft - (prevCell ? (rawLeft - (prevCell.right - wrapperRect.left)) / 2 : 0),
      right: rect.right - wrapperRect.left,
      width: rect.width,
      top: rect.top - wrapperRect.top,
      bottom: rect.bottom - wrapperRect.top,
      id: cell.getAttribute("data-smart-block-cell"),
      index
    };
  });
};
const findTargetRowCells = (cellAreas, mouseY) => {
  const rowCells = cellAreas.filter((c) => mouseY >= c.top && mouseY < c.bottom);
  if (rowCells.length > 0) {
    return rowCells;
  }
  const rows = [];
  for (const c of cellAreas) {
    const existingRow = rows.find((r) => Math.abs(r[0].top - c.top) < 2);
    if (existingRow) {
      existingRow.push(c);
    } else {
      rows.push([c]);
    }
  }
  let closestRow = rows[0];
  let closestDist = Infinity;
  for (const row of rows) {
    const rowMid = (row[0].top + row[0].bottom) / 2;
    const dist = Math.abs(mouseY - rowMid);
    if (dist < closestDist) {
      closestDist = dist;
      closestRow = row;
    }
  }
  return closestRow;
};
const findInsertionPoint = (cells, wrapperRect, mouseX, mouseY) => {
  if (cells.length === 0) {
    return null;
  }
  const cellAreas = buildCellAreas(cells, wrapperRect);
  const targetCells = findTargetRowCells(cellAreas, mouseY);
  const lastRowCell = targetCells[targetCells.length - 1];
  if (lastRowCell && mouseX >= lastRowCell.right) {
    return {
      insertBeforeCellId: null,
      cursorLeft: lastRowCell.right,
      cursorTop: lastRowCell.top,
      cursorHeight: lastRowCell.bottom - lastRowCell.top
    };
  }
  const matchedCell = targetCells.find((c) => mouseX >= c.left && mouseX < c.right);
  if (!matchedCell) {
    return null;
  }
  const { index } = matchedCell;
  const cell = cellAreas[index];
  const insertBefore = mouseX < cell.left + cell.width / 2;
  const nextCellInRow = !insertBefore && index + 1 < cellAreas.length && Math.abs(cellAreas[index + 1].top - cell.top) < 2;
  const cursorLeft = insertBefore ? cells[index].getBoundingClientRect().left - wrapperRect.left : nextCellInRow ? cells[index + 1].getBoundingClientRect().left - wrapperRect.left : cell.right;
  const insertBeforeCellId = insertBefore ? cell.id : nextCellInRow ? cellAreas[index + 1].id : null;
  return {
    insertBeforeCellId,
    cursorLeft,
    cursorTop: cell.top,
    cursorHeight: cell.bottom - cell.top
  };
};
const createDragGhost = (cellElement) => {
  const rect = cellElement.getBoundingClientRect();
  const ghost = cellElement.cloneNode(true);
  ghost.style.cssText = [
    `width:${rect.width}px`,
    `height:${rect.height}px`,
    "position:fixed",
    "top:-9999px",
    "left:-9999px",
    "opacity:0.85",
    "pointer-events:none",
    "box-sizing:border-box"
  ].join(";");
  ghost.querySelectorAll(
    `[data-smart-block-cell-handle],[data-hook="${DATA_HOOKS.SMART_BLOCK_CELL_ADD_BUTTON}"]`
  ).forEach((el) => {
    const handleWrapper = el.closest(`.${styles.cellHandleWrapper}`);
    (handleWrapper ?? el).remove();
  });
  document.body.appendChild(ghost);
  return ghost;
};
export {
  useSmartBlockDrag
};
//# sourceMappingURL=use-smart-block-drag.js.map
