/**
 * Canvas Action Types
 *
 * Action category enum, built-in action IDs, and action definition interfaces.
 *
 * Extracted from settings-types.ts in v1.9.0.
 *
 * @since 1.9.0
 */

import type { UINodeState, UIEdgeState } from './types';
import type { GestureDescriptor } from './gesture-rules';
import type { CanvasEventType } from './event-types';

// =============================================================================
// Action Categories
// =============================================================================

/**
 * Categories for grouping actions in the UI.
 */
export enum ActionCategory {
	/** No action / disabled */
	None = 'none',
	/** Selection-related actions */
	Selection = 'selection',
	/** Viewport/navigation actions */
	Viewport = 'viewport',
	/** Node manipulation actions */
	Node = 'node',
	/** Layout and arrangement actions */
	Layout = 'layout',
	/** History actions (undo/redo) */
	History = 'history',
	/** User-defined custom actions */
	Custom = 'custom',
}

// =============================================================================
// Built-in Action IDs
// =============================================================================

/**
 * IDs for all built-in actions.
 * Using const assertion for type safety while allowing string comparison.
 */
export const BuiltInActionId = {
	// None
	None: 'none',

	// Selection
	SelectNode: 'select-node',
	SelectEdge: 'select-edge',
	AddToSelection: 'add-to-selection',
	ClearSelection: 'clear-selection',
	DeleteSelected: 'delete-selected',

	// Viewport
	FitToView: 'fit-to-view',
	FitAllToView: 'fit-all-to-view',
	CenterOnNode: 'center-on-node',
	ResetViewport: 'reset-viewport',

	// Node
	LockNode: 'lock-node',
	UnlockNode: 'unlock-node',
	ToggleLock: 'toggle-lock',
	OpenContextMenu: 'open-context-menu',
	SplitNode: 'split-node',
	GroupNodes: 'group-nodes',
	MergeNodes: 'merge-nodes',

	// Layout
	ApplyForceLayout: 'apply-force-layout',

	// History
	Undo: 'undo',
	Redo: 'redo',

	// Creation
	CreateNode: 'create-node',
} as const;

export type BuiltInActionIdType = (typeof BuiltInActionId)[keyof typeof BuiltInActionId];

// =============================================================================
// Action Context
// =============================================================================

/**
 * Context passed to action handlers when executing.
 */
export interface ActionContext {
	eventType: CanvasEventType;
	gesture?: GestureDescriptor;
	nodeId?: string;
	nodeData?: UINodeState;
	edgeId?: string;
	edgeData?: UIEdgeState;
	worldPosition: { x: number; y: number };
	screenPosition: { x: number; y: number };
	selectedNodeIds?: string[];
	modifiers: {
		shift: boolean;
		ctrl: boolean;
		alt: boolean;
		meta: boolean;
	};
}

/**
 * Options for creating an ActionContext via the context builder helpers.
 */
export interface ActionContextOptions {
	nodeId?: string;
	nodeData?: UINodeState;
	edgeId?: string;
	edgeData?: UIEdgeState;
}

// =============================================================================
// Action Helpers
// =============================================================================

/**
 * Helper functions provided to action handlers.
 */
export interface ActionHelpers {
	selectNode: (nodeId: string) => void;
	addToSelection: (nodeId: string) => void;
	clearSelection: () => void;
	getSelectedNodeIds: () => string[];
	fitToBounds: (mode: 'graph' | 'selection', padding?: number) => void;
	centerOnNode: (nodeId: string) => void;
	resetViewport: () => void;
	lockNode: (nodeId: string) => void;
	unlockNode: (nodeId: string) => void;
	toggleLock: (nodeId: string) => void;
	deleteNode: (nodeId: string) => Promise<void>;
	isNodeLocked: (nodeId: string) => boolean;
	applyForceLayout: () => Promise<void>;
	undo: () => void;
	redo: () => void;
	canUndo: () => boolean;
	canRedo: () => boolean;
	selectEdge: (edgeId: string) => void;
	clearEdgeSelection: () => void;
	openContextMenu?: (position: { x: number; y: number }, nodeId?: string) => void;
	createNode?: (position: { x: number; y: number }) => Promise<void>;
	splitNode?: (nodeId: string) => Promise<void>;
	groupNodes?: (nodeIds: string[]) => Promise<void>;
	mergeNodes?: (nodeIds: string[]) => Promise<void>;
}

// =============================================================================
// Action Definition
// =============================================================================

/**
 * Full definition of an action that can be triggered by events.
 */
export interface ActionDefinition {
	id: string;
	label: string;
	description: string;
	category: ActionCategory;
	icon?: string;
	requiresNode?: boolean;
	isBuiltIn?: boolean;
	handler: (context: ActionContext, helpers: ActionHelpers) => void | Promise<void>;
}
