import { test, expect } from '../../../../../fixtures/base';

test.describe('Expression editor modal', () => {
	test.beforeEach(async ({ n8n }) => {
		await n8n.start.fromBlankCanvas();
		await n8n.canvas.addInitialNodeToCanvas('Schedule Trigger');
		await n8n.ndv.close();
	});

	test.describe('Keybinds', () => {
		test.beforeEach(async ({ n8n }) => {
			await n8n.canvas.addNode('Hacker News', { action: 'Get many items' });
			await n8n.ndv.openExpressionEditorModal('limit');
		});

		test('should save the workflow with save keybind', async ({ n8n }) => {
			const input = n8n.ndv.getExpressionEditorModalInput();
			await n8n.ndv.fillExpressionEditorModalInput('{{ "hello"');
			await expect(n8n.ndv.getExpressionEditorModalOutput()).toContainText('hello');

			await input.press('ControlOrMeta+s');
			await n8n.notifications.waitForNotificationAndClose('Saved successfully');
		});
	});

	test.describe('Static data', () => {
		test.beforeEach(async ({ n8n }) => {
			await n8n.canvas.addNode('Hacker News', { action: 'Get many items' });
			await n8n.ndv.openExpressionEditorModal('limit');
		});

		test('should resolve primitive resolvables', async ({ n8n }) => {
			const output = n8n.ndv.getExpressionEditorModalOutput();

			// Test number addition
			await n8n.ndv.fillExpressionEditorModalInput('{{ 1 + 2 }}');
			await expect(output).toContainText(/^3$/);

			// Test string concatenation
			await n8n.ndv.fillExpressionEditorModalInput('{{ "ab" + "cd" }}');
			await expect(output).toContainText(/^abcd$/);

			// Test boolean logic
			await n8n.ndv.fillExpressionEditorModalInput('{{ true && false }}');
			await expect(output).toContainText(/^false$/);
		});

		test('should resolve object resolvables', async ({ n8n }) => {
			const output = n8n.ndv.getExpressionEditorModalOutput();

			// Test object creation
			await n8n.ndv.fillExpressionEditorModalInput('{{ { a : 1 } }}');
			await expect(output).toContainText(/^\[Object: \{"a": 1\}\]$/);

			// Test object property access
			await n8n.ndv.fillExpressionEditorModalInput('{{ { a : 1 }.a }}');
			await expect(output).toContainText(/^1$/);
		});

		test('should resolve array resolvables', async ({ n8n }) => {
			const output = n8n.ndv.getExpressionEditorModalOutput();

			// Test array creation
			await n8n.ndv.fillExpressionEditorModalInput('{{ [1, 2, 3] }}');
			await expect(output).toContainText(/^\[Array: \[1,2,3\]\]$/);

			// Test array element access
			await n8n.ndv.fillExpressionEditorModalInput('{{ [1, 2, 3][0] }}');
			await expect(output).toContainText(/^1$/);
		});
	});

	test.describe('Dynamic data', () => {
		test.beforeEach(async ({ n8n }) => {
			await n8n.canvas.openNode('Schedule Trigger');
			await n8n.ndv.setPinnedData([{ myStr: 'Monday' }]);
			await n8n.ndv.clickBackToCanvasButton();
			await n8n.canvas.addNode('No Operation, do nothing', { closeNDV: true });
			await n8n.canvas.addNode('Hacker News', { action: 'Get many items' });
			await n8n.ndv.openExpressionEditorModal('limit');
		});

		test('should resolve $parameter[]', async ({ n8n }) => {
			const output = n8n.ndv.getExpressionEditorModalOutput();
			await n8n.ndv.fillExpressionEditorModalInput('{{ $parameter["operation"] }}');
			await expect(output).toHaveText('getAll');
		});

		test('should resolve input: $json,$input,$(nodeName)', async ({ n8n }) => {
			const output = n8n.ndv.getExpressionEditorModalOutput();

			// Previous nodes have not run, input is empty
			await n8n.ndv.fillExpressionEditorModalInput('{{ $json.myStr }}');
			await expect(output).toHaveText('[Execute previous nodes for preview]');
			await n8n.ndv.fillExpressionEditorModalInput('{{ $input.item.json.myStr }}');
			await expect(output).toHaveText('[Execute previous nodes for preview]');
			await n8n.ndv.fillExpressionEditorModalInput("{{ $('Schedule Trigger').item.json.myStr }}");
			await expect(output).toHaveText('[Execute previous nodes for preview]');

			// Run workflow
			await output.click();
			await n8n.page.keyboard.press('Escape');
			await n8n.ndv.clickBackToCanvasButton();
			await n8n.canvas.executeNode('No Operation, do nothing');
			await n8n.canvas.openNode('Get many items');
			await n8n.ndv.openExpressionEditorModal('limit');

			// Previous nodes have run, input can be resolved
			await n8n.ndv.fillExpressionEditorModalInput('{{ $json.myStr }}');
			await expect(output).toHaveText('Monday');
			await n8n.ndv.fillExpressionEditorModalInput('{{ $input.item.json.myStr }}');
			await expect(output).toHaveText('Monday');
			await n8n.ndv.fillExpressionEditorModalInput("{{ $('Schedule Trigger').item.json.myStr }}");
			await expect(output).toHaveText('Monday');
		});
	});
});
