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

test.describe(
	'Folders - Advanced Operations',
	{
		annotation: [{ type: 'owner', description: 'Identity & Access' }],
	},
	() => {
		test.describe('Duplicate workflows', () => {
			test('should duplicate workflow within root folder from personal projects', async ({
				n8n,
			}) => {
				const { id: projectId } = await n8n.api.projects.createProject();
				const { name: workflowName } = await n8n.api.workflows.createInProject(projectId);
				await n8n.navigate.toProject(projectId);
				const workflowCard = n8n.workflows.cards.getWorkflow(workflowName);
				await n8n.workflows.cards.openCardActions(workflowCard);
				await n8n.workflows.cards.getCardAction('duplicate').click();
				const duplicatePage = await n8n.start.fromNewPage(async () => {
					await n8n.modal.clickButton('Duplicate');
				});

				const duplicatedName = `${workflowName} copy`;
				await duplicatePage.navigate.toProject(projectId);
				await expect(duplicatePage.workflows.cards.getWorkflow(duplicatedName)).toBeVisible();
			});

			test('should duplicate workflow within a folder from personal projects', async ({ n8n }) => {
				const projectId = await n8n.start.fromNewProject();
				const folder = await n8n.api.projects.createFolder(projectId);
				const { name: workflowName } = await n8n.api.workflows.createInProject(projectId, {
					folder: folder.id,
				});
				await n8n.navigate.toFolder(folder.id, projectId);

				const workflowCard = n8n.workflows.cards.getWorkflow(workflowName);
				await n8n.workflows.cards.openCardActions(workflowCard);
				await n8n.workflows.cards.getCardAction('duplicate').click();

				const duplicatePage = await n8n.start.fromNewPage(async () => {
					await n8n.modal.clickButton('Duplicate');
				});

				await duplicatePage.navigate.toFolder(folder.id);
				const duplicatedName = `${workflowName} copy`;
				await expect(duplicatePage.workflows.cards.getWorkflow(duplicatedName)).toBeVisible();
			});

			test('should duplicate workflow within a folder from workflow page', async ({ n8n }) => {
				const { id: projectId } = await n8n.api.projects.createProject();
				const folder = await n8n.api.projects.createFolder(projectId);
				const { name: workflowName, id: workflowId } = await n8n.api.workflows.createInProject(
					projectId,
					{
						folder: folder.id,
					},
				);
				await n8n.navigate.toCanvas(workflowId);

				await n8n.workflowSettingsModal.getWorkflowMenu().click();
				await n8n.workflowSettingsModal.getDuplicateMenuItem().click();
				const duplicatePage = await n8n.start.fromNewPage(async () => {
					await n8n.modal.clickButton('Duplicate');
				});

				const duplicatedName = `${workflowName} copy`;
				await duplicatePage.navigate.toFolder(folder.id, projectId);
				await expect(duplicatePage.workflows.cards.getWorkflow(duplicatedName)).toBeVisible();
			});
		});

		test.describe('Drag and drop', () => {
			test('should drag and drop folders into folders', async ({ n8n }) => {
				const { id: projectId } = await n8n.api.projects.createProject('Drag and Drop Test');
				await n8n.navigate.toProject(projectId);
				const targetFolder = await n8n.api.projects.createFolder(projectId, 'Drag me');
				const destinationFolder = await n8n.api.projects.createFolder(
					projectId,
					'Folder Destination',
				);

				const sourceFolderCard = n8n.workflows.cards.getFolder(targetFolder.name);
				const destinationFolderCard = n8n.workflows.cards.getFolder(destinationFolder.name);

				await n8n.interactions.precisionDragToTarget(sourceFolderCard, destinationFolderCard);

				await expect(
					n8n.notifications.getNotificationByTitleOrContent(
						`${targetFolder.name} has been moved to ${destinationFolder.name}`,
					),
				).toBeVisible();

				await expect(n8n.workflows.cards.getFolders()).toHaveCount(1);

				await n8n.workflows.cards.openFolder(destinationFolder.name);
				await expect(n8n.workflows.cards.getFolder(targetFolder.name)).toBeVisible();
			});

			test('should drag and drop folders into project root breadcrumb', async ({ n8n }) => {
				const project = await n8n.api.projects.createProject('Drag to root test');
				await n8n.navigate.toProject(project.id);
				const parentFolder = await n8n.api.projects.createFolder(project.id, 'Parent Folder');
				const targetFolder = await n8n.api.projects.createFolder(
					project.id,
					'To Project root',
					parentFolder.id,
				);

				await n8n.navigate.toFolder(parentFolder.id, project.id);

				const sourceFolderCard = n8n.workflows.cards.getFolder(targetFolder.name);
				const projectBreadcrumb = n8n.breadcrumbs.getHomeProjectBreadcrumb();

				await n8n.interactions.precisionDragToTarget(sourceFolderCard, projectBreadcrumb);

				await expect(
					n8n.notifications.getNotificationByTitleOrContent(
						`${targetFolder.name} has been moved to ${project.name}`,
					),
				).toBeVisible();

				await expect(n8n.workflows.cards.getFolders()).toHaveCount(0);

				await n8n.navigate.toProject(project.id);
				await expect(n8n.workflows.cards.getFolder(targetFolder.name)).toBeVisible();
			});

			test('should drag and drop workflows into folders', async ({ n8n }) => {
				const { id: projectId } = await n8n.api.projects.createProject('Drag and Drop WF Test');
				const { name: workflowName } = await n8n.api.workflows.createInProject(projectId, {});
				const destinationFolder = await n8n.api.projects.createFolder(projectId);
				await n8n.navigate.toProject(projectId);

				const sourceWorkflowCard = n8n.workflows.cards.getWorkflow(workflowName);
				const destinationFolderCard = n8n.workflows.cards.getFolder(destinationFolder.name);

				await n8n.interactions.precisionDragToTarget(sourceWorkflowCard, destinationFolderCard);

				await expect(
					n8n.notifications.getNotificationByTitleOrContent(
						`${workflowName} has been moved to ${destinationFolder.name}`,
					),
				).toBeVisible();

				await expect(n8n.workflows.cards.getWorkflows()).toHaveCount(0);

				await n8n.workflows.cards.openFolder(destinationFolder.name);
				await expect(n8n.workflows.cards.getWorkflow(workflowName)).toBeVisible();
			});
		});
	},
);
