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

test.describe('Withdrawal', () => {

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

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

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

    test('withdrawal link is visible in navbar user-menu dropdown', async ({ page }) => {
        await page.goto(`${BASE_URL}/`);
        await page.click('[data-testid="navbar-user-menu"]');
        const link = page.locator('[data-testid="nav-link-withdrawal"], [data-testid="nav-link-withdrawals"]');
        if (await link.count() > 0) {
            await expect(link.first()).toBeVisible();
        } else {
            // Link may be under a different testid — verify page is reachable directly
            await page.goto(`${BASE_URL}/withdrawal`);
            await expect(page.locator('[data-testid="withdrawal-page-title"]')).toBeVisible();
        }
    });

    test('submit with zero amount does not show flash success', async ({ page }) => {
        await page.goto(`${BASE_URL}/withdrawal`);
        const form = page.locator('[data-testid="withdrawal-form"]');
        if (await form.count() === 0) {
            test.skip();
            return;
        }
        // Fill required bank fields with any value
        const bankName = page.locator('input[name*="bank_name"], input[name*="bankName"]').first();
        if (await bankName.count() > 0) await bankName.fill('Test Bank');
        const accountName = page.locator('input[name*="account_name"], input[name*="accountName"]').first();
        if (await accountName.count() > 0) await accountName.fill('Test Account');
        const accountNum = page.locator('input[name*="account_number"], input[name*="accountNumber"]').first();
        if (await accountNum.count() > 0) await accountNum.fill('1234567890');
        const amountInput = page.locator('input[name*="amount"]').first();
        if (await amountInput.count() > 0) await amountInput.fill('0');
        await page.click('[data-testid="btn-withdrawal-submit"]');
        await expect(page.locator('[data-testid="flash-success"]')).not.toBeVisible();
    });

    test('if withdrawal is allowed today, submitting valid request creates Pending entry', async ({ page }) => {
        await page.goto(`${BASE_URL}/withdrawal`);
        const form = page.locator('[data-testid="withdrawal-form"]');
        if (await form.count() === 0) {
            test.skip();
            return;
        }
        // Check insufficient funds guard
        const balanceText = await page.locator('[data-testid="available-balance"]').textContent();
        const balance = parseFloat(balanceText?.replace(/[^\d.]/g, '') ?? '0');
        if (balance <= 0) {
            test.skip();
            return;
        }
        const minVal = await form.getAttribute('data-form-validate-min-value');
        const withdrawAmount = Math.max(parseFloat(minVal || '50'), 1);
        if (withdrawAmount > balance) {
            test.skip();
            return;
        }
        await page.fill('[data-testid="input-withdrawal-amount"]', String(withdrawAmount));
        await page.fill('[data-testid="input-withdrawal-bank-name"]', 'GCash');
        await page.fill('[data-testid="input-withdrawal-bank-account-name"]', 'Test User');
        await page.fill('[data-testid="input-withdrawal-bank-account-number"]', '09171234567');
        await page.click('[data-testid="btn-withdrawal-submit"]');
        await page.waitForLoadState('networkidle');
        await expect(page.locator('[data-testid="flash-success"]')).toBeVisible();
        await expect(page.locator('[data-testid^="badge-withdrawal-"]').first()).toContainText('Pending');
    });

    test('if withdrawal is not allowed today, unavailable card is shown', async ({ page }) => {
        await page.goto(`${BASE_URL}/withdrawal`);
        const unavailable = page.locator('[data-testid="withdrawal-unavailable-card"]');
        if (await unavailable.count() > 0) {
            await expect(unavailable).toBeVisible();
            await expect(page.locator('[data-testid="next-allowed-day"]')).toBeVisible();
        } else {
            // Today is an allowed day — skip this assertion
            await expect(page.locator('[data-testid="withdrawal-form"]')).toBeVisible();
        }
    });

    test('agent can access /agent/withdrawal page', 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();
    });

    test('unauthenticated access redirects to /login', async ({ page }) => {
        await page.context().clearCookies();
        await page.goto(`${BASE_URL}/withdrawal`);
        expect(page.url()).toContain('/login');
    });

});

test.describe('Withdrawal — daily limit', () => {

    test('player sees danger flash when daily withdrawal limit is exceeded', async ({ page }) => {
        // Set a very low daily limit as admin
        await loginAs(page, ADMIN.mobile, ADMIN.password);
        await page.goto(`${BASE_URL}/wfbo/settings`);
        const limitInput = page.locator('[data-testid="input-max-daily-withdrawal-amount"]');
        const originalLimit = await limitInput.inputValue();
        await limitInput.fill('50');
        await page.click('[data-testid="btn-save-settings"]');
        await expect(page.locator('[data-testid="flash-success"]')).toBeVisible();

        // Switch to player and check they have enough balance
        await loginAs(page, USER.mobile, USER.password);
        await page.goto(`${BASE_URL}/withdrawal`);

        const form = page.locator('[data-testid="withdrawal-form"]');
        if (await form.count() === 0) {
            // Restore limit and skip — withdrawal not available today
            await loginAs(page, ADMIN.mobile, ADMIN.password);
            await page.goto(`${BASE_URL}/wfbo/settings`);
            await limitInput.fill(originalLimit || '');
            await page.click('[data-testid="btn-save-settings"]');
            test.skip();
            return;
        }

        const balanceText = await page.locator('[data-testid="available-balance"]').textContent();
        const balance = parseFloat(balanceText?.replace(/[^\d.]/g, '') ?? '0');
        if (balance < 100) {
            // Restore limit and skip — not enough balance to test
            await loginAs(page, ADMIN.mobile, ADMIN.password);
            await page.goto(`${BASE_URL}/wfbo/settings`);
            await page.locator('[data-testid="input-max-daily-withdrawal-amount"]').fill(originalLimit || '');
            await page.click('[data-testid="btn-save-settings"]');
            test.skip();
            return;
        }

        // Attempt a ₱100 withdrawal — exceeds the ₱50 limit
        await page.fill('[data-testid="input-withdrawal-amount"]', '100');
        await page.fill('[data-testid="input-withdrawal-bank-name"]', 'GCash');
        await page.fill('[data-testid="input-withdrawal-bank-account-name"]', 'Test User');
        await page.fill('[data-testid="input-withdrawal-bank-account-number"]', '09171234567');
        await page.click('[data-testid="btn-withdrawal-submit"]');
        await page.waitForLoadState('networkidle');

        await expect(page.locator('[data-testid="flash-danger"]')).toBeVisible();
        await expect(page.locator('[data-testid="flash-danger"]')).toContainText('Daily withdrawal limit reached');
        await expect(page.locator('[data-testid="flash-success"]')).not.toBeVisible();

        // Restore original limit
        await loginAs(page, ADMIN.mobile, ADMIN.password);
        await page.goto(`${BASE_URL}/wfbo/settings`);
        await page.locator('[data-testid="input-max-daily-withdrawal-amount"]').fill(originalLimit || '');
        await page.click('[data-testid="btn-save-settings"]');
        await expect(page.locator('[data-testid="flash-success"]')).toBeVisible();
    });

    test('player can withdraw normally when no daily limit is set', async ({ page }) => {
        // Ensure no limit is configured
        await loginAs(page, ADMIN.mobile, ADMIN.password);
        await page.goto(`${BASE_URL}/wfbo/settings`);
        const limitInput = page.locator('[data-testid="input-max-daily-withdrawal-amount"]');
        const originalLimit = await limitInput.inputValue();
        await limitInput.fill('');
        await page.click('[data-testid="btn-save-settings"]');
        await expect(page.locator('[data-testid="flash-success"]')).toBeVisible();

        // Switch to player
        await loginAs(page, USER.mobile, USER.password);
        await page.goto(`${BASE_URL}/withdrawal`);

        const form = page.locator('[data-testid="withdrawal-form"]');
        if (await form.count() === 0) {
            await loginAs(page, ADMIN.mobile, ADMIN.password);
            await page.goto(`${BASE_URL}/wfbo/settings`);
            await page.locator('[data-testid="input-max-daily-withdrawal-amount"]').fill(originalLimit || '');
            await page.click('[data-testid="btn-save-settings"]');
            test.skip();
            return;
        }

        const balanceText = await page.locator('[data-testid="available-balance"]').textContent();
        const balance = parseFloat(balanceText?.replace(/[^\d.]/g, '') ?? '0');
        const minVal = await form.getAttribute('data-form-validate-min-value');
        const withdrawAmount = Math.max(parseFloat(minVal || '50'), 1);
        if (withdrawAmount > balance) {
            await loginAs(page, ADMIN.mobile, ADMIN.password);
            await page.goto(`${BASE_URL}/wfbo/settings`);
            await page.locator('[data-testid="input-max-daily-withdrawal-amount"]').fill(originalLimit || '');
            await page.click('[data-testid="btn-save-settings"]');
            test.skip();
            return;
        }

        await page.fill('[data-testid="input-withdrawal-amount"]', String(withdrawAmount));
        await page.fill('[data-testid="input-withdrawal-bank-name"]', 'GCash');
        await page.fill('[data-testid="input-withdrawal-bank-account-name"]', 'Test User');
        await page.fill('[data-testid="input-withdrawal-bank-account-number"]', '09171234567');
        await page.click('[data-testid="btn-withdrawal-submit"]');
        await page.waitForLoadState('networkidle');

        await expect(page.locator('[data-testid="flash-danger"]')).not.toBeVisible();
        await expect(page.locator('[data-testid="flash-success"]')).toBeVisible();

        // Restore original limit
        await loginAs(page, ADMIN.mobile, ADMIN.password);
        await page.goto(`${BASE_URL}/wfbo/settings`);
        await page.locator('[data-testid="input-max-daily-withdrawal-amount"]').fill(originalLimit || '');
        await page.click('[data-testid="btn-save-settings"]');
        await expect(page.locator('[data-testid="flash-success"]')).toBeVisible();
    });

});
