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();
			});
		});
	},
);
