import { test, expect } from '@playwright/test';
import { execSync } from 'child_process';
import { join, dirname } from 'path';
import { fileURLToPath } from 'url';

const __filename = fileURLToPath(import.meta.url);
const __dirname = dirname(__filename);

const projectRoot = join(__dirname, '../..');
const composeFile = join(projectRoot, 'compose.yaml');

// Extract port from PLAYWRIGHT_BASE_URL or use default (4173 matches playwright.config.ts)
const baseUrl = process.env.PLAYWRIGHT_BASE_URL || 'http://localhost:4173';
const urlMatch = baseUrl.match(/:(\d+)$/);
const PORT = urlMatch ? urlMatch[1] : '4173';
const ALPHA_URL = `http://ecole-alpha.classeo.local:${PORT}`;

const SA_PASSWORD = 'SuperAdmin123';
const REGULAR_PASSWORD = 'TestPassword123';

function getSuperAdminEmail(browserName: string): string {
	return `e2e-sadmin-${browserName}@test.com`;
}

function getRegularUserEmail(browserName: string): string {
	return `e2e-sadmin-regular-${browserName}@example.com`;
}

// eslint-disable-next-line no-empty-pattern
test.beforeAll(async ({}, testInfo) => {
	const browserName = testInfo.project.name;
	const saEmail = getSuperAdminEmail(browserName);
	const regularEmail = getRegularUserEmail(browserName);

	try {
		// Create a test super admin
		const saResult = execSync(
			`docker compose -f "${composeFile}" exec -T php php bin/console app:dev:create-test-super-admin --email=${saEmail} --password=${SA_PASSWORD} 2>&1`,
			{ encoding: 'utf-8' }
		);
		console.warn(
			`[${browserName}] Super admin created or exists:`,
			saResult.includes('already exists') ? 'exists' : 'created'
		);

		// Create a regular user (for access control test)
		const userResult = execSync(
			`docker compose -f "${composeFile}" exec -T php php bin/console app:dev:create-test-user --email=${regularEmail} --password=${REGULAR_PASSWORD} 2>&1`,
			{ encoding: 'utf-8' }
		);
		console.warn(
			`[${browserName}] Regular user created or exists:`,
			userResult.includes('already exists') ? 'exists' : 'created'
		);
	} catch (error) {
		console.error(`[${browserName}] Failed to create test users:`, error);
	}
});

async function loginAsSuperAdmin(
	page: import('@playwright/test').Page,
	email: string
) {
	await page.goto(`${ALPHA_URL}/login`);
	await expect(page.getByRole('heading', { name: /connexion/i })).toBeVisible();

	await page.locator('#email').fill(email);
	await page.locator('#password').fill(SA_PASSWORD);

	const submitButton = page.getByRole('button', { name: /se connecter/i });
	await Promise.all([
		page.waitForURL('**/super-admin/dashboard', { timeout: 30000 }),
		submitButton.click()
	]);
}

test.describe('Super Admin', () => {
	test.describe('Login & Redirect', () => {
		test('super admin login redirects to /super-admin/dashboard', async ({ page }, testInfo) => {
			const email = getSuperAdminEmail(testInfo.project.name);

			await loginAsSuperAdmin(page, email);

			await expect(page).toHaveURL(/\/super-admin\/dashboard/);
		});
	});

	test.describe('Dashboard', () => {
		test('dashboard displays stats cards', async ({ page }, testInfo) => {
			const email = getSuperAdminEmail(testInfo.project.name);

			await loginAsSuperAdmin(page, email);

			// The dashboard should show stat cards
			await expect(page.locator('.stat-card').first()).toBeVisible({ timeout: 10000 });

			// Verify dashboard heading
			await expect(page.getByRole('heading', { name: 'Dashboard' })).toBeVisible();
		});
	});

	test.describe('Navigation', () => {
		test('navigates to establishments page', async ({ page }, testInfo) => {
			const email = getSuperAdminEmail(testInfo.project.name);

			await loginAsSuperAdmin(page, email);

			const etablissementsLink = page.getByRole('link', { name: /établissements/i });
			await Promise.all([
				page.waitForURL('**/super-admin/establishments', { timeout: 10000 }),
				etablissementsLink.click()
			]);

			await expect(page).toHaveURL(/\/super-admin\/establishments/);
			await expect(
				page.getByRole('heading', { name: /établissements/i })
			).toBeVisible();
		});

		test('establishments page has create button', async ({ page }, testInfo) => {
			const email = getSuperAdminEmail(testInfo.project.name);

			await loginAsSuperAdmin(page, email);

			// Navigate via SPA link (page.goto would reload and lose in-memory token)
			const etablissementsLink = page.getByRole('link', { name: /établissements/i });
			await Promise.all([
				page.waitForURL('**/super-admin/establishments', { timeout: 10000 }),
				etablissementsLink.click()
			]);

			await expect(page.getByRole('heading', { name: /établissements/i })).toBeVisible({
				timeout: 10000
			});

			// Check "Nouvel établissement" button/link
			await expect(
				page.getByRole('link', { name: /nouvel établissement/i })
			).toBeVisible();
		});
	});

	test.describe('Create Establishment Form', () => {
		test('new establishment form has required fields', async ({ page }, testInfo) => {
			const email = getSuperAdminEmail(testInfo.project.name);

			await loginAsSuperAdmin(page, email);

			// Navigate via SPA links (page.goto would reload and lose in-memory token)
			const etablissementsLink = page.getByRole('link', { name: /établissements/i });
			await Promise.all([
				page.waitForURL('**/super-admin/establishments', { timeout: 10000 }),
				etablissementsLink.click()
			]);

			const newLink = page.getByRole('link', { name: /nouvel établissement/i });
			await expect(newLink).toBeVisible({ timeout: 10000 });
			await Promise.all([
				page.waitForURL('**/super-admin/establishments/new', { timeout: 10000 }),
				newLink.click()
			]);

			// Verify form fields
			await expect(page.locator('#name')).toBeVisible({ timeout: 10000 });
			await expect(page.locator('#subdomain')).toBeVisible();
			await expect(page.locator('#adminEmail')).toBeVisible();

			// Submit button should be disabled when empty
			const submitButton = page.getByRole('button', {
				name: /créer l'établissement/i
			});
			await expect(submitButton).toBeDisabled();

			// Fill in the form
			await page.locator('#name').fill('École Test E2E');
			await page.locator('#adminEmail').fill('admin-e2e@test.com');

			// Subdomain should be auto-generated
			await expect(page.locator('#subdomain')).not.toHaveValue('');

			// Submit button should be enabled
			await expect(submitButton).toBeEnabled();
		});
	});

	test.describe('Access Control', () => {
		test('regular user is redirected away from /super-admin', async ({ page }, testInfo) => {
			const regularEmail = getRegularUserEmail(testInfo.project.name);

			// Login as regular user on alpha tenant
			await page.goto(`${ALPHA_URL}/login`);
			await page.locator('#email').fill(regularEmail);
			await page.locator('#password').fill(REGULAR_PASSWORD);

			const submitButton = page.getByRole('button', { name: /se connecter/i });
			await Promise.all([
				page.waitForURL('**/dashboard', { timeout: 30000 }),
				submitButton.click()
			]);

			// Try to navigate to super-admin area
			await page.goto(`${ALPHA_URL}/super-admin/dashboard`);

			// Should be redirected away (to /dashboard since not super admin)
			await expect(page).not.toHaveURL(/\/super-admin/, { timeout: 10000 });
		});
	});
});
