import AxeBuilder from '@axe-core/playwright';
import { expect, test, type Page } from '@playwright/test';

const email = process.env.E2E_EMAIL;
const password = process.env.E2E_PASSWORD;

if (process.env.CI && (!email || !password)) {
    throw new Error('E2E_EMAIL and E2E_PASSWORD are required for the Phase 8 Home route in CI.');
}

const login = async (page: Page): Promise<void> => {
    await page.goto('/login');
    await page.getByRole('textbox', { name: 'Username', exact: true }).fill(email!);
    await page.getByLabel('Password').fill(password!);
    await page.getByRole('button', { name: 'Login' }).click();
    await expect(page).toHaveURL(/\/$/);
};

const expectPersistentShell = async (page: Page): Promise<void> => {
    await expect(page.locator('.application-shell')).toHaveCount(1);
    await expect(page.locator('#application-navigation')).toHaveCount(1);
    await expect(page.locator('#application-content')).toHaveCount(1);
    await expect(page.locator('#top-menu, #left-menu')).toHaveCount(0);
};

test('Phase 8 Home renders the migrated metrics and activity preview inside the persistent Vue shell', async ({ page }, testInfo) => {
    test.skip(!email || !password, 'Set E2E_EMAIL and E2E_PASSWORD to validate the Phase 8 Home route.');

    const consoleProblems: string[] = [];

    page.on('console', (message) => {
        if (message.type() === 'error' || message.type() === 'warning') {
            consoleProblems.push(`${message.type()}: ${message.text()}`);
        }
    });
    page.on('pageerror', (error) => consoleProblems.push(`pageerror: ${error.message}`));

    await login(page);

    await expect(page.locator('html')).toHaveAttribute('data-frontend-root', 'inertia');
    await expectPersistentShell(page);
    await expect(page.getByRole('heading', { level: 1, name: 'Home' })).toBeVisible();
    await expect(page.locator('.home-page__currency-badge')).toContainText('Amounts in');

    const cards = page.locator('.home-metrics-grid .info-card');

    await expect(cards).toHaveCount(4);
    await expect(cards.nth(0)).toContainText('# Investors');
    await expect(cards.nth(1)).toContainText('# Investments');
    await expect(cards.nth(2)).toContainText('Amount invested');
    await expect(cards.nth(3)).toContainText('NAV under management');

    await expect(page.getByRole('heading', { level: 2, name: 'Activité récente' })).toBeVisible();

    const geometry = await page.evaluate(() => {
        const content = document.querySelector('#application-content')?.getBoundingClientRect();
        const card = document.querySelector('.home-page__card')?.getBoundingClientRect();

        return content && card ? {
            leftInset: card.left - content.left,
            rightInset: content.right - card.right,
        } : null;
    });

    expect(geometry).not.toBeNull();
    expect(geometry?.leftInset ?? 0).toBeGreaterThanOrEqual(0);
    expect(geometry?.rightInset ?? 0).toBeGreaterThanOrEqual(0);
    expect(await page.evaluate(() => document.documentElement.scrollWidth <= document.documentElement.clientWidth + 1)).toBe(true);

    const axe = await new AxeBuilder({ page })
        .withTags(['wcag2a', 'wcag2aa', 'wcag21aa', 'wcag22aa'])
        .analyze();
    const blockingViolations = axe.violations.filter((violation) => (
        violation.impact === 'critical' || violation.impact === 'serious'
    ));

    expect(blockingViolations).toEqual([]);
    await page.screenshot({
        path: testInfo.outputPath(`home-phase8-${testInfo.project.name}.png`),
        fullPage: true,
    });
    expect(consoleProblems).toEqual([]);
});

test('Phase 8 Home activity filters navigate to the Activity page within the persistent shell', async ({ page }, testInfo) => {
    test.skip(testInfo.project.name !== 'desktop-chromium', 'The shell-persistence marker only needs one browser project.');
    test.skip(!email || !password, 'Set E2E_EMAIL and E2E_PASSWORD to validate the Phase 8 Home route.');

    await login(page);

    const shellMarker = await page.locator('.application-shell').evaluate((shell) => {
        const marker = crypto.randomUUID();

        (shell as HTMLElement & { __phaseEightHomeMarker?: string }).__phaseEightHomeMarker = marker;

        return marker;
    });

    const seeAllLink = page.locator('.home-activity-shell').getByRole('link', { name: 'Tout voir' });

    await expect(seeAllLink).toBeVisible();
    await seeAllLink.click();

    await expect(page).toHaveURL(/\/activity$/);
    await expect(page.locator('html')).toHaveAttribute('data-frontend-root', 'inertia');
    await expect(page.getByRole('heading', { level: 1, name: 'Activité' })).toBeVisible();
    await expect.poll(() => page.locator('.application-shell').evaluate((shell) => (
        shell as HTMLElement & { __phaseEightHomeMarker?: string }
    ).__phaseEightHomeMarker)).toBe(shellMarker);
});
