import type { MutableRefObject } from 'react';
import type { FloorMapItemBase, FloorMapItemUnit, FloorMapZoomConfig } from '../types';
import type { PlacementBoundingBox } from '../utils/batchScenePlacementLayout';
/** react-zoom-pan-pinch TransformWrapper render 注入的上下文 */
export declare type FloorMapTransformContext = {
    zoomIn: () => void;
    zoomOut: () => void;
    resetTransform: () => void;
    /**
     * react-zoom-pan-pinch v3 实际签名：(x, y, scale, animationTime?, animationType?)
     * 默认 animationTime≈200ms；传 0 立即落点，避免被前一次动画吃掉或与之冲突
     * （restore / 缓存恢复路径应使用 0 立即覆盖已在缓动中的 fit 动画）。
     * 这里只暴露我们用到的前 4 参；库 animationType 是 `keyof typeof animations` 联合，
     * 暴露过来反而限制传入对象的兼容性，我们也确实不传它。
     */
    setTransform: (x: number, y: number, scale: number, animationTime?: number) => void;
} | null;
export interface UseFloorMapTransformMetricsParams<T extends FloorMapItemBase> {
    items: T[];
    cellSize: number;
    itemGap: number;
    effectiveItemUnit: FloorMapItemUnit;
    isFloorMapView: boolean;
    mode: 'read' | 'edit';
    zoom: FloorMapZoomConfig;
    transformRef: MutableRefObject<FloorMapTransformContext>;
    /** 由父组件创建并传入 useFloorMapEditState，本 hook 每帧写入内容区偏移 */
    contentOffsetRef: MutableRefObject<{
        x: number;
        y: number;
    }>;
    /** 与 mapLayer.boundingPadding 一致；未传用 DEFAULT_BOUNDING_PADDING */
    boundingPadding?: number;
    /**
     * 平面图：当前画布 id（或其它在切换画布时应重置平移/对齐会话的 key）。
     * 不传则不跑「异步加载图元后的首次左上对齐」逻辑。
     */
    frameResetKey?: string;
    /**
     * 视口持久化标识（通常拼自 canvasId）。传入后：
     *   - 切换 / 挂载时若 localStorage 中有缓存，自动恢复 transform 并跳过本帧 autoFit；
     *   - 用户拖动 / 缩放时（节流 300ms）写回缓存；
     *   - 主动 fitBounds / 进入伪全屏后由 fitBounds 触发的写入也会同步保存。
     * 不传则完全不读不写 localStorage。
     */
    viewportPersistKey?: string;
}
export declare function useFloorMapTransformMetrics<T extends FloorMapItemBase>(params: UseFloorMapTransformMetricsParams<T>): {
    containerRef: import("react").RefObject<HTMLDivElement>;
    mapAreaRef: import("react").RefObject<HTMLDivElement>;
    viewportSize: {
        width: number;
        height: number;
    };
    mapAreaSize: {
        width: number;
        height: number;
    };
    contentWidth: number;
    contentHeight: number;
    contentOffsetX: number;
    contentOffsetY: number;
    initialPositionX: number;
    initialPositionY: number;
    zoomConfig: {
        initialScale: number;
        minScale: number;
        maxScale: number;
        step: number;
    };
    scale: number;
    setScale: import("react").Dispatch<import("react").SetStateAction<number>>;
    isFullscreen: boolean;
    toggleFullscreen: () => void;
    fitBounds: () => boolean;
    focusContentBounds: (bounds: PlacementBoundingBox | null) => boolean;
    isAtFitBounds: boolean;
    notifyTransformed: (x: number, y: number, nextScale: number) => void;
    persistCurrentViewport: () => void;
    attachTransformContext: (ctx: NonNullable<FloorMapTransformContext>) => void;
    lastTransformRef: MutableRefObject<{
        x: number;
        y: number;
        scale: number;
    }>;
    isInteractingWithElement: boolean;
    setIsInteractingWithElement: import("react").Dispatch<import("react").SetStateAction<boolean>>;
    viewportLocked: boolean;
    setViewportLocked: (next: boolean) => void;
    toggleViewportLocked: () => void;
};
