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

const TEST_IMAGE = path.join(__dirname, '..', 'fixtures', 'test-banner.png');

test.describe('WFBO Site Banners', () => {

    test.describe('access control', () => {

        test('admin can access site banners page', async ({ page }) => {
            await loginAs(page, ADMIN.mobile, ADMIN.password);
            await page.goto(`${BASE_URL}/wfbo/site-banners`);

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

        test('finance-only user cannot access WFBO site banners', async ({ page }) => {
            await loginAs(page, FINANCE.mobile, FINANCE.password);
            await page.goto(`${BASE_URL}/wfbo/site-banners`);

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

        test('regular user cannot access WFBO site banners', async ({ page }) => {
            await loginAs(page, USER.mobile, USER.password);
            await page.goto(`${BASE_URL}/wfbo/site-banners`);

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

        test('agent cannot access WFBO site banners', async ({ page }) => {
            await loginAs(page, AGENT.mobile, AGENT.password);
            await page.goto(`${BASE_URL}/wfbo/site-banners`);

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

        test('unauthenticated user is redirected away from site banners', async ({ page }) => {
            await page.context().clearCookies();
            await page.goto(`${BASE_URL}/wfbo/site-banners`);

            expect(page.url()).not.toContain('/wfbo/site-banners');
        });

    });

    test.describe('CRUD as admin', () => {

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

        test('site banners page loads with Add New button', async ({ page }) => {
            await page.goto(`${BASE_URL}/wfbo/site-banners`);

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

        test('new site banner form loads', async ({ page }) => {
            await page.goto(`${BASE_URL}/wfbo/site-banners/new`);

            await expect(page.locator('[data-testid="site-banner-form"]')).toBeVisible();
            await expect(page.locator('[data-testid="input-title"]')).toBeVisible();
            await expect(page.locator('[data-testid="input-image"]')).toBeVisible();
            await expect(page.locator('[data-testid="input-link-url"]')).toBeVisible();
            await expect(page.locator('[data-testid="input-sort-order"]')).toBeVisible();
            await expect(page.locator('[data-testid="btn-submit"]')).toBeVisible();
        });

        test('can create a new site banner', async ({ page }) => {
            const title = `Test Banner ${Date.now()}`;

            await page.goto(`${BASE_URL}/wfbo/site-banners/new`);
            await page.fill('[data-testid="input-title"]', title);
            await page.setInputFiles('[data-testid="input-image"]', TEST_IMAGE);
            await page.fill('[data-testid="input-link-url"]', 'https://example.com/promo');
            await page.fill('[data-testid="input-sort-order"]', '1');
            await page.click('[data-testid="btn-submit"]');

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

        test('submitting empty form shows errors', async ({ page }) => {
            await page.goto(`${BASE_URL}/wfbo/site-banners/new`);
            await page.click('[data-testid="btn-submit"]');

            await expect(page).toHaveURL(`${BASE_URL}/wfbo/site-banners/new`);
            await expect(page.locator('[data-testid="flash-error"]').first()).toBeVisible();
        });

        test('can edit an existing site banner', async ({ page }) => {
            const title = `Edit Test ${Date.now()}`;
            await page.goto(`${BASE_URL}/wfbo/site-banners/new`);
            await page.fill('[data-testid="input-title"]', title);
            await page.setInputFiles('[data-testid="input-image"]', TEST_IMAGE);
            await page.fill('[data-testid="input-sort-order"]', '0');
            await page.click('[data-testid="btn-submit"]');

            await expect(page).toHaveURL(`${BASE_URL}/wfbo/site-banners`);

            const editBtn = page.locator('[data-testid^="btn-edit-"]').last();
            if (await editBtn.count() === 0) {
                test.skip();
                return;
            }

            await editBtn.click();
            await expect(page.locator('[data-testid="site-banner-form"]')).toBeVisible();

            await page.fill('[data-testid="input-title"]', `${title} Updated`);
            await page.click('[data-testid="btn-submit"]');

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

        test('can delete a site banner', async ({ page }) => {
            const title = `Delete Test ${Date.now()}`;
            await page.goto(`${BASE_URL}/wfbo/site-banners/new`);
            await page.fill('[data-testid="input-title"]', title);
            await page.setInputFiles('[data-testid="input-image"]', TEST_IMAGE);
            await page.fill('[data-testid="input-sort-order"]', '0');
            await page.click('[data-testid="btn-submit"]');

            await expect(page).toHaveURL(`${BASE_URL}/wfbo/site-banners`);

            const deleteBtn = page.locator('[data-testid^="btn-delete-"]').last();
            if (await deleteBtn.count() === 0) {
                test.skip();
                return;
            }

            page.once('dialog', dialog => dialog.accept());
            await deleteBtn.click();

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

        test('can disable and re-enable a site banner', async ({ page }) => {
            const title = `Toggle Test ${Date.now()}`;
            await page.goto(`${BASE_URL}/wfbo/site-banners/new`);
            await page.fill('[data-testid="input-title"]', title);
            await page.setInputFiles('[data-testid="input-image"]', TEST_IMAGE);
            await page.fill('[data-testid="input-sort-order"]', '0');
            await page.click('[data-testid="btn-submit"]');

            await expect(page).toHaveURL(`${BASE_URL}/wfbo/site-banners`);

            const toggleBtn = page.locator('[data-testid^="btn-toggle-"]').last();
            if (await toggleBtn.count() === 0) {
                test.skip();
                return;
            }

            page.on('dialog', dialog => dialog.accept());
            await toggleBtn.click();
            await expect(page.locator('[data-testid="flash-success"]')).toBeVisible();
        });

        test('WFBO sidebar has site banners nav link', async ({ page }) => {
            await page.goto(`${BASE_URL}/wfbo/site-banners`);

            await expect(page.locator('[data-testid="wfbo-nav-site-banners"]')).toBeVisible();
        });

    });

    test.describe('public homepage display', () => {

        test('enabled site banner appears on the homepage', async ({ page }) => {
            await loginAs(page, ADMIN.mobile, ADMIN.password);

            const title = `Homepage Banner ${Date.now()}`;
            await page.goto(`${BASE_URL}/wfbo/site-banners/new`);
            await page.fill('[data-testid="input-title"]', title);
            await page.setInputFiles('[data-testid="input-image"]', TEST_IMAGE);
            await page.fill('[data-testid="input-sort-order"]', '0');
            await page.click('[data-testid="btn-submit"]');
            await expect(page.locator('[data-testid="flash-success"]')).toBeVisible();

            await page.goto(`${BASE_URL}/`);
            await expect(page.locator(`img[alt="${title}"]`)).toBeVisible();
        });

        test('prev/next arrows navigate between multiple banners', async ({ page }) => {
            await loginAs(page, ADMIN.mobile, ADMIN.password);

            // Ensure there are at least 2 enabled banners regardless of what earlier
            // tests in this file already created.
            await page.goto(`${BASE_URL}/wfbo/site-banners/new`);
            await page.fill('[data-testid="input-title"]', `Slider Banner ${Date.now()}`);
            await page.setInputFiles('[data-testid="input-image"]', TEST_IMAGE);
            await page.fill('[data-testid="input-sort-order"]', '999');
            await page.click('[data-testid="btn-submit"]');
            await expect(page.locator('[data-testid="flash-success"]')).toBeVisible();

            await page.goto(`${BASE_URL}/`);
            const track = page.locator('[data-site-banner-slider-target="track"]');
            const dots = page.locator('[data-testid^="site-banner-dot-"]');

            const dotCount = await dots.count();
            if (dotCount < 2) {
                test.skip();
                return;
            }

            const activeDotIndex = async () => {
                const classes = await dots.evaluateAll((els) => els.map((el) => el.className));
                return classes.findIndex((c) => c.includes('is-active'));
            };

            const initialActive = await activeDotIndex();
            const initialScrollLeft = await track.evaluate((el) => el.scrollLeft);

            await page.click('[data-testid="site-banner-next"]');
            await expect.poll(activeDotIndex).not.toBe(initialActive);
            await expect.poll(() => track.evaluate((el) => el.scrollLeft)).not.toBe(initialScrollLeft);

            await page.click('[data-testid="site-banner-prev"]');
            await expect.poll(activeDotIndex).toBe(initialActive);
        });

    });

});
