import { describe, it, expect, beforeEach } from 'vitest';
import { createStore } from 'jotai';
import {
	selectedNodeIdsAtom,
	selectedEdgeIdAtom,
	selectedNodesCountAtom,
	hasSelectionAtom,
	selectSingleNodeAtom,
	toggleNodeInSelectionAtom,
	clearSelectionAtom,
	addNodesToSelectionAtom,
	removeNodesFromSelectionAtom,
	selectEdgeAtom,
	clearEdgeSelectionAtom,
} from '../core/selection-store';

describe('useCanvasSelection (atom-level)', () => {
	let store: ReturnType<typeof createStore>;

	beforeEach(() => {
		store = createStore();
	});

	it('starts with empty selection', () => {
		expect(store.get(selectedNodeIdsAtom).size).toBe(0);
		expect(store.get(hasSelectionAtom)).toBe(false);
		expect(store.get(selectedNodesCountAtom)).toBe(0);
	});

	it('selectSingleNodeAtom selects one node', () => {
		store.set(selectSingleNodeAtom, 'n1');
		expect(store.get(selectedNodeIdsAtom).has('n1')).toBe(true);
		expect(store.get(selectedNodesCountAtom)).toBe(1);
	});

	it('selectSingleNodeAtom clears previous selection', () => {
		store.set(selectSingleNodeAtom, 'n1');
		store.set(selectSingleNodeAtom, 'n2');
		expect(store.get(selectedNodeIdsAtom).size).toBe(1);
		expect(store.get(selectedNodeIdsAtom).has('n2')).toBe(true);
	});

	it('addNodesToSelectionAtom adds without clearing', () => {
		store.set(selectSingleNodeAtom, 'n1');
		store.set(addNodesToSelectionAtom, ['n2', 'n3']);
		expect(store.get(selectedNodesCountAtom)).toBe(3);
	});

	it('removeNodesFromSelectionAtom removes specific nodes', () => {
		store.set(addNodesToSelectionAtom, ['n1', 'n2', 'n3']);
		store.set(removeNodesFromSelectionAtom, ['n2']);
		expect(store.get(selectedNodesCountAtom)).toBe(2);
		expect(store.get(selectedNodeIdsAtom).has('n2')).toBe(false);
	});

	it('toggleNodeInSelectionAtom toggles', () => {
		store.set(toggleNodeInSelectionAtom, 'n1');
		expect(store.get(selectedNodeIdsAtom).has('n1')).toBe(true);
		store.set(toggleNodeInSelectionAtom, 'n1');
		expect(store.get(selectedNodeIdsAtom).has('n1')).toBe(false);
	});

	it('clearSelectionAtom empties selection', () => {
		store.set(addNodesToSelectionAtom, ['n1', 'n2']);
		store.set(clearSelectionAtom);
		expect(store.get(hasSelectionAtom)).toBe(false);
	});

	it('edge selection works independently', () => {
		store.set(selectEdgeAtom, 'e1');
		expect(store.get(selectedEdgeIdAtom)).toBe('e1');
		store.set(clearEdgeSelectionAtom);
		expect(store.get(selectedEdgeIdAtom)).toBeNull();
	});
});
