/**
 * Gesture Rules — Type Definitions
 *
 * All type/interface definitions for the composable gesture rule system.
 * Split from gesture-rules.ts for modularity.
 */

import type { InputSource } from './input-classifier';
import type { GestureType, GestureTarget } from './gesture-resolver';

// Re-export for convenience
export type { InputSource, GestureType, GestureTarget };

// =============================================================================
// Types
// =============================================================================

/** Mouse button */
export type GestureButton = 0 | 1 | 2;

/** Modifier key combination */
export interface ModifierFlags {
	shift?: boolean;
	ctrl?: boolean;
	alt?: boolean;
	meta?: boolean;
}

/** Drag phase for compound gesture events */
export type GesturePhase = 'start' | 'move' | 'end' | 'instant';

/**
 * Full description of a gesture event — the "query" passed to the resolver.
 * Every field is populated from the actual pointer/gesture event.
 */
export interface GestureDescriptor {
	/** What type of gesture is being performed */
	gesture: GestureType;
	/** What the gesture is targeting */
	target: GestureTarget;
	/** What input device is being used */
	source: InputSource;
	/** Which mouse button initiated the gesture (default: 0 = left) */
	button?: GestureButton;
	/** Modifier keys held during the gesture */
	modifiers?: ModifierFlags;
	/** Phase for drag gestures */
	phase?: GesturePhase;
	/** Whether a stylus is currently active (for palm rejection) */
	isStylusActive?: boolean;
}

/**
 * Pattern that matches gesture descriptors.
 * Omitted fields are wildcards — they match any value.
 * This is the "left-hand side" of a rule.
 */
export interface GesturePattern {
	gesture?: GestureType;
	target?: GestureTarget;
	source?: InputSource;
	button?: GestureButton;
	modifiers?: ModifierFlags;
}

/**
 * A single gesture → action mapping rule.
 */
export interface GestureRule {
	/** Unique identifier for this rule (for UI editing/removal) */
	id: string;
	/** Pattern to match against */
	pattern: GesturePattern;
	/** Action ID to execute (from action-registry) */
	actionId: string;
	/** Higher priority wins when two rules match with equal specificity */
	priority?: number;
	/** Human-readable label (auto-generated from pattern if omitted) */
	label?: string;
}

/**
 * Result of gesture resolution.
 */
export interface ResolvedGesture {
	actionId: string;
	rule: GestureRule;
	/** Effective score: specificity * 1000 + priority. Higher = better match. */
	score: number;
}

/**
 * Event payload emitted for composable gesture actions.
 */
export interface GestureActionEvent {
	/** The full gesture descriptor that was resolved */
	descriptor: GestureDescriptor;
	/** The resolved action ID */
	actionId: string;
	/** Node ID if the gesture targeted a node */
	nodeId?: string;
	/** World coordinates of the gesture */
	worldPosition: { x: number; y: number };
	/** Screen coordinates of the gesture */
	screenPosition: { x: number; y: number };
	/** Phase: instant for taps/clicks, start/move/end for drags */
	phase: GesturePhase;
}

/** Options for resolveGesture */
export interface ResolveGestureOptions {
	/** Enable palm rejection (default: true) */
	palmRejection?: boolean;
}

/**
 * Index rules by gesture type for O(n/k) typical resolution.
 */
export type GestureRuleIndex = Map<GestureType | '__wildcard__', GestureRule[]>;
