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

const OVERRIDES_URL = `${BASE_URL}/wfbo/dividend-overrides`;
const NEW_URL       = `${BASE_URL}/wfbo/dividend-overrides/new`;
const OVERRIDES_IDX_RE = /\/wfbo\/dividend-overrides(\/?(\?.*)?$)/;

// Shared date for all tests — far future to avoid collisions with real data
const TEST_DATE = '2099-12-01';

async function fillDividends(page: Page, value = '10.00'): Promise<void> {
    const inputs = page.locator('[data-testid^="override-dividend-"]');
    const count = await inputs.count();
    for (let i = 0; i < count; i++) {
        await inputs.nth(i).fill(value);
    }
}

async function deleteAllOverridesForTestDate(page: Page): Promise<void> {
    await page.goto(OVERRIDES_URL);
    // Find and delete any override rows that show the test date
    const rows = page.locator('[data-testid^="override-row-"]');
    const count = await rows.count();
    for (let i = count - 1; i >= 0; i--) {
        const row = rows.nth(i);
        const dateCell = row.locator('td').first();
        const text = await dateCell.textContent();
        if (text?.includes('December 1, 2099')) {
            const deleteBtn = row.locator('[data-testid^="btn-delete-"]');
            page.once('dialog', dialog => dialog.accept());
            await deleteBtn.click();
            await page.waitForURL(OVERRIDES_IDX_RE);
        }
    }
}

test.describe('WFBO Dividend Overrides', () => {

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

    test.afterEach(async ({ page }) => {
        await deleteAllOverridesForTestDate(page);
    });

    // ── Index ─────────────────────────────────────────────────────────────────

    test('index page loads with title', async ({ page }) => {
        await page.goto(OVERRIDES_URL);

        await expect(page.locator('[data-testid="wfbo-page-title"]')).toHaveText('Dividend Overrides');
    });

    test('index shows empty state when no overrides', async ({ page }) => {
        await page.goto(OVERRIDES_URL);

        // May or may not have empty state depending on other data — just check page loads
        await expect(page.locator('[data-testid="btn-new-override"]')).toBeVisible();
    });

    test('new override button is visible', async ({ page }) => {
        await page.goto(OVERRIDES_URL);

        await expect(page.locator('[data-testid="btn-new-override"]')).toBeVisible();
    });

    // ── New form ──────────────────────────────────────────────────────────────

    test('new form page loads with date and time inputs', async ({ page }) => {
        await page.goto(NEW_URL);

        await expect(page.locator('[data-testid="input-override-date"]')).toBeVisible();
        await expect(page.locator('[data-testid="input-time-from"]')).toBeVisible();
        await expect(page.locator('[data-testid="input-time-to"]')).toBeVisible();
        await expect(page.locator('[data-testid="btn-save-override"]')).toBeVisible();
    });

    test('new form has 15 dividend inputs', async ({ page }) => {
        await page.goto(NEW_URL);

        const inputs = page.locator('[data-testid^="override-dividend-"]');
        await expect(inputs).toHaveCount(15);
    });

    // ── Create all-day override ───────────────────────────────────────────────

    test('can create all-day override and it appears in list as "All day"', async ({ page }) => {
        await page.goto(NEW_URL);

        await page.fill('[data-testid="input-override-date"]', TEST_DATE);
        // Leave time_from and time_to blank → all day
        await fillDividends(page);
        await page.click('[data-testid="btn-save-override"]');

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

        // Find the row for our test date and check "All day"
        const overridesTable = page.locator('[data-testid="overrides-table"]');
        await expect(overridesTable).toContainText('All day');
    });

    // ── Create time-specific override ─────────────────────────────────────────

    test('can create time-specific override and it shows time range in list', async ({ page }) => {
        await page.goto(NEW_URL);

        await page.fill('[data-testid="input-override-date"]', TEST_DATE);
        await page.fill('[data-testid="input-time-from"]', '09:00');
        await page.fill('[data-testid="input-time-to"]', '13:00');
        await fillDividends(page);
        await page.click('[data-testid="btn-save-override"]');

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

        const overridesTable = page.locator('[data-testid="overrides-table"]');
        await expect(overridesTable).toContainText('09:00');
        await expect(overridesTable).toContainText('13:00');
    });

    test('can create two overrides on same date with different time ranges', async ({ page }) => {
        // First override: morning
        await page.goto(NEW_URL);
        await page.fill('[data-testid="input-override-date"]', TEST_DATE);
        await page.fill('[data-testid="input-time-from"]', '08:00');
        await page.fill('[data-testid="input-time-to"]', '12:00');
        await fillDividends(page, '5.00');
        await page.click('[data-testid="btn-save-override"]');
        await expect(page.locator('[data-testid="flash-success"]')).toBeVisible();

        // Second override: afternoon
        await page.goto(NEW_URL);
        await page.fill('[data-testid="input-override-date"]', TEST_DATE);
        await page.fill('[data-testid="input-time-from"]', '13:00');
        await page.fill('[data-testid="input-time-to"]', '18:00');
        await fillDividends(page, '8.00');
        await page.click('[data-testid="btn-save-override"]');
        await expect(page.locator('[data-testid="flash-success"]')).toBeVisible();

        await page.waitForURL(OVERRIDES_IDX_RE);

        const table = page.locator('[data-testid="overrides-table"]');
        await expect(table).toContainText('08:00');
        await expect(table).toContainText('13:00');
    });

    // ── View page ─────────────────────────────────────────────────────────────

    test('view page shows "All day" for all-day override', async ({ page }) => {
        // Create all-day override
        await page.goto(NEW_URL);
        await page.fill('[data-testid="input-override-date"]', TEST_DATE);
        await fillDividends(page);
        await page.click('[data-testid="btn-save-override"]');
        await page.waitForURL(OVERRIDES_IDX_RE);

        // Click view on the new row
        const row = page.locator('[data-testid^="override-row-"]').last();
        await row.locator('[data-testid^="btn-view-"]').click();

        await expect(page.locator('.wfbo-card-desc')).toContainText('All day');
    });

    test('view page shows time range for time-specific override', async ({ page }) => {
        await page.goto(NEW_URL);
        await page.fill('[data-testid="input-override-date"]', TEST_DATE);
        await page.fill('[data-testid="input-time-from"]', '10:00');
        await page.fill('[data-testid="input-time-to"]', '16:00');
        await fillDividends(page);
        await page.click('[data-testid="btn-save-override"]');
        await page.waitForURL(OVERRIDES_IDX_RE);

        const row = page.locator('[data-testid^="override-row-"]').last();
        await row.locator('[data-testid^="btn-view-"]').click();

        await expect(page.locator('.wfbo-card-desc')).toContainText('10:00');
        await expect(page.locator('.wfbo-card-desc')).toContainText('16:00');
    });

    // ── Edit ──────────────────────────────────────────────────────────────────

    test('can edit time range of an existing override', async ({ page }) => {
        // Create initial override with time range
        await page.goto(NEW_URL);
        await page.fill('[data-testid="input-override-date"]', TEST_DATE);
        await page.fill('[data-testid="input-time-from"]', '08:00');
        await page.fill('[data-testid="input-time-to"]', '12:00');
        await fillDividends(page);
        await page.click('[data-testid="btn-save-override"]');
        await page.waitForURL(OVERRIDES_IDX_RE);

        // Edit the override
        const row = page.locator('[data-testid^="override-row-"]').last();
        await row.locator('[data-testid^="btn-edit-"]').click();

        // Update time range
        await page.fill('[data-testid="input-time-from"]', '09:00');
        await page.fill('[data-testid="input-time-to"]', '15:00');
        await fillDividends(page);
        await page.click('[data-testid="btn-save-override"]');

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

        await expect(page.locator('[data-testid="overrides-table"]')).toContainText('09:00');
        await expect(page.locator('[data-testid="overrides-table"]')).toContainText('15:00');
    });

    test('edit form pre-populates existing time values', async ({ page }) => {
        await page.goto(NEW_URL);
        await page.fill('[data-testid="input-override-date"]', TEST_DATE);
        await page.fill('[data-testid="input-time-from"]', '07:30');
        await page.fill('[data-testid="input-time-to"]', '11:45');
        await fillDividends(page);
        await page.click('[data-testid="btn-save-override"]');
        await page.waitForURL(OVERRIDES_IDX_RE);

        const row = page.locator('[data-testid^="override-row-"]').last();
        await row.locator('[data-testid^="btn-edit-"]').click();

        await expect(page.locator('[data-testid="input-time-from"]')).toHaveValue('07:30');
        await expect(page.locator('[data-testid="input-time-to"]')).toHaveValue('11:45');
    });

    // ── Validation ────────────────────────────────────────────────────────────

    test('shows error when only time_from is set', async ({ page }) => {
        await page.goto(NEW_URL);
        await page.fill('[data-testid="input-override-date"]', TEST_DATE);
        await page.fill('[data-testid="input-time-from"]', '09:00');
        await page.fill('[data-testid="input-time-to"]', '');
        await fillDividends(page);
        await page.click('[data-testid="btn-save-override"]');

        await expect(page.locator('[data-testid="flash-error"]')).toBeVisible();
    });

    test('shows error when only time_to is set', async ({ page }) => {
        await page.goto(NEW_URL);
        await page.fill('[data-testid="input-override-date"]', TEST_DATE);
        await page.fill('[data-testid="input-time-from"]', '');
        await page.fill('[data-testid="input-time-to"]', '13:00');
        await fillDividends(page);
        await page.click('[data-testid="btn-save-override"]');

        await expect(page.locator('[data-testid="flash-error"]')).toBeVisible();
    });

    test('shows error when time_to is before time_from', async ({ page }) => {
        await page.goto(NEW_URL);
        await page.fill('[data-testid="input-override-date"]', TEST_DATE);
        await page.fill('[data-testid="input-time-from"]', '14:00');
        await page.fill('[data-testid="input-time-to"]', '09:00');
        await fillDividends(page);
        await page.click('[data-testid="btn-save-override"]');

        await expect(page.locator('[data-testid="flash-error"]')).toBeVisible();
    });

    // ── Delete ────────────────────────────────────────────────────────────────

    test('can delete an override', async ({ page }) => {
        await page.goto(NEW_URL);
        await page.fill('[data-testid="input-override-date"]', TEST_DATE);
        await fillDividends(page);
        await page.click('[data-testid="btn-save-override"]');
        await page.waitForURL(OVERRIDES_IDX_RE);

        const row = page.locator('[data-testid^="override-row-"]').last();
        const rowId = await row.getAttribute('data-testid');

        page.once('dialog', dialog => dialog.accept());
        await row.locator('[data-testid^="btn-delete-"]').click();

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

        if (rowId) {
            await expect(page.locator(`[data-testid="${rowId}"]`)).not.toBeVisible();
        }
    });

    // ── Access control ────────────────────────────────────────────────────────

    test('non-admin cannot access dividend overrides page', async ({ page }) => {
        await loginAs(page, USER.mobile, USER.password);
        await page.goto(OVERRIDES_URL);

        await expect(page.locator('[data-testid="wfbo-sidebar"]')).not.toBeVisible();
    });

});
