import { Node, Edge, NodeMouseHandler } from '@xyflow/react';
import { MouseEvent } from 'react';

/**
 * Graph Component Constants
 *
 * Shared constants for graph layout, dimensions, and behavior
 */
declare const GRAPH_CONSTANTS: {
    readonly NODE_WIDTH: 220;
    readonly NODE_HEIGHT: 140;
    readonly HANDLE_SIZE: 12;
    readonly MIN_ZOOM: 0.2;
    readonly MAX_ZOOM: 1.5;
    readonly RANK_SEP: 140;
    readonly NODE_SEP: 60;
};

/**
 * Resource Type Metadata
 *
 * Centralized metadata for ResourceDefinition types including icon names and colors.
 * Icon names reference @tabler/icons-react - UI layer maps these to actual components.
 */

/**
 * Node color types for graph visualization
 * Used by both @repo/core (metadata) and @repo/ui (components)
 */
type NodeColorType = 'violet' | 'blue' | 'orange' | 'teal' | 'gray' | 'yellow';

/**
 * Graph Component Types
 *
 * Shared type definitions for graph components
 */

type GlowIntensity = 'none' | 'subtle' | 'medium' | 'intense';
interface GraphThemeColors {
    primary: string;
    agent: string;
    workflow: string;
    trigger: string;
    integration: string;
    approval: string;
    primaryGlow: string;
    agentGlow: string;
    workflowGlow: string;
    triggerGlow: string;
    integrationGlow: string;
    approvalGlow: string;
    edgeTriggers: string;
    edgeUses: string;
    edgeApproval: string;
    edgeTriggersGlow: string;
    edgeUsesGlow: string;
    edgeApprovalGlow: string;
}

/**
 * useConnectionHighlight - Hook to track and highlight connected nodes/edges
 *
 * When a node is hovered, highlights all directly connected nodes and edges
 * while dimming unconnected elements for better visual clarity.
 */

interface UseConnectionHighlightReturn {
    hoveredNodeId: string | null;
    highlightedNodeIds: Set<string>;
    highlightedEdgeIds: Set<string>;
    onNodeMouseEnter: (nodeId: string) => void;
    onNodeMouseLeave: () => void;
    getNodeClassName: (nodeId: string) => string;
    getEdgeClassName: (edgeId: string) => string;
}
/**
 * Hook to manage connection highlighting state
 */
declare function useConnectionHighlight(nodes: Node[], edges: Edge[]): UseConnectionHighlightReturn;

/**
 * useGraphHighlighting - Higher-level hook for connection highlighting
 *
 * Wraps useConnectionHighlight and automatically applies CSS classes to nodes/edges
 * based on hover state. Eliminates boilerplate code in graph components.
 *
 * @example
 * ```tsx
 * const { nodes, edges, handleNodeMouseEnter, handleNodeMouseLeave } =
 *   useGraphHighlighting(layoutNodes, layoutEdges)
 *
 * <ReactFlow
 *   nodes={nodes}
 *   edges={edges}
 *   onNodeMouseEnter={handleNodeMouseEnter}
 *   onNodeMouseLeave={handleNodeMouseLeave}
 * />
 * ```
 */

interface GraphHighlightingResult {
    nodes: Node[];
    edges: Edge[];
    handleNodeMouseEnter: NodeMouseHandler;
    handleNodeMouseLeave: NodeMouseHandler;
}
/**
 * Apply connection highlighting to nodes and edges
 *
 * @param layoutNodes - Nodes from layout algorithm (without highlight classes)
 * @param layoutEdges - Edges from layout algorithm (without highlight classes)
 * @returns Nodes/edges with highlight classes and mouse handlers
 */
declare function useGraphHighlighting(layoutNodes: Node[], layoutEdges: Edge[]): GraphHighlightingResult;

/**
 * useDirectedChainHighlighting - Directed chain highlighting for ReactFlow graphs
 *
 * When a node is hovered, highlights all predecessors (upstream) and successors
 * (downstream) following edge direction, while dimming unrelated nodes.
 *
 * Pre-computes directed reachability for O(1) lookup on hover.
 *
 * @example
 * ```tsx
 * const { nodes, edges, handleNodeMouseEnter, handleNodeMouseLeave } =
 *   useDirectedChainHighlighting(layoutNodes, layoutEdges)
 *
 * <ReactFlow
 *   nodes={nodes}
 *   edges={edges}
 *   onNodeMouseEnter={handleNodeMouseEnter}
 *   onNodeMouseLeave={handleNodeMouseLeave}
 * />
 * ```
 */

interface DirectedChainHighlightingOptions {
    /** Optional selected node ID - its chain will always be highlighted */
    selectedNodeId?: string | null;
}
interface DirectedChainHighlightingResult<N extends Node, E extends Edge> {
    nodes: N[];
    edges: E[];
    hoveredNodeId: string | null;
    handleNodeMouseEnter: NodeMouseHandler;
    handleNodeMouseLeave: NodeMouseHandler;
}
/**
 * Apply directed chain highlighting to graph nodes and edges
 *
 * @param layoutNodes - Nodes from layout algorithm
 * @param layoutEdges - Edges from layout algorithm
 * @param options - Optional configuration (selectedNodeId for persistent chain highlight)
 * @returns Nodes/edges with highlight classes and mouse handlers
 */
declare function useDirectedChainHighlighting<N extends Node, E extends Edge>(layoutNodes: N[], layoutEdges: E[], options?: DirectedChainHighlightingOptions): DirectedChainHighlightingResult<N, E>;

/**
 * Generic hook for handling node selection in ReactFlow graphs
 * Supports both string-based and number-based node IDs
 */
declare function useNodeSelection<T extends string | number>(selectedId: T | null, onSelect: (id: T | null) => void): {
    handleNodeClick: (event: MouseEvent, node: Node) => void;
    handlePaneClick: () => void;
    handleContainerClick: (event: MouseEvent) => void;
};

/**
 * Hook to trigger fit view when data or nodes change
 *
 * @param data - Data that triggers fit view when changed (e.g., timelineData, iterationData)
 * @param nodes - ReactFlow nodes array
 * @returns fitViewTrigger - Increment value to pass to GraphFitViewHandler
 */
declare function useFitViewTrigger(data: unknown, nodes: Node[]): number;

/**
 * calculateGraphHeight - Dynamic height calculation for graph containers
 *
 * Calculates container height based on item count with min/max bounds.
 * Useful for graphs that grow with content (workflow steps, knowledge nodes, etc.)
 *
 * @example
 * ```tsx
 * const containerHeight = calculateGraphHeight({
 *   itemCount: workflow.steps.length,
 *   minHeight: 300,
 *   maxHeight: 500,
 *   heightPerItem: 80
 * })
 *
 * <div style={{ height: containerHeight }}>
 *   <ReactFlow ... />
 * </div>
 * ```
 */
interface GraphHeightOptions {
    /**
     * Number of items to calculate height for
     */
    itemCount: number;
    /**
     * Minimum container height in pixels
     * @default 300
     */
    minHeight?: number;
    /**
     * Maximum container height in pixels
     * @default 500
     */
    maxHeight?: number;
    /**
     * Additional height per item in pixels
     * @default 80
     */
    heightPerItem?: number;
}
/**
 * Calculate dynamic container height based on item count
 *
 * Formula: min(minHeight + (itemCount * heightPerItem), maxHeight)
 *
 * @param options - Configuration for height calculation
 * @returns Container height in pixels
 */
declare function calculateGraphHeight({ itemCount, minHeight, maxHeight, heightPerItem }: GraphHeightOptions): number;

export { GRAPH_CONSTANTS, calculateGraphHeight, useConnectionHighlight, useDirectedChainHighlighting, useFitViewTrigger, useGraphHighlighting, useNodeSelection };
export type { DirectedChainHighlightingOptions, DirectedChainHighlightingResult, GlowIntensity, GraphHeightOptions, GraphHighlightingResult, GraphThemeColors, NodeColorType };
