import { test, expect, Page } from '@playwright/test';
import {
    BASE_URL,
    ADMIN,
    AUDITOR,
    loginAs,
    registerAndLogin,
    ensureLiveRacingEnabled,
    createArena,
    createEventShowUrl,
    addRace,
    addHorses,
    offerSingleBetTypes,
    offerMultiBetTypeCombos,
    publishEvent,
    placeWizardBet,
    closeBetting,
    saveResult,
    adjustWalletAsAuditor,
} from '../helpers';

// WFBO event page ▸ "Puro" tab: for Pick 4 / 5 / 6 / WTA, the share of
// tickets still alive (hit every leg run so far) and the next-leg horses
// those tickets ride on.

async function dividendRowId(page: Page, label: RegExp): Promise<string> {
    const blocks = page.locator('[data-testid^="combo-bettype-"]');
    for (let i = 0; i < (await blocks.count()); i++) {
        const text = (await blocks.nth(i).locator('label.fw-semibold').first().textContent())
            ?.replace(/\s+/g, ' ').replace(/\s*\([\d-]+…\)\s*$/u, '').trim() ?? '';
        if (label.test(text)) {
            return (await blocks.nth(i).getAttribute('data-testid'))?.replace('combo-bettype-', '') ?? '';
        }
    }
    throw new Error(`no combination block for ${label}`);
}

test.describe('WFBO event — Puro tab', () => {
    test.setTimeout(240_000);

    test('shows the share of Pick 4 tickets still alive after each leg and the next-leg horses', async ({ page }) => {
        const players = [await registerAndLogin(page), await registerAndLogin(page)];
        await loginAs(page, AUDITOR.mobile, AUDITOR.password);
        for (const p of players) {
            await adjustWalletAsAuditor(page, p.mobile, '100', 'Puro e2e');
        }

        // Event: 4 races x 2 horses, Pick 4 over R1-R4, Win on R1 (sets R1's winner).
        await loginAs(page, ADMIN.mobile, ADMIN.password);
        await ensureLiveRacingEnabled(page);
        const arena = await createArena(page, 'Puro', { win: '10', pick_4: '2' });
        const { eventUrl, eventId } = await createEventShowUrl(page, arena);
        const races = [];
        for (let n = 1; n <= 4; n++) {
            races.push(await addRace(page, eventUrl, n));
        }
        const horses: string[][] = [];
        for (const race of races) {
            horses.push(await addHorses(page, race.raceUrl, 2));
        }
        const [r1, r2, r3, r4] = races.map(r => r.raceId);
        await offerSingleBetTypes(page, eventUrl, [{ key: 'win', raceId: r1 }]);
        await offerMultiBetTypeCombos(page, eventUrl, 'pick_4', [[r1, r2, r3, r4]]);
        await publishEvent(page, eventUrl);

        // Before any bet: the Pick 4 card is there, nothing counted.
        await page.goto(`${BASE_URL}${eventUrl}?tab=puro`);
        await expect(page.locator('[data-testid="tab-puro"]')).toHaveClass(/is-active/);
        const card = page.locator('[data-testid^="puro-card-"]');
        await expect(card).toHaveCount(1);
        await expect(card).toContainText('Pick 4 · R1–R4');
        await expect(card.locator('[data-testid^="puro-status-"]')).toHaveText('Not started');

        // Player A: #1 in every leg. Player B: #2 in R1, both horses boxed in R2.
        const picks = [
            { [r1]: [horses[0][0]], [r2]: [horses[1][0]], [r3]: [horses[2][0]], [r4]: [horses[3][0]] },
            { [r1]: [horses[0][1]], [r2]: [horses[1][0], horses[1][1]], [r3]: [horses[2][0]], [r4]: [horses[3][0]] },
        ];
        for (const [i, p] of players.entries()) {
            await loginAs(page, p.mobile, p.password);
            await placeWizardBet(page, { eventId, cardLabel: 'Pick 4', legs: picks[i] });
        }

        await loginAs(page, ADMIN.mobile, ADMIN.password);
        await page.goto(`${BASE_URL}${eventUrl}?tab=puro`);
        await expect(card.locator('[data-testid^="puro-headline-"]')).toContainText('100.0%');
        await expect(card.locator('[data-testid^="puro-headline-"]')).toContainText('2 of 2 tickets');
        await expect(card.locator('[data-testid^="puro-headline-"]')).toContainText('3 of 3 combos');

        // R1 won by #1: only player A's ticket is still puro.
        await closeBetting(page, races[0].raceUrl);
        await page.goto(`${BASE_URL}${races[0].raceUrl}`);
        const winId = await dividendRowId(page, /^Win$/);
        await saveResult(page, races[0].raceUrl, {
            combinations: { [winId]: [{ horseIds: [horses[0][0]], dividend: '20.00' }] },
        });

        await page.goto(`${BASE_URL}${eventUrl}?tab=puro`);
        await expect(card.locator('[data-testid^="puro-status-"]')).toHaveText('1 of 4 legs run');
        const headline = card.locator('[data-testid^="puro-headline-"]');
        await expect(headline).toContainText('50.0%');
        await expect(headline).toContainText('1 of 2 tickets');
        await expect(headline).toContainText('1 of 3 combos');

        const funnelRows = card.locator('[data-testid$="-row"][data-testid^="puro-funnel-"]');
        await expect(funnelRows).toHaveCount(1);
        await expect(funnelRows.first()).toContainText('After R1');
        await expect(funnelRows.first()).toContainText('#1 won');
        await expect(funnelRows.first()).toContainText('50.0%');

        // Next leg R2: the puro ticket rides horse #1.
        await expect(card).toContainText('Next leg R2');
        const nextRows = card.locator('[data-testid$="-row"][data-testid^="puro-next-"]');
        await expect(nextRows).toHaveCount(1);
        await expect(nextRows.first()).toContainText('#1');
        await expect(nextRows.first()).toContainText('100.0%');
        await nextRows.first().scrollIntoViewIfNeeded();
    });

    test('says so when the event offers no Pick-N or WTA', async ({ page }) => {
        await loginAs(page, ADMIN.mobile, ADMIN.password);
        await ensureLiveRacingEnabled(page);
        const arena = await createArena(page, 'PuroNone', { win: '10' });
        const { eventUrl } = await createEventShowUrl(page, arena);
        const race = await addRace(page, eventUrl, 1);
        await addHorses(page, race.raceUrl, 2);
        await offerSingleBetTypes(page, eventUrl, [{ key: 'win', raceId: race.raceId }]);

        await page.goto(`${BASE_URL}${eventUrl}?tab=puro`);
        await expect(page.locator('[data-testid="puro-empty"]')).toBeVisible();
    });
});
