import type { IWorkflowBase } from 'n8n-workflow';

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

test.describe('Form Trigger', {
	annotation: [
		{ type: 'owner', description: 'NODES' },
	],
}, () => {
	test.beforeEach(async ({ n8n }) => {
		await n8n.start.fromBlankCanvas();
	});

	test("add node by clicking on 'On form submission'", async ({ n8n }) => {
		await n8n.canvas.clickNodeCreatorPlusButton();
		await n8n.canvas.nodeCreatorItemByName('On form submission').click();

		await n8n.ndv.fillParameterInput('Form Title', 'Test Form');
		await n8n.ndv.fillParameterInput('Form Description', 'Test Form Description');
		await n8n.ndv.clickBackToCanvasButton();

		await expect(n8n.canvas.nodeByName('On form submission')).toBeVisible();
		await expect(n8n.canvas.nodeIssuesBadge('On form submission')).toBeHidden();
	});

	test('should fill up form fields', async ({ n8n }) => {
		await n8n.canvas.clickNodeCreatorPlusButton();
		await n8n.canvas.nodeCreatorItemByName('On form submission').click();

		await n8n.ndv.fillParameterInput('Form Title', 'Test Form');
		await n8n.ndv.fillParameterInput('Form Description', 'Test Form Description');

		// Add first field - Number type with required flag
		await n8n.ndv.addFixedCollectionItem();
		await n8n.ndv.fillParameterInputByName('fieldLabel', 'Test Field 1');
		await n8n.ndv.selectOptionInParameterDropdown('fieldType', 'Number');
		await n8n.ndv.addFixedCollectionProperty('Custom Field Name', 0);
		await n8n.ndv.fillParameterInputByName('fieldName', 'testField1');
		await n8n.ndv.addFixedCollectionProperty('Required Field', 0);
		await n8n.ndv.setParameterSwitch('requiredField', true);

		// Add second field - Text type
		await n8n.ndv.addFixedCollectionItem();
		await n8n.ndv.fillParameterInputByName('fieldLabel', 'Test Field 2', 1);
		await n8n.ndv.addFixedCollectionProperty('Custom Field Name', 1);
		await n8n.ndv.fillParameterInputByName('fieldName', 'testField2', 1);

		// Add third field - Date type
		await n8n.ndv.addFixedCollectionItem();
		await n8n.ndv.fillParameterInputByName('fieldLabel', 'Test Field 3', 2);
		await n8n.ndv.selectOptionInParameterDropdown('fieldType', 'Date', 2);
		await n8n.ndv.addFixedCollectionProperty('Custom Field Name', 2);
		await n8n.ndv.fillParameterInputByName('fieldName', 'testField3', 2);

		// Add fourth field - Dropdown type with options
		await n8n.ndv.addFixedCollectionItem();
		await n8n.ndv.fillParameterInputByName('fieldLabel', 'Test Field 4', 3);
		await n8n.ndv.selectOptionInParameterDropdown('fieldType', 'Dropdown', 3);
		await n8n.ndv.addFixedCollectionProperty('Custom Field Name', 3);
		await n8n.ndv.fillParameterInputByName('fieldName', 'testField4', 3);

		// Configure dropdown field options
		await n8n.page.getByRole('button', { name: 'Add Field Option' }).click();
		await n8n.ndv.fillParameterInputByName('option', 'Option 1');
		await n8n.ndv.fillParameterInputByName('option', 'Option 2', 1);

		// Add optional submitted message
		await n8n.ndv.addParameterOptionByName('Form Response');
		await n8n.ndv.fillParameterInput('Text to Show', 'Your test form was successfully submitted');

		await n8n.ndv.clickBackToCanvasButton();
		await expect(n8n.canvas.nodeByName('On form submission')).toBeVisible();
		await expect(n8n.canvas.nodeIssuesBadge('On form submission')).toBeHidden();
	});

	test('should create and submit a multi-page form', async ({ n8n }) => {
		// Add Form Trigger node with first name field
		await n8n.canvas.clickNodeCreatorPlusButton();
		await n8n.canvas.nodeCreatorItemByName('On form submission').click();

		await n8n.ndv.fillParameterInput('Form Title', 'Multi-Page Form');
		await n8n.ndv.fillParameterInput('Form Description', 'A form with multiple pages');

		// Add a single field to the Form Trigger node
		await n8n.ndv.addFixedCollectionItem();
		await n8n.ndv.fillParameterInputByName('fieldLabel', 'What is your first name?');

		await n8n.ndv.clickBackToCanvasButton();

		// Add Form node (next page) by selecting the "Next Form Page" action
		await n8n.canvas.addNode('n8n Form', { closeNDV: false, action: 'Next Form Page' });

		// Add a single field to the Form node
		await n8n.ndv.addFixedCollectionItem();
		await n8n.ndv.fillParameterInputByName('fieldLabel', 'What is your last name?');

		await n8n.ndv.clickBackToCanvasButton();

		// Start the workflow execution so it's waiting for form submissions
		// This allows the multi-page form flow to work (continuing to Form node after trigger)
		await n8n.canvas.clickExecuteWorkflowButton();
		await expect(n8n.canvas.getExecuteWorkflowButton()).toHaveText('Waiting for trigger event');

		// Get the form test URL from the NDV
		await n8n.canvas.openNode('On form submission');
		const formUrlLocator = n8n.page.locator('text=/form-test\\/[a-f0-9-]+/');
		const formUrl = await formUrlLocator.textContent();

		// Open form URL in a new browser tab
		const formPage = await n8n.page.context().newPage();
		await formPage.goto(formUrl!);

		// Fill first page with a random first name
		const firstName = `John${Date.now()}`;
		await formPage.getByLabel('What is your first name?').fill(firstName);
		await formPage.getByRole('button', { name: 'Submit' }).click();

		// Fill second page with a random last name
		const lastName = `Doe${Date.now()}`;
		await formPage.getByLabel('What is your last name?').fill(lastName);
		await formPage.getByRole('button', { name: 'Submit' }).click();

		// Verify the form was submitted successfully
		await expect(formPage.getByText('Your response has been recorded')).toBeVisible();

		// Close the form page
		await formPage.close();
	});

	test.describe('form execution with basic auth', () => {
		const password = new Date().toDateString();

		test.use({
			httpCredentials: {
				username: 'test',
				password,
			},
		});

		test('form submission works with basic auth', async ({ api, n8n }) => {
			const { id, name } = await api.credentials.createCredential({
				name: 'Basic Auth test:test',
				type: 'httpBasicAuth',
				data: {
					user: 'test',
					password,
				},
			});

			const workflow: Partial<IWorkflowBase> = {
				nodes: [
					{
						parameters: {
							authentication: 'basicAuth',
							formTitle: 'Test',
							options: {
								respondWithOptions: {
									values: {
										formSubmittedText: 'This worked',
									},
								},
							},
						},
						type: 'n8n-nodes-base.formTrigger',
						typeVersion: 2.5,
						position: [0, 0],
						id: '49b31a69-3fc9-43d0-944e-990783330e7a',
						name: 'On form submission',
						webhookId: '17eae80c-039e-4779-be68-08cd5afc5f65',
						credentials: {
							httpBasicAuth: {
								id,
								name,
							},
						},
					},
				],
				connections: {},
				pinData: {},
				meta: {
					instanceId: 'acd7615bcc3af421bbd7517e305cc16505176a6a47045dbe39e25d904c940573',
				},
			};

			const { workflowId } = await api.workflows.createWorkflowFromDefinition(workflow, {
				makeUnique: true,
			});

			await n8n.page.goto(`/workflow/${workflowId}`);

			// Start the workflow execution so it's waiting for form submissions
			await n8n.canvas.clickExecuteWorkflowButton();
			await expect(n8n.canvas.getExecuteWorkflowButton()).toHaveText('Waiting for trigger event');

			// Get the form test URL from the NDV
			await n8n.canvas.openNode('On form submission');
			const formUrlLocator = n8n.page.locator('text=/form-test\\/[a-f0-9-]+/');
			const formUrl = await formUrlLocator.textContent();

			// Open form URL in a new browser tab

			const formPage = await n8n.page.context().newPage();
			await formPage.goto(formUrl!);

			// Submit the form
			await formPage.getByRole('button', { name: 'Submit' }).click();
			await expect(formPage.getByText('This worked')).toBeVisible();
		});

		test('multi-step form submission works with basic auth', async ({ api, n8n }) => {
			const { id, name } = await api.credentials.createCredential({
				name: 'Basic Auth test:test',
				type: 'httpBasicAuth',
				data: {
					user: 'test',
					password,
				},
			});

			const workflow: Partial<IWorkflowBase> = {
				nodes: [
					{
						parameters: {
							authentication: 'basicAuth',
							formTitle: 'Test',
						},
						type: 'n8n-nodes-base.formTrigger',
						typeVersion: 2.5,
						position: [0, 0],
						id: '49b31a69-3fc9-43d0-944e-990783330e7a',
						name: 'On form submission',
						webhookId: '17eae80c-039e-4779-be68-08cd5afc5f64',
						credentials: {
							httpBasicAuth: {
								id,
								name,
							},
						},
					},
					{
						parameters: {
							options: {
								formDescription: 'Step 2',
							},
						},
						type: 'n8n-nodes-base.form',
						typeVersion: 2.5,
						position: [208, 0],
						id: 'e748b959-faeb-4476-aa30-1c7a6434843a',
						name: 'Form',
						webhookId: '1e1a6d32-d3a4-4150-886b-2119cc4072bc',
					},
					{
						parameters: {
							operation: 'completion',
							completionTitle: 'Success',
							completionMessage: 'This worked',
							options: {},
						},
						type: 'n8n-nodes-base.form',
						typeVersion: 2.5,
						position: [416, 0],
						id: '2e52c834-e08a-4848-bd86-be1f7909a956',
						name: 'Form1',
						webhookId: '1839391a-f07d-4bee-858f-678c1b45252b',
					},
				],
				connections: {
					'On form submission': {
						main: [
							[
								{
									node: 'Form',
									type: 'main',
									index: 0,
								},
							],
						],
					},
					Form: {
						main: [
							[
								{
									node: 'Form1',
									type: 'main',
									index: 0,
								},
							],
						],
					},
				},
				pinData: {},
				meta: {
					templateCredsSetupCompleted: true,
					instanceId: 'acd7615bcc3af421bbd7517e305cc16505176a6a47045dbe39e25d904c940573',
				},
			};

			const { workflowId } = await api.workflows.createWorkflowFromDefinition(workflow, {
				makeUnique: true,
			});

			await n8n.page.goto(`/workflow/${workflowId}`);

			// Start the workflow execution so it's waiting for form submissions
			await n8n.canvas.clickExecuteWorkflowButton();
			await expect(n8n.canvas.getExecuteWorkflowButton()).toHaveText('Waiting for trigger event');

			// Get the form test URL from the NDV
			await n8n.canvas.openNode('On form submission');
			const formUrlLocator = n8n.page.locator('text=/form-test\\/[a-f0-9-]+/');
			const formUrl = await formUrlLocator.textContent();

			// Open form URL in a new browser tab

			const formPage = await n8n.page.context().newPage();
			await formPage.goto(formUrl!);

			// Submit first page
			await formPage.getByRole('button', { name: 'Submit' }).click();
			await expect(formPage.getByText('Step 2')).toBeVisible();

			// submit second page
			await formPage.getByRole('button', { name: 'Submit' }).click();
			await expect(formPage.getByText('This worked')).toBeVisible();
		});
	});
});
