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

test.describe('WFBO Loaders page — ADMIN access', () => {

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

    test('page loads with the loaders breakdown table and a Total row', async ({ page }) => {
        await page.goto(`${BASE_URL}/wfbo/loaders`);
        await expect(page.locator('[data-testid="wfbo-page-title"]')).toHaveText('Loaders');

        const table = page.locator('[data-testid="loaders-breakdown"]');
        await expect(table).toBeVisible();
        await expect(table).toContainText('Approved Deposits');
        await expect(table).toContainText('Avg Approval Time');
        await expect(page.locator('[data-testid="loaders-row-unassigned"]')).toContainText('Unassigned / Other');

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

    test('period filter pills are present and default to Today', async ({ page }) => {
        await page.goto(`${BASE_URL}/wfbo/loaders`);
        await expect(page.locator('[data-testid="period-this_month"]').first()).toBeVisible();
        await expect(page.locator('[data-testid="period-today"]')).toHaveClass(/is-active/);
    });

    test('the Loaders nav link is under the Finance group', async ({ page }) => {
        await page.goto(`${BASE_URL}/wfbo/loaders`);
        await expect(page.locator('[data-testid="wfbo-nav-loaders"]')).toBeVisible();
    });

    test('an admin assigned as a payment detail handler gets its own row, not folded into Unassigned', async ({ page }) => {
        const bankName = `Loaders Admin Test Bank ${Date.now()}`;
        const ref       = `TXN-LOADER-ADMIN-${Date.now()}`;

        await page.goto(`${BASE_URL}/wfbo/payment-details/new`);
        await page.fill('[data-testid="input-label"]', bankName);
        await page.fill('[data-testid="input-bank-name"]', bankName);
        await page.fill('[data-testid="input-account-name"]', 'Test Account');
        await page.fill('[data-testid="input-account-number"]', `${Date.now()}`.slice(-10));
        await page.selectOption('[data-testid="select-finance-handler"]', { label: 'Admin User (+10000000003)' });
        await page.click('[data-testid="btn-submit"]');
        await expect(page).toHaveURL(`${BASE_URL}/wfbo/payment-details`);

        await loginAs(page, USER.mobile, USER.password);
        await page.goto(`${BASE_URL}/deposit`);
        const bankOption = page.locator('[data-testid="select-payment-detail"] option', { hasText: bankName });
        if (await bankOption.count() === 0) {
            test.skip();
            return;
        }
        const bankValue = await bankOption.getAttribute('value');
        await page.selectOption('[data-testid="select-payment-detail"]', bankValue!);
        await page.fill('[data-testid="input-amount"]', '250.00');
        await page.fill('[data-testid="input-transaction-reference"]', ref);
        await page.click('[data-testid="btn-deposit-submit"]');
        await expect(page.locator('[data-testid="flash-success"]')).toBeVisible();

        await loginAs(page, ADMIN.mobile, ADMIN.password);
        await page.goto(`${BASE_URL}/wfbo/deposits?status=pending`);
        const row = page.locator('[data-testid^="deposit-row-"]').filter({ hasText: ref });
        await expect(row).toBeVisible();
        const id = (await row.getAttribute('data-testid'))!.replace('deposit-row-', '');
        page.once('dialog', dialog => dialog.accept());
        await page.click(`[data-testid="btn-approve-${id}"]`);
        await expect(page.locator(`[data-testid="btn-approve-${id}"]`)).not.toBeAttached({ timeout: 10000 });

        await page.goto(`${BASE_URL}/wfbo/loaders?period=today`);
        const adminRow = page.locator('[data-testid^="loaders-row-"]:not([data-testid="loaders-row-unassigned"]):not([data-testid="loaders-row-total"])')
            .filter({ hasText: 'Admin User' });
        await expect(adminRow).toBeVisible();
        await expect(adminRow).toContainText('₱250.00');

        // Approved during business hours (10am-10pm PHT), so an avg approval
        // time should now be shown for this handler instead of "—".
        const avgCell = adminRow.locator('td[data-testid$="-avg-approval"]');
        const hour = new Date().getHours();
        if (hour >= 10 && hour < 22) {
            await expect(avgCell).not.toHaveText('—');
        }
    });

    test('a finance user with no assigned payment detail does not appear on the page', async ({ page }) => {
        await page.goto(`${BASE_URL}/wfbo/loaders`);
        const rowBefore = page.locator('[data-testid^="loaders-row-"]:not([data-testid="loaders-row-unassigned"]):not([data-testid="loaders-row-total"])')
            .filter({ hasText: 'Finance2 User' });
        if (await rowBefore.count() > 0) {
            // Another spec already assigned Finance2 a payment detail in this
            // run - can't cleanly assert absence for them here.
            test.skip();
            return;
        }
        await expect(rowBefore).toHaveCount(0);
    });

    test('the loaders total equals the sum of every row', async ({ page }) => {
        await page.goto(`${BASE_URL}/wfbo/loaders`);
        const peso = async (loc: ReturnType<typeof page.locator>) =>
            Number(((await loc.textContent()) ?? '').replace(/[^0-9.-]/g, '') || '0');

        const rowCells = page.locator('[data-testid^="loaders-row-"]:not([data-testid="loaders-row-total"]) td:nth-child(2)');
        let sum = 0;
        for (let i = 0; i < await rowCells.count(); i++) sum += await peso(rowCells.nth(i));

        const total = await peso(page.locator('[data-testid="loaders-row-total"] td:nth-child(2)'));
        expect(Math.round(total * 100)).toBe(Math.round(sum * 100));
    });

});

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

    test('a FINANCE user has no Loaders nav link and 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-deposits"]')).toBeVisible();
        await expect(page.locator('[data-testid="wfbo-nav-loaders"]')).toHaveCount(0);

        await page.goto(`${BASE_URL}/wfbo/loaders`);
        await expect(page.locator('[data-testid="loaders-breakdown"]')).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/loaders`);
        await expect(page.locator('[data-testid="loaders-breakdown"]')).not.toBeVisible();
    });

});
