function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); }
function _toConsumableArray(arr) { return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _unsupportedIterableToArray(arr) || _nonIterableSpread(); }
function _nonIterableSpread() { throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
function _iterableToArray(iter) { if (typeof Symbol !== "undefined" && iter[Symbol.iterator] != null || iter["@@iterator"] != null) return Array.from(iter); }
function _arrayWithoutHoles(arr) { if (Array.isArray(arr)) return _arrayLikeToArray(arr); }
function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
function _defineProperty(obj, key, value) { key = _toPropertyKey(key); if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == _typeof(i) ? i : String(i); }
function _toPrimitive(t, r) { if ("object" != _typeof(t) || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != _typeof(i)) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest(); }
function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }
function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i]; return arr2; }
function _iterableToArrayLimit(r, l) { var t = null == r ? null : "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (null != t) { var e, n, i, u, a = [], f = !0, o = !1; try { if (i = (t = t.call(r)).next, 0 === l) { if (Object(t) !== t) return; f = !1; } else for (; !(f = (e = i.call(t)).done) && (a.push(e.value), a.length !== l); f = !0); } catch (r) { o = !0, n = r; } finally { try { if (!f && null != t.return && (u = t.return(), Object(u) !== u)) return; } finally { if (o) throw n; } } return a; } }
function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }
/**
 * 平面图编辑态：连线选中、拉线、草稿 edges 更新
 */
import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
import { applySourceStub, applyTargetStub, DEFAULT_EDGE_STUB_LENGTH, getAnchorPoint, pathFromPoints, pickAutoAnchor, resolveDrawingTargetAtPoint, routeOrthogonal, simplifyCollinearPath } from "../utils/edgeRouting";
import { useFloorMapEdgeViewModel } from "./useFloorMapEdgeViewModel";
function newEdgeId() {
  return "edge_".concat(Date.now(), "_").concat(Math.random().toString(36).slice(2, 9));
}
export function useFloorMapEdgeEditing(params) {
  var _config$edges, _rectsById$get;
  var enabled = params.enabled,
    config = params.config,
    items = params.items,
    mergedItems = params.mergedItems,
    cellSize = params.cellSize,
    itemUnit = params.itemUnit,
    itemGap = params.itemGap,
    contentOffsetRef = params.contentOffsetRef,
    selectedId = params.selectedId,
    setSelectedId = params.setSelectedId,
    commitDraft = params.commitDraft,
    mapContentRef = params.mapContentRef,
    _params$scale = params.scale,
    scale = _params$scale === void 0 ? 1 : _params$scale;
  var _useState = useState(null),
    _useState2 = _slicedToArray(_useState, 2),
    selectedEdgeId = _useState2[0],
    setSelectedEdgeId = _useState2[1];
  var _useState3 = useState(null),
    _useState4 = _slicedToArray(_useState3, 2),
    drawing = _useState4[0],
    setDrawing = _useState4[1];
  var _useState5 = useState(null),
    _useState6 = _slicedToArray(_useState5, 2),
    ghostEnd = _useState6[0],
    setGhostEnd = _useState6[1];
  /** 拉线时当前悬停的目标图元与吸附端口 */
  var _useState7 = useState(null),
    _useState8 = _slicedToArray(_useState7, 2),
    drawingTarget = _useState8[0],
    setDrawingTarget = _useState8[1];
  var _useState9 = useState({}),
    _useState10 = _slicedToArray(_useState9, 2),
    pendingRectsById = _useState10[0],
    setPendingRectsById = _useState10[1];
  /** 拖动中段手柄时的临时 routing 覆盖（pointerup 后写入 edge.routing） */
  var _useState11 = useState({}),
    _useState12 = _slicedToArray(_useState11, 2),
    pendingRoutingByEdge = _useState12[0],
    setPendingRoutingByEdge = _useState12[1];
  var edges = (_config$edges = config === null || config === void 0 ? void 0 : config.edges) !== null && _config$edges !== void 0 ? _config$edges : [];
  var _useFloorMapEdgeViewM = useFloorMapEdgeViewModel({
      edges: edges,
      items: items,
      cellSize: cellSize,
      itemUnit: itemUnit,
      itemGap: itemGap,
      pendingRectsById: pendingRectsById,
      pendingRoutingByEdge: pendingRoutingByEdge
    }),
    routes = _useFloorMapEdgeViewM.routes,
    rectsById = _useFloorMapEdgeViewM.rectsById;
  var clearEdgeSelection = useCallback(function () {
    setSelectedEdgeId(null);
  }, []);
  var selectEdge = useCallback(function (edgeId) {
    if (drawing) return;
    setSelectedEdgeId(edgeId);
    if (edgeId) setSelectedId(null);
  }, [drawing, setSelectedId]);
  var selectNode = useCallback(function (id) {
    if (drawing) return;
    setSelectedId(id);
    if (id) setSelectedEdgeId(null);
  }, [drawing, setSelectedId]);
  var clientToContent = useCallback(function (clientX, clientY) {
    var el = mapContentRef.current;
    if (!el) return null;
    var rect = el.getBoundingClientRect();
    var off = contentOffsetRef.current;
    return {
      x: (clientX - rect.left) / scale - off.x,
      y: (clientY - rect.top) / scale - off.y
    };
  }, [mapContentRef, contentOffsetRef, scale]);
  var ghostPathD = useMemo(function () {
    var _drawingTarget$anchor;
    if (!drawing || !ghostEnd) return null;
    var srcRect = rectsById.get(drawing.fromInstanceId);
    if (!srcRect) return null;
    var sourcePt = getAnchorPoint(srcRect, drawing.fromAnchor);
    var tgtRect = drawingTarget ? rectsById.get(drawingTarget.instanceId) : null;
    var targetSide = (_drawingTarget$anchor = drawingTarget === null || drawingTarget === void 0 ? void 0 : drawingTarget.anchor) !== null && _drawingTarget$anchor !== void 0 ? _drawingTarget$anchor : 'left';
    var targetPt = tgtRect ? getAnchorPoint(tgtRect, targetSide) : ghostEnd;
    var points = routeOrthogonal(sourcePt, drawing.fromAnchor, targetPt, targetSide, undefined, srcRect && tgtRect ? {
      sourceRect: srcRect,
      targetRect: tgtRect
    } : undefined);
    return pathFromPoints(points);
  }, [drawing, ghostEnd, drawingTarget, rectsById]);
  var drawingTargetPreview = useMemo(function () {
    if (!drawing || !drawingTarget) return null;
    var rect = rectsById.get(drawingTarget.instanceId);
    if (!rect) return null;
    return {
      instanceId: drawingTarget.instanceId,
      rect: rect,
      anchor: drawingTarget.anchor
    };
  }, [drawing, drawingTarget, rectsById]);
  var startDrawingFromAnchor = useCallback(function (instanceId, anchor) {
    setDrawing({
      fromInstanceId: instanceId,
      fromAnchor: anchor
    });
    setDrawingTarget(null);
    setGhostEnd(null);
    setSelectedEdgeId(null);
    setSelectedId(instanceId);
  }, [setSelectedId]);
  var finishDrawing = useCallback(function (clientX, clientY) {
    var _resolved$instanceId;
    if (!drawing || !config) {
      setDrawing(null);
      setGhostEnd(null);
      setDrawingTarget(null);
      return;
    }
    var pt = clientToContent(clientX, clientY);
    if (!pt) {
      setDrawing(null);
      setGhostEnd(null);
      setDrawingTarget(null);
      return;
    }
    var resolved = drawingTarget !== null && drawingTarget !== void 0 ? drawingTarget : resolveDrawingTargetAtPoint(pt, mergedItems.map(function (m) {
      return m.id;
    }), rectsById, drawing.fromInstanceId);
    var targetId = (_resolved$instanceId = resolved === null || resolved === void 0 ? void 0 : resolved.instanceId) !== null && _resolved$instanceId !== void 0 ? _resolved$instanceId : null;
    var targetAnchor = resolved === null || resolved === void 0 ? void 0 : resolved.anchor;
    if (targetId && targetId !== drawing.fromInstanceId) {
      var edge = {
        id: newEdgeId(),
        sourceId: drawing.fromInstanceId,
        targetId: targetId,
        sourceAnchor: drawing.fromAnchor,
        targetAnchor: targetAnchor,
        status: 'online'
      };
      commitDraft(function (prev) {
        var _prev$edges;
        return _objectSpread(_objectSpread({}, prev), {}, {
          edges: [].concat(_toConsumableArray((_prev$edges = prev.edges) !== null && _prev$edges !== void 0 ? _prev$edges : []), [edge])
        });
      });
      setSelectedEdgeId(edge.id);
      setSelectedId(null);
    }
    setDrawing(null);
    setGhostEnd(null);
    setDrawingTarget(null);
  }, [drawing, drawingTarget, config, clientToContent, mergedItems, rectsById, commitDraft, setSelectedId]);
  useEffect(function () {
    if (!drawing) return;
    var onMove = function onMove(ev) {
      var pt = clientToContent(ev.clientX, ev.clientY);
      if (!pt) return;
      var hit = resolveDrawingTargetAtPoint(pt, mergedItems.map(function (m) {
        return m.id;
      }), rectsById, drawing.fromInstanceId);
      setDrawingTarget(hit);
      if (hit) {
        var rect = rectsById.get(hit.instanceId);
        if (rect) {
          setGhostEnd(getAnchorPoint(rect, hit.anchor));
          return;
        }
      }
      setGhostEnd(pt);
    };
    var onUp = function onUp(ev) {
      finishDrawing(ev.clientX, ev.clientY);
    };
    window.addEventListener('pointermove', onMove);
    window.addEventListener('pointerup', onUp);
    return function () {
      window.removeEventListener('pointermove', onMove);
      window.removeEventListener('pointerup', onUp);
    };
  }, [drawing, clientToContent, finishDrawing, mergedItems, rectsById]);
  var updateEdge = useCallback(function (edgeId, patch) {
    commitDraft(function (prev) {
      var _prev$edges2;
      return _objectSpread(_objectSpread({}, prev), {}, {
        edges: ((_prev$edges2 = prev.edges) !== null && _prev$edges2 !== void 0 ? _prev$edges2 : []).map(function (e) {
          return e.id === edgeId ? _objectSpread(_objectSpread({}, e), patch) : e;
        })
      });
    });
  }, [commitDraft]);

  /**
   * 拖动连线段手柄：所有拖动都直接对「path snapshot」做形变。
   * - `role='inner'`：把指定 segmentIndex 的主轴坐标平移到鼠标位置。
   * - `role='first'`：在 snapshot 前面插入一对新点（短 stub + 新被拖动段），
   *   随后拖动改新被拖动段的主轴。即「拖首段 = 新增一个角」，可以无限叠加。
   * - `role='last'`：对称地在末尾追加一对新点。
   * 释放后把「working snapshot」一次性写入 edge.routing.pathSnapshot。
   */
  var draggingSegmentRef = useRef(null);
  var startDraggingSegment = useCallback(function (params) {
    var edge = edges.find(function (e) {
      return e.id === params.edgeId;
    });
    if (!edge) return;
    var currentRoute = routes.find(function (r) {
      return r.edgeId === params.edgeId;
    });
    if (!currentRoute) return;
    /** 始终用「当前 view-model 渲染的 path」（已对齐到最新图元锚点）作为 working 起点。
     *  再做一次共线化简，确保 applySourceStub/Target 不会被冗余共线点干扰
     *  （否则插入 stub 后改 y/x，后续共线点未跟随会出斜段）。 */
    var baseSnapshot = simplifyCollinearPath(currentRoute.points);
    var workingSnapshot = baseSnapshot;
    var targetSegIndex;
    if (params.role === 'first') {
      var _edge$sourceAnchor, _params$segmentLength;
      var srcRect = rectsById.get(edge.sourceId);
      var tgtRect = rectsById.get(edge.targetId);
      var sourceAnchor = (_edge$sourceAnchor = edge.sourceAnchor) !== null && _edge$sourceAnchor !== void 0 ? _edge$sourceAnchor : srcRect && tgtRect ? pickAutoAnchor(srcRect, tgtRect) : 'right';
      var segLen = (_params$segmentLength = params.segmentLength) !== null && _params$segmentLength !== void 0 ? _params$segmentLength : DEFAULT_EDGE_STUB_LENGTH * 2;
      var stubLen = Math.min(DEFAULT_EDGE_STUB_LENGTH, segLen / 2);
      workingSnapshot = applySourceStub(baseSnapshot, stubLen, sourceAnchor);
      /** stub 后被拖动段 = path 的 segment 2（即 snapshot[2]→snapshot[3]） */
      targetSegIndex = 2;
    } else if (params.role === 'last') {
      var _edge$targetAnchor, _params$segmentLength2;
      var _srcRect = rectsById.get(edge.sourceId);
      var _tgtRect = rectsById.get(edge.targetId);
      var targetAnchor = (_edge$targetAnchor = edge.targetAnchor) !== null && _edge$targetAnchor !== void 0 ? _edge$targetAnchor : _srcRect && _tgtRect ? pickAutoAnchor(_tgtRect, _srcRect) : 'left';
      var _segLen = (_params$segmentLength2 = params.segmentLength) !== null && _params$segmentLength2 !== void 0 ? _params$segmentLength2 : DEFAULT_EDGE_STUB_LENGTH * 2;
      var _stubLen = Math.min(DEFAULT_EDGE_STUB_LENGTH, _segLen / 2);
      workingSnapshot = applyTargetStub(baseSnapshot, _stubLen, targetAnchor);
      /** stub 后被拖动段 = path 的 segment (n-3)（即 snapshot[n-4]→snapshot[n-3]） */
      targetSegIndex = workingSnapshot.length - 4;
    } else {
      targetSegIndex = params.segmentIndex;
    }
    draggingSegmentRef.current = {
      edgeId: params.edgeId,
      workingSnapshot: workingSnapshot,
      targetSegIndex: targetSegIndex,
      axis: params.axis,
      startClientX: params.clientX,
      startClientY: params.clientY,
      startPosition: params.startPosition
    };
    setPendingRoutingByEdge(function (prev) {
      return _objectSpread(_objectSpread({}, prev), {}, _defineProperty({}, params.edgeId, {
        pathSnapshot: workingSnapshot
      }));
    });
    setSelectedEdgeId(params.edgeId);
  }, [edges, routes, rectsById]);
  useEffect(function () {
    var onMove = function onMove(ev) {
      var drag = draggingSegmentRef.current;
      if (!drag) return;
      var dx = (ev.clientX - drag.startClientX) / scale;
      var dy = (ev.clientY - drag.startClientY) / scale;
      var delta = drag.axis === 'h' ? dy : dx;
      var nextPos = drag.startPosition + delta;
      var snap = drag.workingSnapshot.map(function (p) {
        return [p[0], p[1]];
      });
      var i = drag.targetSegIndex;
      if (i < 0 || i + 1 >= snap.length) return;
      if (drag.axis === 'h') {
        snap[i] = [snap[i][0], nextPos];
        snap[i + 1] = [snap[i + 1][0], nextPos];
      } else {
        snap[i] = [nextPos, snap[i][1]];
        snap[i + 1] = [nextPos, snap[i + 1][1]];
      }
      setPendingRoutingByEdge(function (prev) {
        return _objectSpread(_objectSpread({}, prev), {}, _defineProperty({}, drag.edgeId, {
          pathSnapshot: snap
        }));
      });
    };
    var onUp = function onUp() {
      var drag = draggingSegmentRef.current;
      draggingSegmentRef.current = null;
      if (!drag) return;
      setPendingRoutingByEdge(function (prev) {
        var next = _objectSpread({}, prev);
        var finalRouting = next[drag.edgeId];
        delete next[drag.edgeId];
        if (finalRouting) {
          updateEdge(drag.edgeId, {
            routing: finalRouting
          });
        }
        return next;
      });
    };
    window.addEventListener('pointermove', onMove);
    window.addEventListener('pointerup', onUp);
    return function () {
      window.removeEventListener('pointermove', onMove);
      window.removeEventListener('pointerup', onUp);
    };
  }, [scale, updateEdge]);
  var deleteEdge = useCallback(function (edgeId) {
    commitDraft(function (prev) {
      var _prev$edges3;
      return _objectSpread(_objectSpread({}, prev), {}, {
        edges: ((_prev$edges3 = prev.edges) !== null && _prev$edges3 !== void 0 ? _prev$edges3 : []).filter(function (e) {
          return e.id !== edgeId;
        })
      });
    });
    setSelectedEdgeId(function (id) {
      return id === edgeId ? null : id;
    });
  }, [commitDraft]);
  var handleEdgeClick = useCallback(function (edgeId) {
    selectEdge(edgeId);
  }, [selectEdge]);
  var handleMapBackgroundClick = useCallback(function () {
    if (drawing) return;
    setSelectedEdgeId(null);
    setSelectedId(null);
  }, [drawing, setSelectedId]);
  useEffect(function () {
    if (!enabled) return;
    var onKey = function onKey(ev) {
      if (ev.key !== 'Delete' && ev.key !== 'Backspace') return;
      if (!selectedEdgeId) return;
      var t = ev.target;
      if (t && (t.tagName === 'INPUT' || t.tagName === 'TEXTAREA' || t.isContentEditable)) {
        return;
      }
      ev.preventDefault();
      deleteEdge(selectedEdgeId);
    };
    window.addEventListener('keydown', onKey);
    return function () {
      return window.removeEventListener('keydown', onKey);
    };
  }, [enabled, selectedEdgeId, deleteEdge]);
  var selectedEdge = useMemo(function () {
    var _edges$find;
    return (_edges$find = edges.find(function (e) {
      return e.id === selectedEdgeId;
    })) !== null && _edges$find !== void 0 ? _edges$find : null;
  }, [edges, selectedEdgeId]);
  var selectedNodeRect = selectedId ? (_rectsById$get = rectsById.get(selectedId)) !== null && _rectsById$get !== void 0 ? _rectsById$get : null : null;
  return {
    edges: edges,
    routes: routes,
    rectsById: rectsById,
    selectedEdgeId: selectedEdgeId,
    selectedEdge: selectedEdge,
    selectedNodeRect: selectedNodeRect,
    drawing: drawing,
    drawingTargetPreview: drawingTargetPreview,
    ghostPathD: ghostPathD,
    selectNode: selectNode,
    selectEdge: selectEdge,
    clearEdgeSelection: clearEdgeSelection,
    startDrawingFromAnchor: startDrawingFromAnchor,
    handleEdgeClick: handleEdgeClick,
    handleMapBackgroundClick: handleMapBackgroundClick,
    updateEdge: updateEdge,
    deleteEdge: deleteEdge,
    setPendingRectsById: setPendingRectsById,
    startDraggingSegment: startDraggingSegment
  };
}