import { test, expect, type Page } from './fixtures';

// E2E for the bot API token management page: list existing tokens, create one
// (the raw bearer is shown once), and revoke one.

const existing = {
    id: 't1111111-1111-1111-1111-111111111111',
    user_id: 'u1',
    name: 'existing-bot',
    created_at: '2026-01-01T00:00:00Z',
    last_used_at: null,
    expires_at: null
};

type Captured = { created: Record<string, unknown> | null; deleted: string | null };

async function mockTokens(page: Page, cap: Captured) {
    await page.route('**/api/v1/auth/config', (r) =>
        r.fulfill({
            status: 200,
            contentType: 'application/json',
            body: JSON.stringify({ self_register_enabled: true, private_mode: false })
        })
    );
    await page.route('**/api/v1/auth/me', (r) =>
        r.fulfill({
            status: 200,
            contentType: 'application/json',
            body: JSON.stringify({
                user: { id: 'u1', username: 'reader', created_at: '2026-01-01T00:00:00Z', is_admin: false }
            })
        })
    );
    await page.route('**/api/v1/auth/me/preferences', (r) =>
        r.fulfill({ status: 200, contentType: 'application/json', body: '{}' })
    );
    await page.route('**/api/v1/me/bookmarks*', (r) =>
        r.fulfill({
            status: 200,
            contentType: 'application/json',
            body: JSON.stringify({ items: [], page: { limit: 50, offset: 0, total: 0 } })
        })
    );

    // Specific id-scoped DELETE first (last-match-wins ordering).
    await page.route('**/api/v1/auth/tokens/*', async (r) => {
        cap.deleted = r.request().url().split('/').pop() ?? null;
        await r.fulfill({ status: 204, body: '' });
    });
    await page.route('**/api/v1/auth/tokens', async (r) => {
        if (r.request().method() === 'POST') {
            cap.created = r.request().postDataJSON();
            await r.fulfill({
                status: 201,
                contentType: 'application/json',
                body: JSON.stringify({
                    id: 't2',
                    user_id: 'u1',
                    name: cap.created?.name,
                    created_at: '2026-03-01T00:00:00Z',
                    last_used_at: null,
                    expires_at: null,
                    bearer: 'secret-raw-bearer-xyz'
                })
            });
            return;
        }
        await r.fulfill({
            status: 200,
            contentType: 'application/json',
            body: JSON.stringify({ items: [existing] })
        });
    });
}

test('lists, creates (shows the bearer once), and revokes tokens', async ({ page }) => {
    const cap: Captured = { created: null, deleted: null };
    await mockTokens(page, cap);
    await page.goto('/profile/tokens');

    // Existing token is listed.
    await expect(page.getByTestId(`token-row-${existing.id}`)).toContainText('existing-bot');

    // Create a token — the raw bearer is revealed exactly once.
    await page.getByTestId('token-name').fill('new-bot');
    await page.getByRole('button', { name: 'Create token' }).click();
    await expect(page.getByTestId('token-fresh')).toContainText('secret-raw-bearer-xyz');
    await expect.poll(() => cap.created).toEqual({ name: 'new-bot' });

    // Revoke the existing token (confirm dialog accepted).
    page.on('dialog', (d) => d.accept());
    await page.getByTestId(`token-revoke-${existing.id}`).click();
    await expect.poll(() => cap.deleted).toBe(existing.id);
});
