import { nanoid } from 'nanoid';

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

test.describe(
	'Data Table list view',
	{
		annotation: [{ type: 'owner', description: 'Adore' }],
	},
	() => {
		test.beforeEach(async ({ n8n, api }) => {
			await api.enableFeature('sharing');
			await api.enableFeature('folders');
			await api.enableFeature('advancedPermissions');
			await api.enableFeature('projectRole:admin');
			await api.enableFeature('projectRole:editor');
			await api.setMaxTeamProjectsQuota(-1);
			await n8n.goHome();
		});

		test('Should correctly render project data tables in project and everything in overview', async ({
			n8n,
		}) => {
			const TEST_PROJECTS = [
				{
					name: `Project ${nanoid(8)}`,
					dataTable: `Data Table ${nanoid(8)}`,
				},
				{
					name: `Project ${nanoid(8)}`,
					dataTable: `Data Table ${nanoid(8)}`,
				},
			];

			// Create projects and check that they only render their own data tables
			for (const project of TEST_PROJECTS) {
				await n8n.dataTableComposer.createDataTableInNewProject(
					project.name,
					project.dataTable,
					'empty-state',
				);

				await expect(n8n.dataTable.getDataTableCardByName(project.dataTable)).toBeVisible();
				await expect(n8n.dataTable.getDataTableCards()).toHaveCount(1);
			}

			// Go to overview, both data tables should be visible
			await n8n.navigate.toDatatables();
			for (const project of TEST_PROJECTS) {
				await expect(n8n.dataTable.getDataTableCardByName(project.dataTable)).toBeVisible();
			}
		});

		test('Should create data table in personal project when created from Overview', async ({
			n8n,
		}) => {
			const TEST_DATA_TABLE_NAME = `Data Table ${nanoid(8)}`;

			await n8n.page.goto('projects/home/datatables');

			await n8n.dataTable.clickAddDataTableAction();

			const newDataTableModal = n8n.dataTable.getNewDataTableModal();
			await expect(newDataTableModal).toBeVisible();

			await n8n.dataTableComposer.createNewDataTable(TEST_DATA_TABLE_NAME);

			const dataTableDetailsContainer = n8n.dataTableDetails.getPageWrapper();
			await expect(dataTableDetailsContainer).toBeVisible();

			const dataTableProjectBreadcrumb = n8n.dataTableDetails.getDataTableProjectBreadcrumb();
			await expect(dataTableProjectBreadcrumb).toHaveText('Personal');

			const dataTableBreadcrumb = n8n.dataTableDetails.getDataTableBreadcrumb();
			await expect(dataTableBreadcrumb).toContainText(TEST_DATA_TABLE_NAME);
		});

		test('Should create data table from project empty state', async ({ n8n }) => {
			const TEST_PROJECT_NAME = `Project ${nanoid(8)}`;
			const TEST_DATA_TABLE_NAME = `Data Table ${nanoid(8)}`;

			await n8n.dataTableComposer.createDataTableInNewProject(
				TEST_PROJECT_NAME,
				TEST_DATA_TABLE_NAME,
				'empty-state',
			);

			await expect(n8n.dataTable.getDataTableCardByName(TEST_DATA_TABLE_NAME)).toBeVisible();
		});

		test('Should create project data table from header dropdown', async ({ n8n }) => {
			const TEST_PROJECT_NAME = `Project ${nanoid(8)}`;
			const TEST_DATA_TABLE_NAME = `Data Table ${nanoid(8)}`;

			await n8n.dataTableComposer.createDataTableInNewProject(
				TEST_PROJECT_NAME,
				TEST_DATA_TABLE_NAME,
				'header-dropdown',
			);

			await expect(n8n.dataTable.getDataTableCardByName(TEST_DATA_TABLE_NAME)).toBeVisible();
		});

		test('Should create data table from workflows tab', async ({ n8n }) => {
			const TEST_PROJECT_NAME = `Project ${nanoid(8)}`;
			const TEST_DATA_TABLE_NAME = `Data Table ${nanoid(8)}`;

			await n8n.dataTableComposer.createDataTableInNewProject(
				TEST_PROJECT_NAME,
				TEST_DATA_TABLE_NAME,
				'header-dropdown',
				false,
			);

			await expect(n8n.dataTable.getDataTableCardByName(TEST_DATA_TABLE_NAME)).toBeVisible();
		});

		test('Should delete data table from card actions', async ({ n8n }) => {
			const TEST_PROJECT_NAME = `Project ${nanoid(8)}`;
			const TEST_DATA_TABLE_NAME = `Data Table ${nanoid(8)}`;

			await n8n.dataTableComposer.createDataTableInNewProject(
				TEST_PROJECT_NAME,
				TEST_DATA_TABLE_NAME,
				'empty-state',
			);

			await n8n.dataTable.clickDataTableCardActionsButton(TEST_DATA_TABLE_NAME);
			await n8n.dataTable.getDataTableCardAction('delete').click();

			await expect(n8n.dataTable.getDeleteDataTableModal()).toBeVisible();
			await n8n.dataTable.clickDeleteDataTableConfirmButton();

			await expect(n8n.dataTable.getDataTableCardByName(TEST_DATA_TABLE_NAME)).toBeHidden();
		});

		test('Should paginate data table list correctly', async ({ n8n }) => {
			const TEST_PROJECT_NAME = `Project ${nanoid(8)}`;
			const TOTAL_DATA_TABLES = 11;
			const PAGE_SIZE = 10;

			const { projectId } = await n8n.projectComposer.createProject(TEST_PROJECT_NAME);
			await n8n.page.goto(`projects/${projectId}/datatables`);

			// Create just enough data tables to require pagination
			for (let i = 0; i < TOTAL_DATA_TABLES; i++) {
				await n8n.dataTable.clickAddDataTableAction();
				await n8n.dataTableComposer.createNewDataTable(`Data Table ${i + 1}`);
				await n8n.sideBar.clickProjectMenuItem(TEST_PROJECT_NAME);
				await n8n.dataTable.clickDataTableProjectTab();
			}
			// Change page size to PAGE_SIZE
			await n8n.dataTable.selectDataTablePageSize(PAGE_SIZE.toString());
			// First page should only have PAGE_SIZE items
			await expect(n8n.dataTable.getDataTableCards()).toHaveCount(PAGE_SIZE);

			// Forward to next page, should show the rest
			await n8n.dataTable.getPaginationNextButton().click();
			await expect(n8n.dataTable.getDataTableCards()).toHaveCount(TOTAL_DATA_TABLES - PAGE_SIZE);
		});
	},
);
