const { test, expect } = require("@playwright/test");

async function gotoReadyPlay(page, seed = 42, draw3 = false) {
    const suffix = draw3 ? "&draw3=" : "";
    await page.goto(`/play?seed=${seed}${suffix}`);
    await page.waitForFunction(
        () =>
            typeof window.__FERROUS_DEBUG__ === "object" &&
            window.__FERROUS_DEBUG__.seed() !== null,
        null,
        { timeout: 30_000 }
    );
}

test("play loads and exposes debug bridge", async ({ page }) => {
    await gotoReadyPlay(page, 42);

    const seed = await page.evaluate(() => window.__FERROUS_DEBUG__.seed());
    expect(seed).toBe(42);

    const legalMoves = await page.evaluate(() => window.__FERROUS_DEBUG__.legalMoves());
    expect(Array.isArray(legalMoves)).toBeTruthy();
    expect(legalMoves.length).toBeGreaterThan(0);
});

test("play respects draw3 URL param", async ({ page }) => {
    await gotoReadyPlay(page, 77, true);

    const snap = await page.evaluate(() => window.__FERROUS_DEBUG__.snapshot());
    expect(snap).not.toBeNull();
    expect(snap.draw_mode).toBe("DrawThree");
});

test("play debug bridge apply and undo work", async ({ page }) => {
    await gotoReadyPlay(page, 42);

    const baseline = await page.evaluate(() => window.__FERROUS_DEBUG__.moveHistory().length);

    const applied = await page.evaluate(() => window.__FERROUS_DEBUG__.applyLegalMove(0));
    expect(applied?.ok).toBeTruthy();

    await expect
        .poll(() => page.evaluate(() => window.__FERROUS_DEBUG__.moveHistory().length))
        .toBe(baseline + 1);

    const undone = await page.evaluate(() => window.__FERROUS_DEBUG__.undo());
    expect(undone?.ok).toBeTruthy();

    await expect
        .poll(() => page.evaluate(() => window.__FERROUS_DEBUG__.moveHistory().length))
        .toBe(baseline);
});

test("play failure report contains replay diagnostics", async ({ page }) => {
    await gotoReadyPlay(page, 42);

    const report = await page.evaluate(() => window.__FERROUS_DEBUG__.failureReport());
    expect(report).not.toBeNull();
    expect(typeof report.seed).toBe("number");
    expect(Array.isArray(report.moveHistory)).toBeTruthy();
    expect(Array.isArray(report.legalMoves)).toBeTruthy();
    expect(report.currentState).toBeTruthy();
    expect(report.invariants).toBeTruthy();
});

test("play autonomous autoplay keeps invariants stable across seed batch", async ({ page }) => {
    test.setTimeout(120_000);
    const seeds = [0, 1, 2, 5, 13, 42, 77];

    for (const seed of seeds) {
        await gotoReadyPlay(page, seed);
        const run = await page.evaluate(() =>
            window.__FERROUS_DEBUG__.runAutoplay({
                maxSteps: 220,
                maxVisitsPerState: 2,
                policy: "loop_aware",
            })
        );
        expect(run.ok, `seed ${seed} failed: ${JSON.stringify(run)}`).toBeTruthy();
    }
});
