import { describe, it, expect, vi } from 'vitest';
import { render } from '@testing-library/react';
import { createStore, Provider } from 'jotai';
import React from 'react';
import Graph from 'graphology';
import { Canvas } from '../../components/Canvas';
import type { GraphNodeAttributes, GraphEdgeAttributes, DBGraphNode } from '../../core/types';
import { graphAtom, graphOptions, currentGraphIdAtom } from '../../core/graph-store';
import { addNodeToLocalGraphAtom } from '../../core/graph-mutations';

function makeDbNode(id: string, x = 0, y = 0): DBGraphNode {
	return {
		id,
		graph_id: 'test-graph',
		label: `Node ${id}`,
		node_type: 'default',
		configuration: null,
		ui_properties: { x, y, width: 200, height: 100, size: 15, zIndex: 0 },
		data: null,
		created_at: '2024-01-01T00:00:00Z',
		updated_at: '2024-01-01T00:00:00Z',
	};
}

function setupStore() {
	const store = createStore();
	store.set(graphAtom, new Graph<GraphNodeAttributes, GraphEdgeAttributes>(graphOptions));
	store.set(currentGraphIdAtom, 'test-graph');
	return store;
}

function renderWithStore(store: ReturnType<typeof createStore>, ui: React.ReactElement) {
	return render(<Provider store={store}>{ui}</Provider>);
}

describe('Canvas', () => {
	it('renders viewport container', () => {
		const store = setupStore();
		const { container } = renderWithStore(
			store,
			<Canvas renderNode={({ node }) => <div>{node.label}</div>} />,
		);

		expect(container.querySelector('[data-viewport="true"]')).toBeInTheDocument();
	});

	it('renders additional children inside viewport', () => {
		const store = setupStore();
		const { getByText } = renderWithStore(
			store,
			<Canvas renderNode={({ node }) => <div>{node.label}</div>}>
				<div>Overlay Content</div>
			</Canvas>,
		);

		expect(getByText('Overlay Content')).toBeInTheDocument();
	});

	it('passes viewport props through', () => {
		const store = setupStore();
		const { container } = renderWithStore(
			store,
			<Canvas
				renderNode={({ node }) => <div>{node.label}</div>}
				className="my-canvas"
			/>,
		);

		expect(container.querySelector('.my-canvas')).toBeInTheDocument();
	});

	it('renders with custom style', () => {
		const store = setupStore();
		const { container } = renderWithStore(
			store,
			<Canvas
				renderNode={({ node }) => <div>{node.label}</div>}
				style={{ border: '1px solid red' }}
			/>,
		);

		const viewport = container.querySelector('[data-viewport="true"]') as HTMLElement;
		expect(viewport.style.border).toBe('1px solid red');
	});

	it('renders without errors when graph has no nodes', () => {
		const store = setupStore();
		const { container } = renderWithStore(
			store,
			<Canvas renderNode={({ node }) => <div>{node.label}</div>} />,
		);

		// Should render viewport without any node elements
		expect(container.querySelector('[data-viewport="true"]')).toBeInTheDocument();
		expect(container.querySelectorAll('[data-draggable-node="true"]')).toHaveLength(0);
	});
});
