/**
 * Interaction Store
 *
 * Manages canvas interaction modes (picking nodes, points, etc.)
 * and visual feedback during interactions.
 */

import { atom } from 'jotai';
import type { UINodeState, NodePosition } from './types';

// =============================================================================
// Input Mode Types
// =============================================================================

/**
 * A selectable option for 'select' type inputs.
 */
export type SelectOption = {
	/** Display label for the option */
	label: string;
	/** Value to use when selected */
	value: string;
	/** Single key shortcut (e.g., 'w' for widget) */
	shortcut: string;
	/** Optional description shown on hover */
	description?: string;
};

/**
 * Input mode - controls how canvas interactions are routed.
 * When not 'normal', canvas clicks are intercepted for special handling.
 */
export type InputMode =
	| { type: 'normal' }
	| { type: 'pickPoint'; prompt: string; snapToGrid?: boolean }
	| { type: 'pickNode'; prompt: string; filter?: (node: UINodeState) => boolean }
	| { type: 'pickNodes'; prompt: string; filter?: (node: UINodeState) => boolean }
	| { type: 'text'; prompt: string }
	| { type: 'select'; prompt: string; options: SelectOption[] };

export type KeyboardInteractionMode = 'navigate' | 'manipulate';

// =============================================================================
// Feedback Types
// =============================================================================

export type Point = { x: number; y: number };

/**
 * Visual feedback state for the canvas overlay.
 */
export type FeedbackState = {
	/** Node ID being hovered during pick mode */
	hoveredNodeId?: string;
	/** Current cursor position in world coordinates */
	cursorWorldPos?: Point;
	/** Preview edge to draw during edge creation */
	previewEdge?: { from: Point; to: Point };
	/** Ghost node following cursor (for node creation) */
	ghostNode?: { position: Point; opacity: number };
	/** Show crosshair at cursor position */
	crosshair?: boolean;
} | null;

// =============================================================================
// Input Mode Atoms
// =============================================================================

/**
 * Current input mode - controls how canvas interactions are routed.
 */
export const inputModeAtom = atom<InputMode>({ type: 'normal' });

/**
 * Keyboard interaction mode for arrow/space/enter behavior.
 */
export const keyboardInteractionModeAtom = atom<KeyboardInteractionMode>('navigate');

/**
 * Visual feedback state for overlays during interaction.
 */
export const interactionFeedbackAtom = atom<FeedbackState>(null);

/**
 * Resolver for pending input values (used by command systems).
 */
export const pendingInputResolverAtom = atom<unknown | null>(null);

// =============================================================================
// Action Atoms
// =============================================================================

/**
 * Reset input mode to normal.
 */
export const resetInputModeAtom = atom(null, (_get, set) => {
	set(inputModeAtom, { type: 'normal' });
	set(interactionFeedbackAtom, null);
	set(pendingInputResolverAtom, null);
});

/**
 * Reset keyboard interaction mode back to navigation.
 */
export const resetKeyboardInteractionModeAtom = atom(null, (_get, set) => {
	set(keyboardInteractionModeAtom, 'navigate');
});

/**
 * Set keyboard interaction mode explicitly.
 */
export const setKeyboardInteractionModeAtom = atom(
	null,
	(_get, set, mode: KeyboardInteractionMode) => {
		set(keyboardInteractionModeAtom, mode);
	},
);

/**
 * Set input mode for picking a node.
 */
export const startPickNodeAtom = atom(
	null,
	(_get, set, options: { prompt: string; filter?: (node: UINodeState) => boolean }) => {
		set(inputModeAtom, { type: 'pickNode', ...options });
	},
);

/**
 * Set input mode for picking multiple nodes.
 */
export const startPickNodesAtom = atom(
	null,
	(_get, set, options: { prompt: string; filter?: (node: UINodeState) => boolean }) => {
		set(inputModeAtom, { type: 'pickNodes', ...options });
	},
);

/**
 * Set input mode for picking a point on the canvas.
 */
export const startPickPointAtom = atom(
	null,
	(_get, set, options: { prompt: string; snapToGrid?: boolean }) => {
		set(inputModeAtom, { type: 'pickPoint', ...options });
	},
);

/**
 * Provide input value (called when user picks a node/point).
 */
export const provideInputAtom = atom(null, (get, set, value: unknown) => {
	set(pendingInputResolverAtom, value);
	// Input mode is typically reset by the consumer after receiving the value
});

/**
 * Update feedback during interaction.
 */
export const updateInteractionFeedbackAtom = atom(null, (get, set, feedback: Partial<NonNullable<FeedbackState>>) => {
	const current = get(interactionFeedbackAtom);
	set(interactionFeedbackAtom, { ...current, ...feedback });
});

// =============================================================================
// Derived Atoms
// =============================================================================

/**
 * Whether canvas is in a picking mode (not normal).
 */
export const isPickingModeAtom = atom((get) => {
	const mode = get(inputModeAtom);
	return mode.type !== 'normal';
});

/**
 * Whether currently picking a node.
 */
export const isPickNodeModeAtom = atom((get) => {
	const mode = get(inputModeAtom);
	return mode.type === 'pickNode' || mode.type === 'pickNodes';
});
