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

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

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

    test('deposit page loads with form and history table', async ({ page }) => {
        await page.goto(`${BASE_URL}/deposit`);

        await expect(page.locator('[data-testid="deposit-page-title"]')).toBeVisible();
        await expect(page.locator('[data-testid="deposit-form"]')).toBeVisible();
        await expect(page.locator('[data-testid="select-payment-detail"]')).toBeVisible();
        await expect(page.locator('[data-testid="input-amount"]')).toBeVisible();
        await expect(page.locator('[data-testid="btn-deposit-submit"]')).toBeVisible();
        await expect(page.locator('[data-testid="deposit-history-table"]')).toBeVisible();
    });

    test('bank dropdown is visible and lists available payment details', async ({ page }) => {
        await page.goto(`${BASE_URL}/deposit`);

        const select = page.locator('[data-testid="select-payment-detail"]');
        await expect(select).toBeVisible();

        const options = select.locator('option:not([value=""])');
        const count   = await options.count();
        if (count > 0) {
            // At least one selectable bank option exists
            await expect(options.first()).not.toBeEmpty();
        }
    });

    test('bank dropdown always includes an "Others" option', async ({ page }) => {
        await page.goto(`${BASE_URL}/deposit`);

        const options = page.locator('[data-testid="select-payment-detail"] option');
        await expect(options.last()).toHaveText(/Others/);
    });

    test('selecting "Others" reveals the inactive-bank dropdown', async ({ page }) => {
        await page.goto(`${BASE_URL}/deposit`);

        await expect(page.locator('[data-testid="select-payment-detail-other"]')).toBeHidden();

        await page.selectOption('[data-testid="select-payment-detail"]', 'others');

        await expect(page.locator('[data-testid="select-payment-detail-other"]')).toBeVisible();
    });

    test('switching away from "Others" hides the inactive-bank dropdown again', async ({ page }) => {
        await page.goto(`${BASE_URL}/deposit`);

        await page.selectOption('[data-testid="select-payment-detail"]', 'others');
        await expect(page.locator('[data-testid="select-payment-detail-other"]')).toBeVisible();

        const options = page.locator('[data-testid="select-payment-detail"] option:not([value=""]):not([value="others"])');
        if (await options.count() > 0) {
            await page.selectOption('[data-testid="select-payment-detail"]', { index: 1 });
        } else {
            await page.selectOption('[data-testid="select-payment-detail"]', { value: '' });
        }

        await expect(page.locator('[data-testid="select-payment-detail-other"]')).toBeHidden();
    });

    test('transaction image upload field is visible on deposit form', async ({ page }) => {
        await page.goto(`${BASE_URL}/deposit`);
        await expect(page.locator('[data-testid="input-transaction-image"]')).toBeVisible();
    });

    test('deposit form shows the "do not share your receipt" warning', async ({ page }) => {
        await page.goto(`${BASE_URL}/deposit`);
        const warning = page.locator('[data-testid="deposit-receipt-warning"]');
        await expect(warning).toBeVisible();
        await expect(warning).toContainText('Do Not Share Your Receipt');
        await expect(warning).toContainText('reference number');
    });

    test('deposit link is visible in navbar dropdown', async ({ page }) => {
        await page.click('[data-testid="navbar-user-menu"]');
        await expect(page.locator('[data-testid="nav-link-deposits"]')).toBeVisible();
    });

    test('submitting a valid deposit shows it as Pending', async ({ page }) => {
        await page.goto(`${BASE_URL}/deposit`);

        // "Others" is always present as a fallback choice - only a real, currently
        // enabled bank lets this test submit without also picking a second dropdown.
        const bankOptions = page.locator('[data-testid="select-payment-detail"] option:not([value=""]):not([value="others"])');
        if (await bankOptions.count() === 0) {
            test.skip();
            return;
        }
        await page.selectOption('[data-testid="select-payment-detail"]', { index: 1 });
        await page.fill('[data-testid="input-amount"]', '100.00');
        await page.fill('[data-testid="input-transaction-reference"]', `TXN-${Date.now()}`);
        await page.click('[data-testid="btn-deposit-submit"]');

        await expect(page).toHaveURL(`${BASE_URL}/deposit`);
        await expect(page.locator('[data-testid="flash-success"]')).toBeVisible();
        await expect(page.locator('[data-testid^="badge-status-"]').first()).toContainText('Pending');
    });

    test('amount of 0 shows validation error', async ({ page }) => {
        await page.goto(`${BASE_URL}/deposit`);
        await page.fill('[data-testid="input-amount"]', '0');
        await page.click('[data-testid="btn-deposit-submit"]');

        await expect(page).toHaveURL(`${BASE_URL}/deposit`);
        await expect(page.locator('[data-testid="flash-success"]')).not.toBeVisible();
    });

    test('empty amount shows validation error', async ({ page }) => {
        await page.goto(`${BASE_URL}/deposit`);
        await page.click('[data-testid="btn-deposit-submit"]');

        await expect(page).toHaveURL(`${BASE_URL}/deposit`);
        await expect(page.locator('[data-testid="flash-success"]')).not.toBeVisible();
    });

    test('unauthenticated access redirects away from deposit page', async ({ page }) => {
        await page.context().clearCookies();
        await page.goto(`${BASE_URL}/deposit`);

        expect(page.url()).not.toContain('/deposit');
    });

    test('payment details section is shown when payment details exist', async ({ page }) => {
        await page.goto(`${BASE_URL}/deposit`);

        // The section only renders when paymentDetails is not empty.
        // If it exists, verify structure; if not, the section is simply absent (no assert needed).
        const section = page.locator('[data-testid="deposit-payment-details"]');
        const count = await section.count();

        if (count > 0) {
            await expect(section).toBeVisible();
            // At least one payment detail card must exist inside the section
            await expect(section.locator('[data-testid^="payment-detail-"]').first()).toBeVisible();
        }
    });

    test('agent can access deposit page', async ({ page }) => {
        await loginAs(page, AGENT.mobile, AGENT.password);
        await page.goto(`${BASE_URL}/deposit`);

        await expect(page.locator('[data-testid="deposit-page-title"]')).toBeVisible();
        await expect(page.locator('[data-testid="deposit-form"]')).toBeVisible();
    });

    test('duplicate transaction reference shows validation error and blocks submission', async ({ page }) => {
        const ref = `TXN-DUP-${Date.now()}`;

        // First submission — should succeed
        await page.goto(`${BASE_URL}/deposit`);
        // "Others" is always present as a fallback choice - only a real, currently
        // enabled bank lets this test submit without also picking a second dropdown.
        const bankOptions = page.locator('[data-testid="select-payment-detail"] option:not([value=""]):not([value="others"])');
        if (await bankOptions.count() === 0) {
            test.skip();
            return;
        }
        await page.selectOption('[data-testid="select-payment-detail"]', { index: 1 });
        await page.fill('[data-testid="input-amount"]', '50.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();

        // Second submission with the same reference — should be blocked
        await page.goto(`${BASE_URL}/deposit`);
        await page.selectOption('[data-testid="select-payment-detail"]', { index: 1 });
        await page.fill('[data-testid="input-amount"]', '75.00');
        await page.fill('[data-testid="input-transaction-reference"]', ref);
        await page.click('[data-testid="btn-deposit-submit"]');

        await expect(page).toHaveURL(`${BASE_URL}/deposit`);
        await expect(page.locator('[data-testid="flash-success"]')).not.toBeVisible();
        await expect(page.locator('[data-testid="transaction-reference-errors"]')).toContainText('already been used');
    });

});
