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 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 ADMIN_EMAIL = 'e2e-responsive-nav@example.com';
const ADMIN_PASSWORD = 'ResponsiveNav123';

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

test.describe('Admin Responsive Navigation', () => {
	test.beforeAll(async () => {
		execSync(
			`docker compose -f "${composeFile}" exec -T php php bin/console app:dev:create-test-user --tenant=ecole-alpha --email=${ADMIN_EMAIL} --password=${ADMIN_PASSWORD} --role=ROLE_ADMIN 2>&1`,
			{ encoding: 'utf-8' }
		);
	});

	async function loginAsAdmin(page: import('@playwright/test').Page) {
		await page.goto(`${ALPHA_URL}/login`);
		await page.waitForLoadState('networkidle');
		await page.locator('#email').fill(ADMIN_EMAIL);
		await page.locator('#password').fill(ADMIN_PASSWORD);
		await Promise.all([
			page.waitForURL(/\/dashboard/, { timeout: 30000 }),
			page.getByRole('button', { name: /se connecter/i }).click()
		]);
	}

	// =========================================================================
	// MOBILE (375×667)
	// =========================================================================
	test.describe('Mobile (375×667)', () => {
		test.use({ viewport: { width: 375, height: 667 } });

		test('shows hamburger button and hides desktop nav', async ({ page }) => {
			await loginAsAdmin(page);
			await page.goto(`${ALPHA_URL}/admin/users`);
			await page.waitForLoadState('networkidle');

			const hamburger = page.getByRole('button', { name: /ouvrir le menu/i });
			await expect(hamburger).toBeVisible();

			const desktopNav = page.locator('.desktop-nav');
			await expect(desktopNav).not.toBeVisible();
		});

		test('displays current section label', async ({ page }) => {
			await loginAsAdmin(page);
			await page.goto(`${ALPHA_URL}/admin/users`);
			await page.waitForLoadState('networkidle');

			const label = page.locator('.mobile-section-label');
			await expect(label).toBeVisible();
			await expect(label).toHaveText('Utilisateurs');
		});

		test('opens and closes menu via hamburger button', async ({ page }) => {
			await loginAsAdmin(page);
			await page.goto(`${ALPHA_URL}/admin/users`);
			await page.waitForLoadState('networkidle');

			const hamburger = page.getByRole('button', { name: /ouvrir le menu/i });

			// Open
			await hamburger.click();
			const drawer = page.locator('[role="dialog"][aria-modal="true"]');
			await expect(drawer).toBeVisible();

			// Close via × button
			const closeButton = page.getByRole('button', { name: /fermer le menu/i });
			await closeButton.click();
			await expect(drawer).not.toBeVisible();
		});

		test('closes menu on overlay click', async ({ page }) => {
			await loginAsAdmin(page);
			await page.goto(`${ALPHA_URL}/admin/users`);
			await page.waitForLoadState('networkidle');

			await page.getByRole('button', { name: /ouvrir le menu/i }).click();
			const drawer = page.locator('[role="dialog"][aria-modal="true"]');
			await expect(drawer).toBeVisible();

			// Click overlay (outside drawer)
			const overlay = page.locator('.mobile-overlay');
			await overlay.click({ position: { x: 350, y: 300 } });
			await expect(drawer).not.toBeVisible();
		});

		test('closes menu on Escape key', async ({ page }) => {
			await loginAsAdmin(page);
			await page.goto(`${ALPHA_URL}/admin/users`);
			await page.waitForLoadState('networkidle');

			await page.getByRole('button', { name: /ouvrir le menu/i }).click();
			const drawer = page.locator('[role="dialog"][aria-modal="true"]');
			await expect(drawer).toBeVisible();

			await page.keyboard.press('Escape');
			await expect(drawer).not.toBeVisible();
		});

		test('shows active state for current section in mobile menu', async ({ page }) => {
			await loginAsAdmin(page);
			await page.goto(`${ALPHA_URL}/admin/users`);
			await page.waitForLoadState('networkidle');

			await page.getByRole('button', { name: /ouvrir le menu/i }).click();
			const drawer = page.locator('[role="dialog"][aria-modal="true"]');
			await expect(drawer).toBeVisible();

			// Active category "Personnes" should be auto-expanded
			const activeLink = drawer.locator('.mobile-nav-link.active');
			await expect(activeLink).toHaveText('Utilisateurs');
		});

		test('navigates via mobile menu and closes it', async ({ page }) => {
			await loginAsAdmin(page);
			await page.goto(`${ALPHA_URL}/admin/users`);
			await page.waitForLoadState('networkidle');

			// Open menu and expand "Organisation" section to find "Classes"
			await page.getByRole('button', { name: /ouvrir le menu/i }).click();
			const drawer = page.locator('[role="dialog"][aria-modal="true"]');
			await expect(drawer).toBeVisible();

			// Expand "Organisation" accordion
			await drawer.getByRole('button', { name: 'Organisation' }).click();
			await drawer.getByRole('link', { name: 'Classes' }).click();

			// Menu should close and page should navigate
			await expect(drawer).not.toBeVisible();
			await expect(page).toHaveURL(/\/admin\/classes/);

			// Section label should update
			const label = page.locator('.mobile-section-label');
			await expect(label).toHaveText('Classes');
		});

		test('accordion sections expand and collapse', async ({ page }) => {
			await loginAsAdmin(page);
			await page.goto(`${ALPHA_URL}/admin/users`);
			await page.waitForLoadState('networkidle');

			await page.getByRole('button', { name: /ouvrir le menu/i }).click();
			const drawer = page.locator('[role="dialog"][aria-modal="true"]');
			await expect(drawer).toBeVisible();

			// "Personnes" should be auto-expanded (active category)
			await expect(drawer.getByRole('link', { name: 'Utilisateurs' })).toBeVisible();

			// "Organisation" should be collapsed initially
			await expect(drawer.getByRole('link', { name: 'Classes' })).not.toBeVisible();

			// Expand "Organisation"
			await drawer.getByRole('button', { name: 'Organisation' }).click();
			await expect(drawer.getByRole('link', { name: 'Classes' })).toBeVisible();

			// Collapse "Organisation"
			await drawer.getByRole('button', { name: 'Organisation' }).click();
			await expect(drawer.getByRole('link', { name: 'Classes' })).not.toBeVisible();
		});
	});

	// =========================================================================
	// TABLET (768×1024)
	// =========================================================================
	test.describe('Tablet (768×1024)', () => {
		test.use({ viewport: { width: 768, height: 1024 } });

		test('shows hamburger button (below 1200px)', async ({ page }) => {
			await loginAsAdmin(page);
			await page.goto(`${ALPHA_URL}/admin/users`);
			await page.waitForLoadState('networkidle');

			const hamburger = page.getByRole('button', { name: /ouvrir le menu/i });
			await expect(hamburger).toBeVisible();

			const desktopNav = page.locator('.desktop-nav');
			await expect(desktopNav).not.toBeVisible();
		});

		test('drawer opens and shows grouped nav', async ({ page }) => {
			await loginAsAdmin(page);
			await page.goto(`${ALPHA_URL}/admin/users`);
			await page.waitForLoadState('networkidle');

			await page.getByRole('button', { name: /ouvrir le menu/i }).click();
			const drawer = page.locator('[role="dialog"][aria-modal="true"]');
			await expect(drawer).toBeVisible();

			// "Personnes" auto-expanded (contains active link Utilisateurs)
			await expect(drawer.getByRole('link', { name: 'Utilisateurs' })).toBeVisible();

			// Expand "Organisation" to see its links
			await drawer.getByRole('button', { name: 'Organisation' }).click();
			await expect(drawer.getByRole('link', { name: 'Classes' })).toBeVisible();
			await expect(drawer.getByRole('link', { name: 'Matières' })).toBeVisible();
		});
	});

	// =========================================================================
	// DESKTOP (1280×800)
	// =========================================================================
	test.describe('Desktop (1280×800)', () => {
		test.use({ viewport: { width: 1280, height: 800 } });

		test('hides hamburger and shows desktop nav', async ({ page }) => {
			await loginAsAdmin(page);
			await page.goto(`${ALPHA_URL}/admin/users`);
			await page.waitForLoadState('networkidle');

			const hamburger = page.getByRole('button', { name: /ouvrir le menu/i });
			await expect(hamburger).not.toBeVisible();

			const desktopNav = page.locator('.desktop-nav');
			await expect(desktopNav).toBeVisible();
		});

		test('desktop nav shows category dropdowns', async ({ page }) => {
			await loginAsAdmin(page);
			await page.goto(`${ALPHA_URL}/admin/users`);
			await page.waitForLoadState('networkidle');

			const nav = page.locator('.desktop-nav');

			// Category triggers should be visible
			await expect(nav.getByRole('button', { name: /personnes/i })).toBeVisible();
			await expect(nav.getByRole('button', { name: /organisation/i })).toBeVisible();
			await expect(nav.getByRole('button', { name: /année scolaire/i })).toBeVisible();
			await expect(nav.getByRole('button', { name: /paramètres/i })).toBeVisible();

			// Hover "Personnes" to reveal dropdown
			await nav.getByRole('button', { name: /personnes/i }).hover();
			const dropdown = nav.locator('.dropdown-panel').first();
			await expect(dropdown).toBeVisible();
			await expect(dropdown.getByRole('menuitem', { name: 'Utilisateurs' })).toBeVisible();
			await expect(dropdown.getByRole('menuitem', { name: 'Élèves' })).toBeVisible();

			// Hover "Organisation"
			await nav.getByRole('button', { name: /organisation/i }).hover();
			const orgDropdown = nav.locator('.dropdown-panel').first();
			await expect(orgDropdown.getByRole('menuitem', { name: 'Classes' })).toBeVisible();
			await expect(orgDropdown.getByRole('menuitem', { name: 'Matières' })).toBeVisible();
			await expect(orgDropdown.getByRole('menuitem', { name: 'Affectations' })).toBeVisible();
		});

		test('active category trigger is highlighted', async ({ page }) => {
			await loginAsAdmin(page);
			await page.goto(`${ALPHA_URL}/admin/users`);
			await page.waitForLoadState('networkidle');

			const nav = page.locator('.desktop-nav');
			const personnesTrigger = nav.getByRole('button', { name: /personnes/i });
			await expect(personnesTrigger).toHaveClass(/active/);
		});

		test('hides mobile section label', async ({ page }) => {
			await loginAsAdmin(page);
			await page.goto(`${ALPHA_URL}/admin/users`);
			await page.waitForLoadState('networkidle');

			const label = page.locator('.mobile-section-label');
			await expect(label).not.toBeVisible();
		});
	});
});
