/**
 * Built-in Serialization Commands
 *
 * Commands for canvas export/import:
 * - exportCanvas: Export graph to JSON snapshot (copies to clipboard)
 * - importCanvas: Import graph from JSON snapshot (reads from clipboard)
 *
 * @since 1.3.0
 */

import type { CommandDefinition } from '../types';
import { registerCommand } from '../registry';

/**
 * Export canvas to JSON snapshot
 */
export const exportCanvasCommand: CommandDefinition = {
	name: 'exportCanvas',
	description: 'Export the current canvas to a JSON snapshot (copies to clipboard)',
	aliases: ['export'],
	category: 'custom',
	inputs: [],
	execute: async (_inputs, ctx) => {
		const { exportGraph } = await import('../../core/canvas-serializer');
		const { showToastAtom } = await import('../../core/toast-store');
		const { graphAtom } = await import('../../core/graph-store');

		const graph = ctx.get(graphAtom);
		const nodeCount = graph.order;
		const edgeCount = graph.size;

		if (nodeCount === 0) {
			throw new Error('Canvas is empty — nothing to export');
		}

		// Build a Jotai-compatible store façade from the CommandContext
		const store = { get: ctx.get, set: ctx.set } as Parameters<typeof exportGraph>[0];
		const snapshot = exportGraph(store);

		// Copy JSON to system clipboard
		const json = JSON.stringify(snapshot, null, 2);
		await navigator.clipboard.writeText(json);

		ctx.set(showToastAtom, `Exported ${nodeCount} nodes, ${edgeCount} edges to clipboard`);
	},
};

/**
 * Import canvas from JSON snapshot
 */
export const importCanvasCommand: CommandDefinition = {
	name: 'importCanvas',
	description: 'Import a canvas from a JSON snapshot (reads from clipboard)',
	aliases: ['import'],
	category: 'custom',
	inputs: [],
	execute: async (_inputs, ctx) => {
		const { importGraph, validateSnapshot } = await import('../../core/canvas-serializer');
		const { showToastAtom } = await import('../../core/toast-store');
		const { pushHistoryAtom } = await import('../../core/history-store');

		let json: string;
		try {
			json = await navigator.clipboard.readText();
		} catch {
			throw new Error('Could not read clipboard — paste the snapshot JSON manually');
		}

		let data: unknown;
		try {
			data = JSON.parse(json);
		} catch {
			throw new Error('Clipboard does not contain valid JSON');
		}

		const result = validateSnapshot(data);
		if (!result.valid) {
			throw new Error(`Invalid snapshot: ${result.errors[0]}`);
		}

		// Record history before import
		ctx.set(pushHistoryAtom, 'Import canvas');

		const store = { get: ctx.get, set: ctx.set } as Parameters<typeof importGraph>[0];
		const snapshot = data as import('../../core/canvas-serializer').CanvasSnapshot;
		importGraph(store, snapshot);

		ctx.set(showToastAtom, `Imported ${snapshot.nodes.length} nodes, ${snapshot.edges.length} edges`);
	},
};

/**
 * Register all serialization commands
 */
export function registerSerializationCommands(): void {
	registerCommand(exportCanvasCommand);
	registerCommand(importCanvasCommand);
}
