import type {
	KeybindingConfig,
	ShortcutKey,
} from "@/actions/keybinding";
import type { TActionWithOptionalArgs } from "./types";

export type TActionCategory =
	| "playback"
	| "navigation"
	| "editing"
	| "selection"
	| "history"
	| "timeline"
	| "controls"
	| "assets";

export interface TActionBaseDefinition {
	description: string;
	category: TActionCategory;
	args?: Record<string, unknown>;
}

export interface TActionDefinition extends TActionBaseDefinition {
	defaultShortcuts?: readonly ShortcutKey[];
}

export const ACTIONS = {
	"toggle-play": {
		description: "Play/Pause",
		category: "playback",
	},
	"stop-playback": {
		description: "Stop playback",
		category: "playback",
	},
	"seek-forward": {
		description: "Seek forward 1 second",
		category: "playback",
		args: { seconds: "number" },
	},
	"seek-backward": {
		description: "Seek backward 1 second",
		category: "playback",
		args: { seconds: "number" },
	},
	"frame-step-forward": {
		description: "Frame step forward",
		category: "navigation",
	},
	"frame-step-backward": {
		description: "Frame step backward",
		category: "navigation",
	},
	"jump-forward": {
		description: "Jump forward 5 seconds",
		category: "navigation",
		args: { seconds: "number" },
	},
	"jump-backward": {
		description: "Jump backward 5 seconds",
		category: "navigation",
		args: { seconds: "number" },
	},
	"goto-start": {
		description: "Go to timeline start",
		category: "navigation",
	},
	"goto-end": {
		description: "Go to timeline end",
		category: "navigation",
	},
	split: {
		description: "Split elements at playhead",
		category: "editing",
	},
	"split-left": {
		description: "Split and remove left",
		category: "editing",
	},
	"split-right": {
		description: "Split and remove right",
		category: "editing",
	},
	"delete-selected": {
		description: "Delete current selection",
		category: "editing",
	},
	"copy-selected": {
		description: "Copy selected elements",
		category: "editing",
	},
	"paste-copied": {
		description: "Paste elements at playhead",
		category: "editing",
	},
	"toggle-snapping": {
		description: "Toggle snapping",
		category: "editing",
	},
	"toggle-ripple-editing": {
		description: "Toggle ripple editing",
		category: "editing",
	},
	"toggle-source-audio": {
		description: "Extract or recover source audio",
		category: "editing",
	},
	"select-all": {
		description: "Select all elements",
		category: "selection",
	},
	"cancel-interaction": {
		description: "Cancel current interaction",
		category: "controls",
	},
	"deselect-all": {
		description: "Deselect all elements",
		category: "selection",
	},
	"duplicate-selected": {
		description: "Duplicate selected element",
		category: "selection",
	},
	"toggle-elements-muted-selected": {
		description: "Mute/unmute selected elements",
		category: "selection",
	},
	"toggle-elements-visibility-selected": {
		description: "Show/hide selected elements",
		category: "selection",
	},
	"toggle-bookmark": {
		description: "Toggle bookmark at playhead",
		category: "timeline",
	},
	undo: {
		description: "Undo",
		category: "history",
	},
	redo: {
		description: "Redo",
		category: "history",
	},
	"remove-media-asset": {
		description: "Remove media asset",
		category: "assets",
		args: { projectId: "string", assetId: "string" },
	},
	"remove-media-assets": {
		description: "Remove media assets",
		category: "assets",
		args: { projectId: "string", assetIds: "string[]" },
	},
} as const satisfies Record<string, TActionBaseDefinition>;

export type TAction = keyof typeof ACTIONS;

const ACTION_DEFAULT_SHORTCUTS = {
	"toggle-play": ["space", "k"],
	"seek-forward": ["l"],
	"seek-backward": ["j"],
	"frame-step-forward": ["right"],
	"frame-step-backward": ["left"],
	"jump-forward": ["shift+right"],
	"jump-backward": ["shift+left"],
	"goto-start": ["home", "enter"],
	"goto-end": ["end"],
	split: ["s"],
	"split-left": ["q"],
	"split-right": ["w"],
	"delete-selected": ["backspace", "delete"],
	"copy-selected": ["ctrl+c"],
	"paste-copied": ["ctrl+v"],
	"toggle-snapping": ["n"],
	"select-all": ["ctrl+a"],
	"cancel-interaction": ["escape"],
	"duplicate-selected": ["ctrl+d"],
	undo: ["ctrl+z"],
	redo: ["ctrl+shift+z", "ctrl+y"],
} as const satisfies Partial<Record<TActionWithOptionalArgs, readonly ShortcutKey[]>>;

const ACTION_DEFAULT_SHORTCUTS_BY_ACTION: Partial<
	Record<TAction, readonly ShortcutKey[]>
> = ACTION_DEFAULT_SHORTCUTS;

export function getActionDefinition({
	action,
}: {
	action: TAction;
}): TActionDefinition {
	return {
		...ACTIONS[action],
		defaultShortcuts: ACTION_DEFAULT_SHORTCUTS_BY_ACTION[action],
	};
}

export function getDefaultShortcuts(): KeybindingConfig {
	const shortcuts: KeybindingConfig = {};

	for (const [action, defaultShortcuts] of Object.entries(
		ACTION_DEFAULT_SHORTCUTS,
	) as Array<[TActionWithOptionalArgs, readonly ShortcutKey[]]>) {
		for (const shortcut of defaultShortcuts) {
			shortcuts[shortcut] = action;
		}
	}

	return shortcuts;
}
