/**
 * Core types for @blinksgg/canvas
 */

// --- JSON Type (Supabase compatible) ---

/**
 * JSON type compatible with Supabase's generated types.
 * This allows the package to work with database JSONB fields.
 */
export type Json =
	| string
	| number
	| boolean
	| null
	| { [key: string]: Json | undefined }
	| Json[];

// --- Graph Types ---

/**
 * Database graph record - container for nodes and edges.
 */
export interface DBGraph {
	id: string;
	owner_id: string | null;
	name: string;
	description: string | null;
	/** App-specific customization data (style guide, settings, etc.) */
	data?: Json | null;
	created_at: string;
	updated_at: string;
}

// --- Node Types ---

export type NodeId = string;
export type EdgeKey = string;

export interface NodePosition {
	x: number;
	y: number;
}

/**
 * Database node record - the shape of node data from your database.
 * Uses Json type for JSONB fields to be compatible with Supabase's generated types.
 */
export interface DBGraphNode {
	id: string;
	graph_id: string;
	label: string | null;
	node_type: string | null;
	configuration: Json | null;
	ui_properties: Json | null;
	/** App-specific customization data */
	data?: Json | null;
	created_at: string;
	updated_at: string;
}

/**
 * UI properties stored in database JSONB
 */
export interface UINodePropertiesFromDB {
	x?: number;
	y?: number;
	size?: number;
	width?: number;
	height?: number;
	color?: string;
	zIndex?: number;
}

/**
 * UI node properties for persist callbacks.
 * Typed version of the JSONB payload sent to database updates.
 * Known fields have explicit types; additional app-specific fields are allowed via index signature.
 */
export interface UINodeProperties {
	x?: number;
	y?: number;
	width?: number;
	height?: number;
	size?: number;
	color?: string;
	zIndex?: number;
	[key: string]: Json | undefined;
}

/**
 * Graph node attributes stored in Graphology
 */
export interface GraphNodeAttributes {
	x: number;
	y: number;
	size: number;
	width: number;
	height: number;
	color: string;
	label?: string;
	zIndex: number;
	dbData: DBGraphNode;
	/** Parent group node ID (for nested grouping) */
	parentId?: string;
}

/**
 * Complete UI node state for rendering
 */
export interface UINodeState extends GraphNodeAttributes {
	id: NodeId;
	position: NodePosition;
	isDragging: boolean;
}

// --- Edge Types ---

/**
 * Database edge record.
 * Uses Json type for JSONB fields to be compatible with Supabase's generated types.
 */
export interface DBGraphEdge {
	id: string;
	graph_id: string;
	source_node_id: string;
	target_node_id: string;
	edge_type: string | null;
	filter_condition: Json | null;
	ui_properties: Json | null;
	/** App-specific customization data */
	data?: Json | null;
	created_at: string;
	updated_at: string;
}

/**
 * UI properties stored in database JSONB for edges
 */
export interface UIEdgePropertiesFromDB {
	style?: string;
	color?: string;
	weight?: number;
}

/**
 * Graph edge attributes stored in Graphology
 */
export interface GraphEdgeAttributes {
	weight?: number;
	type?: 'solid' | 'dashed';
	color?: string;
	label?: string;
	dbData: DBGraphEdge;
}

/**
 * Complete UI edge state for rendering
 */
export interface UIEdgeState extends GraphEdgeAttributes {
	key: EdgeKey;
	sourceId: string;
	targetId: string;
	sourcePosition: NodePosition;
	targetPosition: NodePosition;
	sourceNodeSize: number;
	targetNodeSize: number;
	sourceNodeWidth: number;
	sourceNodeHeight: number;
	targetNodeWidth: number;
	targetNodeHeight: number;
	/** Source port ID (if using port-based connections) */
	sourcePort?: string;
	/** Target port ID (if using port-based connections) */
	targetPort?: string;
	/** Calculated source endpoint position (when port is specified) */
	sourceEndpoint?: NodePosition;
	/** Calculated target endpoint position (when port is specified) */
	targetEndpoint?: NodePosition;
}

/**
 * State for edge creation in progress
 */
export interface EdgeCreationState {
	isCreating: boolean;
	sourceNodeId: string | null;
	sourceNodePosition: NodePosition | null;
	targetPosition: NodePosition | null;
	hoveredTargetNodeId: string | null;
	sourceHandle: string | null;
	targetHandle: string | null;
	/** Port ID on the source node (for port-based connections) */
	sourcePort: string | null;
	/** Port ID on the target node (for port-based connections) */
	targetPort: string | null;
	/** Snapped target position (when hovering a valid port) */
	snappedTargetPosition: NodePosition | null;
}

// --- Sync Types ---

export type SyncStatus = 'synced' | 'syncing' | 'error' | 'offline';

export type QueuedMutationType = 'UPDATE_NODE' | 'DELETE_NODE' | 'CREATE_EDGE' | 'UPDATE_EDGE' | 'DELETE_EDGE';

export interface QueuedMutation {
	id: string;
	type: QueuedMutationType;
	payload: { [key: string]: Json | undefined };
	timestamp: number;
	retryCount: number;
	maxRetries: number;
}

// --- Viewport Types ---

export interface PanOffset {
	x: number;
	y: number;
}

// --- Render Props Types ---

export interface NodeRenderProps {
	node: UINodeState;
	isSelected: boolean;
	isDragging: boolean;
	isResizing: boolean;
}
