import { GraphMouseEvent } from "../../../../graphEvents";
import { Layer, LayerContext, LayerProps } from "../../../../services/Layer";
import { TCameraState } from "../../../../services/camera/CameraService";
import { TBlockId } from "../../../../store/block/Block";
import { PortState } from "../../../../store/connection/port/Port";
import type { Emitter } from "../../../../utils/Emitter";
import { Point, TPoint } from "../../../../utils/types/shapes";
export type TPortSnapConditionContext = {
    sourcePort: PortState;
    targetPort: PortState;
    cursorPosition: TPoint;
    distance: number;
};
export type TPortSnapCondition = (context: TPortSnapConditionContext) => boolean;
/**
 * Port metadata structure for PortConnectionLayer
 * This structure is stored under PortConnectionLayer.PortMetaKey in port.meta
 */
export interface IPortConnectionMeta {
    /** Enable snapping for this port. If false or undefined, port will not participate in snapping */
    snappable?: boolean;
    /** Custom condition for snapping - validates if connection is allowed */
    snapCondition?: TPortSnapCondition;
}
type TIcon = {
    path: string;
    fill?: string;
    stroke?: string;
    width: number;
    height: number;
    viewWidth: number;
    viewHeight: number;
};
type LineStyle = {
    color: string;
    width?: number;
    dash: number[];
};
type DrawLineFunction = (start: TPoint, end: TPoint) => {
    path: Path2D;
    style: LineStyle;
};
type PortConnectionLayerProps = LayerProps & {
    createIcon?: TIcon;
    point?: TIcon;
    drawLine?: DrawLineFunction;
    searchRadius?: number;
    lineWidth?: number;
    lineDash?: number[];
};
declare module "../../../../graphEvents" {
    interface GraphEventsDefinitions {
        /**
         * Port-based event fired when a user initiates a connection from a port.
         * Extends connection-create-start with direct port reference.
         */
        "port-connection-create-start": (event: CustomEvent<{
            blockId: TBlockId;
            anchorId: string | undefined;
            sourcePort: PortState;
        }>) => void;
        /**
         * Port-based event fired when the connection hovers over a potential target port.
         * Extends connection-create-hover with direct port references.
         */
        "port-connection-create-hover": (event: CustomEvent<{
            sourceBlockId: TBlockId;
            sourceAnchorId: string | undefined;
            targetBlockId: TBlockId | undefined;
            targetAnchorId: string | undefined;
            sourcePort: PortState;
            targetPort?: PortState;
        }>) => void;
        /**
         * Port-based event fired when a connection is successfully created between two ports.
         * Extends connection-created with direct port references.
         */
        "port-connection-created": (event: CustomEvent<{
            sourceBlockId: TBlockId;
            sourceAnchorId?: string;
            targetBlockId: TBlockId;
            targetAnchorId?: string;
            sourcePort: PortState;
            targetPort: PortState;
        }>) => void;
        "port-connection-cancel": (event: CustomEvent<{
            sourcePort: PortState;
            targetPort: PortState;
        }>) => void;
        /**
         * Port-based event fired when the user releases the mouse button.
         * Extends connection-create-drop with direct port references.
         */
        "port-connection-create-drop": (event: CustomEvent<{
            sourceBlockId: TBlockId;
            sourceAnchorId: string;
            targetBlockId?: TBlockId;
            targetAnchorId?: string;
            point: Point;
            sourcePort: PortState;
            targetPort?: PortState;
        }>) => void;
    }
}
/**
 * PortConnectionLayer - new layer for creating connections, working only with ports
 *
 * Key differences from ConnectionLayer:
 * - Works only with ports, (use Block and Anchor components only to pass more info about ports in Event)
 * - Uses findPortAtPoint to detect ports under cursor
 * - Metadata is stored under unique PortConnectionLayer.PortMetaKey key
 * - More efficient search through spatial index
 * - Events extended with sourcePort and targetPort parameters
 *
 * @example
 * ```typescript
 * // Configure port for snapping
 * port.updatePort({
 *   meta: {
 *     [PortConnectionLayer.PortMetaKey]: {
 *       snappable: true,
 *       snapCondition: (ctx) => {
 *         // Custom validation logic
 *         return true;
 *       }
 *     }
 *   }
 * });
 * ```
 */
export declare class PortConnectionLayer extends Layer<PortConnectionLayerProps, LayerContext & {
    canvas: HTMLCanvasElement;
    ctx: CanvasRenderingContext2D;
}> {
    /**
     * Unique key for port metadata
     * Using a symbol prevents conflicts with other layers
     */
    static readonly PortMetaKey: unique symbol;
    private startState;
    private endState;
    private sourcePort?;
    private targetPort?;
    private snappingPortsTree;
    private isSnappingTreeOutdated;
    private portsUnsubscribe?;
    protected enabled: boolean;
    constructor(props: PortConnectionLayerProps);
    protected afterInit(): void;
    protected onCameraChange(_camera: TCameraState): void;
    enable: () => void;
    disable: () => void;
    protected currentListener: Emitter | null;
    private isSnappablePort;
    protected handleMouseDown: (nativeEvent: GraphMouseEvent) => void;
    protected renderEndpoint(ctx: CanvasRenderingContext2D): void;
    protected render(): void;
    private onStartConnection;
    private onMoveNewConnection;
    protected selectPort(port: PortState, select: boolean): void;
    protected cancelNewConnection(): void;
    private onEndNewConnection;
    private findNearestSnappingPort;
    /**
     * Rebuild the RBush spatial index for snapping ports
     * Optimization: Only includes ports from components visible in viewport + padding
     */
    private rebuildSnappingTree;
    /**
     * Determine the port type (IN or OUT)
     * @param port Port to check
     * @returns EAnchorType.IN, EAnchorType.OUT, or null if the port is a block point (no specific direction)
     */
    private getPortType;
    /**
     * Get full event parameters from a port
     * Includes both legacy parameters (blockId, anchorId) and new port reference
     */
    protected getEventParams(port?: PortState): {
        blockId?: TBlockId;
        anchorId?: string;
    };
    unmount(): void;
}
export {};
