import { test, expect } from '@playwright/test';
import { BASE_URL, ADMIN, AUDITOR, FINANCE, OPERATIONS, loginAs } from '../helpers';

test.describe('WFBO Expenses — AUDITOR access', () => {

    test.beforeEach(async ({ page }) => {
        await loginAs(page, AUDITOR.mobile, AUDITOR.password);
    });

    test('the list page loads with the seeded expenses and a Total row', async ({ page }) => {
        await page.goto(`${BASE_URL}/wfbo/expenses`);

        await expect(page.locator('[data-testid="wfbo-page-title"]')).toHaveText('Expenses');
        const table = page.locator('[data-testid="expenses-table"]');
        await expect(table).toBeVisible();
        await expect(table).toContainText('Internet bill');

        const totalRow = page.locator('[data-testid="expense-row-total"]');
        await expect(totalRow).toContainText('Total');
        await expect(totalRow).toContainText('₱');

        // Period pills present.
        await expect(page.locator('[data-testid="period-this_month"]').first()).toBeVisible();
    });

    test('a seeded expense with a receipt shows a view link', async ({ page }) => {
        await page.goto(`${BASE_URL}/wfbo/expenses`);
        const link = page.locator('[data-testid^="btn-view-receipt-"]').first();
        await expect(link).toBeVisible();
        await expect(link).toHaveAttribute('href', /^https:\/\/storage\.googleapis\.com\//);
    });

    test('record a new expense', async ({ page }) => {
        const description = `E2E test expense ${Date.now()}`;

        await page.goto(`${BASE_URL}/wfbo/expenses/new`);
        await expect(page.locator('[data-testid="expense-form"]')).toBeVisible();
        await page.fill('[data-testid="input-expense-date"]', new Date().toISOString().slice(0, 10));
        await page.fill('[data-testid="input-description"]', description);
        await page.fill('[data-testid="input-amount"]', '175.50');
        await page.click('[data-testid="btn-submit-expense"]');

        await expect(page).toHaveURL(`${BASE_URL}/wfbo/expenses`);
        await expect(page.locator('[data-testid="flash-success"]')).toBeVisible();
        await expect(page.locator('[data-testid="expenses-table"]')).toContainText(description);
    });

    test('edit an expense', async ({ page }) => {
        const description = `Edit target ${Date.now()}`;

        await page.goto(`${BASE_URL}/wfbo/expenses/new`);
        await page.fill('[data-testid="input-expense-date"]', new Date().toISOString().slice(0, 10));
        await page.fill('[data-testid="input-description"]', description);
        await page.fill('[data-testid="input-amount"]', '10.00');
        await page.click('[data-testid="btn-submit-expense"]');
        await expect(page).toHaveURL(`${BASE_URL}/wfbo/expenses`);

        const row = page.locator('[data-testid^="expense-row-"]').filter({ hasText: description });
        await row.locator('[data-testid^="btn-edit-"]').click();
        await expect(page.locator('[data-testid="expense-form"]')).toBeVisible();
        await page.fill('[data-testid="input-amount"]', '999.99');
        await page.click('[data-testid="btn-submit-expense"]');

        await expect(page.locator('[data-testid="flash-success"]')).toBeVisible();
        await expect(
            page.locator('[data-testid^="expense-row-"]').filter({ hasText: description }),
        ).toContainText('999.99');
    });

    test('delete an expense', async ({ page }) => {
        const description = `Delete target ${Date.now()}`;

        await page.goto(`${BASE_URL}/wfbo/expenses/new`);
        await page.fill('[data-testid="input-expense-date"]', new Date().toISOString().slice(0, 10));
        await page.fill('[data-testid="input-description"]', description);
        await page.fill('[data-testid="input-amount"]', '5.00');
        await page.click('[data-testid="btn-submit-expense"]');
        await expect(page).toHaveURL(`${BASE_URL}/wfbo/expenses`);

        const row = page.locator('[data-testid^="expense-row-"]').filter({ hasText: description });
        page.once('dialog', dialog => dialog.accept());
        await row.locator('[data-testid^="btn-delete-"]').click();

        await expect(page.locator('[data-testid="flash-success"]')).toBeVisible();
        await expect(
            page.locator('[data-testid^="expense-row-"]').filter({ hasText: description }),
        ).toHaveCount(0);
    });

    test('recorded expenses appear on the Finance ▸ Report page', async ({ page }) => {
        await page.goto(`${BASE_URL}/wfbo/cashflow?period=this_year`);

        const table = page.locator('[data-testid="expense-breakdown"]');
        await expect(table).toBeVisible();
        await expect(table).toContainText('Internet bill');
        await expect(page.locator('[data-testid="expense-report-row-total"]')).toContainText('₱');
    });

});

test.describe('WFBO Expenses — role guard', () => {

    test('a plain ADMIN has no Expenses nav link and is blocked from the page', async ({ page }) => {
        await loginAs(page, ADMIN.mobile, ADMIN.password);

        await page.goto(`${BASE_URL}/wfbo/deposits`);
        await expect(page.locator('[data-testid="wfbo-nav-deposits"]')).toBeVisible();
        await expect(page.locator('[data-testid="wfbo-nav-expenses"]')).toHaveCount(0);

        await page.goto(`${BASE_URL}/wfbo/expenses`);
        await expect(page.locator('[data-testid="expenses-table"]')).not.toBeVisible();
    });

    test('a FINANCE user is blocked from the page', async ({ page }) => {
        await loginAs(page, FINANCE.mobile, FINANCE.password);

        await page.goto(`${BASE_URL}/wfbo/deposits`);
        await expect(page.locator('[data-testid="wfbo-nav-expenses"]')).toHaveCount(0);

        await page.goto(`${BASE_URL}/wfbo/expenses`);
        await expect(page.locator('[data-testid="expenses-table"]')).not.toBeVisible();
    });

    test('an OPERATIONS user is blocked from the page', async ({ page }) => {
        await loginAs(page, OPERATIONS.mobile, OPERATIONS.password);
        await page.goto(`${BASE_URL}/wfbo/expenses`);
        await expect(page.locator('[data-testid="expenses-table"]')).not.toBeVisible();
    });

});
