import { default as Konva } from 'konva';

/**
 * Unique identifier for a tree node.
 */
export type TreeNodeId = string | number;
/**
 * Represents a single item in the action menu for a tree node.
 */
export interface NodeActionMenuItem<T = Record<string, unknown>> {
    /** Unique key for the menu item. */
    readonly key: string;
    /** Text label to display for the menu item. */
    readonly label: string;
    /** Optional Konva shape or ReactNode to display as an icon. */
    readonly icon?: React.ReactNode;
    /** Callback executed when the menu item is clicked. */
    readonly onClick: (node: TreeNodeData<T>) => void;
    /** Optional: Indicates if the menu item should be disabled. */
    readonly disabled?: boolean;
}
/**
 * Defines the structure for a node icon.
 */
export type NodeIconType = 'image' | 'html' | 'konva';
export interface NodeIcon {
    readonly type: NodeIconType;
    readonly content: any;
    readonly width?: number;
    readonly height?: number;
}
/**
 * Represents the data structure for a single node in the tree.
 * @template T - The type of custom data associated with the node.
 */
export interface TreeNodeData<T = Record<string, unknown>> {
    /** Unique ID of the node. */
    readonly id: TreeNodeId;
    /** Label or text to display for the node. */
    readonly label: string;
    /** Child nodes. */
    readonly children?: ReadonlyArray<TreeNodeData<T>>;
    /** Custom data associated with the node. */
    readonly data?: T;
    /** Indicates if this node can load children asynchronously. */
    readonly hasAsyncChildren?: boolean;
    /** Optional: Icon to display for the node. */
    readonly icon?: NodeIcon;
}
/**
 * Props for the main MagicTree component.
 * @template T - The type of custom data associated with each tree node.
 */
export interface MagicTreeProps<T = Record<string, unknown>> {
    /** The array of tree node data to render. */
    readonly data: ReadonlyArray<TreeNodeData<T>>;
    /** Set of IDs for currently expanded nodes. */
    readonly expandedKeys: ReadonlyArray<TreeNodeId>;
    /** Callback function invoked when a node's expanded state is toggled. */
    readonly onExpand: (nodeIdList: ReadonlyArray<TreeNodeId>) => void;
    /** Height of each node in pixels. Essential for virtualization. */
    readonly nodeHeight: number;
    /** Width of the tree container. */
    readonly width?: number;
    /** Height of the tree container. */
    readonly height?: number;
    /**
     * Optional custom render function for a node's content (excluding expand/collapse icon and indentation).
     * If not provided, a default renderer will be used.
     */
    readonly renderNodeContent?: (props: NodeContentRenderProps<T>) => React.ReactNode;
    readonly icon?: (props: FlattenedTreeNode<T>) => React.ReactNode;
    /** Callback function when a node is clicked. */
    readonly onNodeClick?: (node: TreeNodeData<T>, event: Konva.KonvaEventObject<MouseEvent>) => void;
    /** Callback function when a node is hovered. */
    readonly onNodeHover?: (node: TreeNodeData<T> | null, event: Konva.KonvaEventObject<MouseEvent> | null) => void;
    /**
     * Callback function to load children for a node asynchronously.
     * The parent component is responsible for fetching the data and updating the main 'data' prop.
     * The MagicTree component will manage the loading state internally based on this promise.
     */
    readonly onLoadData?: (node: TreeNodeData<T>) => Promise<void>;
    /**
     * Optional function to provide action menu items for a given node.
     * Return an array of MenuItem objects or null/undefined to show no menu.
     */
    readonly renderRowActionMenu?: (node: TreeNodeData<T>) => ReadonlyArray<NodeActionMenuItem<T>> | null | undefined;
    /** Optional: Callback when a drag gesture is initiated on a node. */
    readonly onNodeDragStart?: (event: NodeDragStartEvent<T>) => void;
    /** Optional: Callback when a node is being dragged. */
    readonly onNodeDragMove?: (event: NodeDragMoveEvent<T>) => void;
    /** Optional: Callback when a drag gesture ends for a node. */
    readonly onNodeDragEnd?: (event: NodeDragEndEvent<T>) => void;
    /**
     * Optional configuration for displaying tooltips on node hover.
     * - If `true`, a default tooltip showing the node label will be used.
     * - If a function, it will be called with the node data and should return the tooltip content (string or ReactNode).
     * - If `false` or undefined, no tooltip will be shown.
     */
    readonly showNodeTooltip?: boolean | ((node: TreeNodeData<T>) => React.ReactNode | string);
    readonly iconSize?: number;
}
/** Defines the event payload for onNodeDragStart. */
export interface NodeDragStartEvent<T = Record<string, unknown>> {
    /** The node data being dragged. */
    readonly node: TreeNodeData<T>;
    /** The pointer position relative to the Konva stage at the start of the drag. */
    readonly pointerPosition: {
        readonly x: number;
        readonly y: number;
    };
    /** The raw mouse event that initiated the drag. */
    readonly rawEvent: MouseEvent;
}
/** Defines the event payload for onNodeDragMove. */
export interface NodeDragMoveEvent<T = Record<string, unknown>> {
    /** The node data being dragged. */
    readonly node: TreeNodeData<T>;
    /** The current pointer position relative to the Konva stage. */
    readonly pointerPosition: {
        readonly x: number;
        readonly y: number;
    };
    /** The change in pointer position from the start of the drag. */
    readonly delta: {
        readonly x: number;
        readonly y: number;
    };
    /** The raw mouse event. */
    readonly rawEvent: MouseEvent;
}
/** Defines the event payload for onNodeDragEnd. */
export interface NodeDragEndEvent<T = Record<string, unknown>> {
    /** The node data that was being dragged. */
    readonly node: TreeNodeData<T>;
    /** The raw mouse event that ended the drag. */
    readonly rawEvent: MouseEvent;
}
/**
 * Props passed to the custom `renderNodeContent` function.
 * @template T - The type of custom data associated with the tree node.
 */
export interface NodeContentRenderProps<T = Record<string, unknown>> {
    /** The data for the node being rendered (original TreeNodeData). */
    readonly node: TreeNodeData<T>;
    /** Current depth of the node in the tree (0-indexed). */
    readonly depth: number;
    /** Indicates if the node is currently expanded. */
    readonly isExpanded: boolean;
    /** Indicates if the node has children (either already loaded or loadable). */
    readonly hasChildren: boolean;
    /** Indicates if the node is currently hovered. */
    readonly isHovered: boolean;
    /** Indicates if the node is currently loading children (managed by MagicTree). */
    readonly isLoading: boolean;
    /** Default x offset for the content (after icon and indentation). */
    readonly contentX: number;
    /** Default y offset for the content. */
    readonly contentY: number;
    /** Available width for the content area. */
    readonly contentWidth: number;
    /** Available height for the content area. */
    readonly contentHeight: number;
}
/**
 * Internal representation of a flattened node, used for rendering and virtualization.
 * @template T - The type of custom data associated with the tree node.
 */
export interface FlattenedTreeNode<T = Record<string, unknown>> extends Omit<TreeNodeData<T>, 'isLoading'> {
    /** Depth of the node in the tree (0-indexed). */
    readonly depth: number;
    /** Y position of the node in the virtualized list. */
    readonly y: number;
    /** Original parent ID (if any) */
    readonly parentId?: TreeNodeId;
    /** Indicates if the node is currently expanded (if it has children). This is always defined for a flattened node. */
    readonly isExpanded: boolean;
}
