/**
 * Badge Print Page — Print Layout CSS Tests
 *
 * Verifies that the badge is horizontally (and vertically) centered on the page
 * when print media CSS is active, using Playwright's emulateMedia({ media: 'print' }).
 *
 * Strategy: inject badge + template data directly into IndexedDB so liveQuery
 * fires without needing a full API round-trip, then check bounding boxes.
 *
 * Cross-browser: add Firefox to playwright.config.ts projects to catch the
 * overflow:auto + display:contents incompatibility that Firefox enforces strictly.
 */
import { test, expect } from '@playwright/test';
import { testing_event_id } from './_helpers/env';
import { inject_badge_and_template } from './_helpers/idb_helpers';
import { setup_badge_test_page } from './_helpers/minimal_ae_api_mocks';

const event_id = testing_event_id;

// Use the demo badge/template IDs from tests/README.md
const badge_id     = 'UIJT-73-63-61';
const template_id  = 'jgfixEpYp1B';

// Minimal badge record — both *_id and *_id_random set to the same value so
// db_events.badge.get(event_badge_id) finds the record via the Dexie primary key.
const mock_badge = {
    id: badge_id,
    event_badge_id: badge_id,
    event_badge_id_random: badge_id,
    event_id: event_id,
    event_id_random: event_id,
    event_badge_template_id: template_id,
    event_badge_template_id_random: template_id,
    full_name_override: 'Scott Idem',
    given_name: 'Scott',
    family_name: 'Idem',
    email: 'scott@example.com',
    badge_type: 'presenter',
    badge_type_code: 'presenter',
    print_count: 0,
    affiliations: 'One Sky IT',
    location: 'Minneapolis, MN',
    enable: true,
};

// Minimal template record — layout drives the @page size injection
const mock_template = {
    id: template_id,
    id_random: template_id,
    event_badge_template_id: template_id,
    badge_template_id: template_id,
    event_id: event_id,
    event_id_random: event_id,
    name: 'Dev Demo 202x',
    layout: 'badge_3.5x5.5_pvc',
    cfg_json: '{}',
    enable: true,
};


test.describe('Badge Print Page — print layout centering', () => {
    test.beforeEach(async ({ page }) => {
        await setup_badge_test_page(page, event_id);
    });

    test('badge is horizontally centered on a letter-size page', async ({ page }) => {
        // Letter paper: 8.5in × 11in at 96 dpi = 816 × 1056 px
        await page.setViewportSize({ width: 816, height: 1056 });

        // First navigation initializes the Dexie schema; inject_idb then writes the data.
        // After injection we reload so liveQuery starts fresh against the populated IDB —
        // direct IDB writes bypass Dexie's notification system and won't trigger a re-query.
        await page.goto(`/events/${event_id}/badges/${badge_id}/print`);
        await page.waitForLoadState('domcontentloaded');
        await page.evaluate(inject_badge_and_template, { badge: mock_badge, template: mock_template });
        await page.reload();
        await page.waitForLoadState('domcontentloaded');

        // Wait for LiveQuery to render the badge wrapper
        await page.waitForSelector('.event_badge_wrapper', { timeout: 8000 });

        // Apply print media CSS (activates @media print rules)
        await page.emulateMedia({ media: 'print' });

        // Wait for layout to settle under print CSS
        await page.waitForFunction(() => {
            const el = document.querySelector('.event_badge_wrapper') as HTMLElement | null;
            return el !== null && el.offsetWidth > 0;
        }, { timeout: 5000 });

        const badge_box = await page.locator('.event_badge_wrapper').boundingBox();
        expect(badge_box, 'badge wrapper must have a bounding box').not.toBeNull();

        const viewport       = page.viewportSize()!;
        const badge_center_x = badge_box!.x + badge_box!.width / 2;
        const page_center_x  = viewport.width / 2;

        // Badge horizontal center must be within 5px of the page center
        expect(
            Math.abs(badge_center_x - page_center_x),
            `badge center (${badge_center_x.toFixed(1)}px) should equal page center (${page_center_x}px)`
        ).toBeLessThan(5);
    });

    test('badge is vertically centered on a letter-size page', async ({ page }) => {
        await page.setViewportSize({ width: 816, height: 1056 });

        await page.goto(`/events/${event_id}/badges/${badge_id}/print`);
        await page.waitForLoadState('domcontentloaded');
        await page.evaluate(inject_badge_and_template, { badge: mock_badge, template: mock_template });
        await page.reload();
        await page.waitForLoadState('domcontentloaded');

        await page.waitForSelector('.event_badge_wrapper', { timeout: 8000 });
        await page.emulateMedia({ media: 'print' });

        await page.waitForFunction(() => {
            const el = document.querySelector('.event_badge_wrapper') as HTMLElement | null;
            return el !== null && el.offsetHeight > 0;
        }, { timeout: 5000 });

        const badge_box = await page.locator('.event_badge_wrapper').boundingBox();
        expect(badge_box).not.toBeNull();

        const viewport       = page.viewportSize()!;
        const badge_center_y = badge_box!.y + badge_box!.height / 2;
        const page_center_y  = viewport.height / 2;

        // Badge vertical center must be within 5px of the page center
        expect(
            Math.abs(badge_center_y - page_center_y),
            `badge center Y (${badge_center_y.toFixed(1)}px) should equal page center Y (${page_center_y}px)`
        ).toBeLessThan(5);
    });

    test('#ae_main_content is a full-page positioned block in print mode', async ({ page }) => {
        // Verifies overflow:visible (overflow:auto fix) and position:relative (centering context).
        await page.goto(`/events/${event_id}/badges/${badge_id}/print`);
        // domcontentloaded is too early — wait for the element to exist after hydration.
        await page.waitForSelector('#ae_main_content', { timeout: 8000 });
        await page.emulateMedia({ media: 'print' });

        const styles = await page.evaluate(() => {
            const el = document.getElementById('ae_main_content');
            if (!el) return null;
            const cs = getComputedStyle(el);
            return { overflow: cs.overflow, position: cs.position };
        });
        expect(styles, '#ae_main_content must exist').not.toBeNull();
        expect(styles!.overflow, '#ae_main_content overflow should be visible in print').toBe('visible');
        // position:static — print CSS strips #ae_main_content's overflow clipping by setting
        // display:block + overflow:visible + position:static so it doesn't interfere with centering.
        expect(styles!.position, '#ae_main_content should be static in print').toBe('static');
    });

    test('badge wrapper is absolutely positioned and centered in print mode', async ({ page }) => {
        await page.setViewportSize({ width: 816, height: 1056 });

        await page.goto(`/events/${event_id}/badges/${badge_id}/print`);
        await page.waitForLoadState('domcontentloaded');
        await page.evaluate(inject_badge_and_template, { badge: mock_badge, template: mock_template });
        await page.reload();
        await page.waitForLoadState('domcontentloaded');
        await page.waitForSelector('.event_badge_wrapper', { timeout: 8000 });
        await page.emulateMedia({ media: 'print' });

        const styles = await page.evaluate(() => {
            const el = document.querySelector('.event_badge_wrapper') as HTMLElement | null;
            if (!el) return null;
            const cs = getComputedStyle(el);
            return {
                position:  cs.position,
                transform: cs.transform,
            };
        });
        expect(styles).not.toBeNull();
        // position:fixed — anchors to the @page content area in print, bypassing all ancestor
        // overflow/height constraints. This is intentional (see print layout architecture docs).
        expect(styles!.position, 'badge wrapper should be fixed in print').toBe('fixed');
        // transform should contain a matrix (translate(-50%,-50%) for centering)
        expect(styles!.transform, 'badge wrapper should have a transform applied').not.toBe('none');
    });
});
