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

test.describe('Agent Portal — Role Guard', () => {

    test('non-agent USER cannot access agent dashboard (title not visible)', async ({ page }) => {
        await loginAs(page, USER.mobile, USER.password);
        await page.goto(`${BASE_URL}/agent/dashboard`);
        await expect(page.locator('[data-testid="agent-dashboard-title"]')).not.toBeVisible();
    });

    test('non-agent USER cannot access agent transactions page', async ({ page }) => {
        await loginAs(page, USER.mobile, USER.password);
        await page.goto(`${BASE_URL}/agent/transactions`);
        await expect(page.locator('[data-testid="agent-tx-title"]')).not.toBeVisible();
    });

});

test.describe('Agent Portal — Transactions', () => {

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

    test('agent transactions page loads with title', async ({ page }) => {
        await page.goto(`${BASE_URL}/agent/transactions`);
        await expect(page.locator('[data-testid="agent-tx-title"]')).toBeVisible();
    });

    test('agent transactions page shows search form and table', async ({ page }) => {
        await page.goto(`${BASE_URL}/agent/transactions`);
        await expect(page.locator('[data-testid="agent-tx-search-form"]')).toBeVisible();
        await expect(page.locator('[data-testid="agent-tx-table"]')).toBeVisible();
    });

    test('agent transaction search submits and reloads the page', async ({ page }) => {
        await page.goto(`${BASE_URL}/agent/transactions`);
        await page.fill('[data-testid="agent-tx-search-input"]', 'test');
        await page.click('[data-testid="agent-tx-search-btn"]');
        await expect(page).toHaveURL(/search=test/);
    });

});

test.describe('Agent Portal — Users / Referrals', () => {

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

    test('agent users page loads with title', async ({ page }) => {
        await page.goto(`${BASE_URL}/agent/users`);
        await expect(page.locator('[data-testid="agent-users-title"]')).toBeVisible();
    });

    test('agent users page shows table', async ({ page }) => {
        await page.goto(`${BASE_URL}/agent/users`);
        await expect(page.locator('[data-testid="agent-users-table"]')).toBeVisible();
    });

    test('agent users search form is present', async ({ page }) => {
        await page.goto(`${BASE_URL}/agent/users`);
        await expect(page.locator('[data-testid="agent-users-search-form"]')).toBeVisible();
    });

});

test.describe('Agent Portal — Withdrawal', () => {

    test('agent withdrawal page loads with title and allowed-days info', async ({ page }) => {
        await loginAs(page, AGENT.mobile, AGENT.password);
        await page.goto(`${BASE_URL}/agent/withdrawal`);
        await expect(page.locator('[data-testid="agent-withdrawal-page-title"]')).toBeVisible();
        await expect(page.locator('[data-testid="allowed-days-info"]')).toBeVisible();
    });

    test('agent withdrawal page renders title and shows history table when data exists', async ({ page }) => {
        await loginAs(page, AGENT.mobile, AGENT.password);
        await page.goto(`${BASE_URL}/agent/withdrawal`);
        await expect(page.locator('[data-testid="agent-withdrawal-page-title"]')).toBeVisible();
        // History table is only rendered when past withdrawals exist or withdrawal is allowed today
        const table = page.locator('[data-testid="agent-withdrawal-history-table"]');
        if (await table.count() > 0) {
            await expect(table).toBeVisible();
        }
    });

    test('agent schedule gates the withdrawal form by day', async ({ page }) => {
        const manilaDay = ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat']
            .indexOf(new Intl.DateTimeFormat('en-US', { timeZone: 'Asia/Manila', weekday: 'short' }).format(new Date()));

        const setAgentDay = async (day: number | null) => {
            await loginAs(page, ADMIN.mobile, ADMIN.password);
            await page.goto(`${BASE_URL}/wfbo/settings`);
            for (let d = 0; d <= 6; d++) {
                const cb = page.locator(`[data-testid="input-agent-withdrawal-day-${d}-enabled"]`);
                if (d === day) {
                    await cb.check();
                } else {
                    await cb.uncheck();
                }
            }
            await page.click('[data-testid="btn-save-settings"]');
            await expect(page.locator('[data-testid="flash-success"]')).toBeVisible();
        };

        // Today open -> form shows.
        await setAgentDay(manilaDay);
        await loginAs(page, AGENT.mobile, AGENT.password);
        await page.goto(`${BASE_URL}/agent/withdrawal`);
        await expect(page.locator('[data-testid="agent-withdrawal-form"]')).toBeVisible();
        await expect(page.locator('[data-testid="agent-withdrawal-schedule-table"]')).toHaveCount(0);

        // Bank / E-Wallet Name is a dropdown with the fixed options.
        const bankSelect = page.locator('[data-testid="input-withdrawal-bank-name"]');
        await expect(bankSelect).toHaveJSProperty('tagName', 'SELECT');
        expect((await bankSelect.locator('option').allInnerTexts()).map(o => o.trim())).toEqual(
            expect.arrayContaining(['GCASH', 'MAYA', 'GOTYME', 'BPI', 'BDO', 'UNION BANK', 'METRO BANK', 'OTHERS']),
        );

        // Only tomorrow open -> unavailable card.
        await setAgentDay((manilaDay + 1) % 7);
        await loginAs(page, AGENT.mobile, AGENT.password);
        await page.goto(`${BASE_URL}/agent/withdrawal`);
        await expect(page.locator('[data-testid="withdrawal-unavailable-card"]')).toBeVisible();
        await expect(page.locator('[data-testid="agent-withdrawal-form"]')).toHaveCount(0);

        // Restore: disable agent withdrawals entirely.
        await setAgentDay(null);
    });

});

test.describe('Agent Portal — Agents List (ROLE_MASTER_AGENT)', () => {

    test('master agent can view /agent/agents page', async ({ page }) => {
        await loginAs(page, AGENT.mobile, AGENT.password);
        await page.goto(`${BASE_URL}/agent/agents`);
        await expect(page.locator('[data-testid="agent-agents-title"]')).toBeVisible();
    });

    test('agents table is present', async ({ page }) => {
        await loginAs(page, AGENT.mobile, AGENT.password);
        await page.goto(`${BASE_URL}/agent/agents`);
        await expect(page.locator('[data-testid="agent-agents-table"]')).toBeVisible();
    });

});

test.describe('Agent Portal — Promote User', () => {

    test('master agent can promote a referred user to agent via modal', async ({ page }) => {
        await loginAs(page, AGENT.mobile, AGENT.password);
        await page.goto(`${BASE_URL}/agent/users`);

        const promoteBtn = page.locator('[data-testid^="btn-promote-agent-"]').first();
        if (await promoteBtn.count() === 0) {
            test.skip(true, 'No promotable users in fixture state');
            return;
        }
        await promoteBtn.click();

        const modal = page.locator('[data-testid="promote-agent-modal"]');
        await expect(modal).toHaveCSS('display', 'flex');
        await page.fill('[data-testid="input-promote-commission-rate"]', '30');
        await page.click('[data-testid="btn-confirm-promote"]');
        await expect(page.locator('[data-testid="flash-success"]')).toBeVisible();
    });

});

test.describe('Agent Portal — Edit Commission', () => {

    test('master agent can edit a sub-agent commission rate', async ({ page }) => {
        await loginAs(page, AGENT.mobile, AGENT.password);
        await page.goto(`${BASE_URL}/agent/agents`);

        const editBtn = page.locator('button', { hasText: 'Edit Commission' }).first();
        if (await editBtn.count() === 0) {
            test.skip(true, 'No sub-agents in fixture state');
            return;
        }
        await editBtn.click();

        const modal = page.locator('#edit-commission-modal');
        await expect(modal).toHaveCSS('display', 'flex');

        const rateInput = page.locator('#edit-commission-rate');
        await rateInput.fill('25');
        await page.locator('#edit-commission-form button[type="submit"]').click();
        await expect(page.locator('[data-testid="flash-success"]')).toBeVisible();
    });

});


