import {expect, test} from '@playwright/test';
import {globalDataRequests} from '../../utils/acceptance';
import {limitRequests, mockApi, responseFixtures} from '@tryghost/admin-x-framework/test/acceptance';

test.describe('Theme settings', async () => {
    test('Browsing and installing default themes', async ({page}) => {
        const {lastApiRequests} = await mockApi({page, requests: {
            ...globalDataRequests,
            browseThemes: {method: 'GET', path: '/themes/', response: responseFixtures.themes},
            installTheme: {method: 'POST', path: /^\/themes\/install\/\?/, response: {
                themes: [{
                    name: 'headline',
                    package: {},
                    active: false,
                    templates: []
                }]
            }},
            activateTheme: {method: 'PUT', path: '/themes/headline/activate/', response: {
                themes: [{
                    name: 'headline',
                    package: {},
                    active: true,
                    templates: []
                }]
            }}
        }});

        await page.goto('/');

        const designSection = page.getByTestId('design');

        await designSection.getByRole('button', {name: 'Customize'}).click();

        const designModal = page.getByTestId('design-modal');

        await designModal.getByTestId('change-theme').click();

        const modal = page.getByTestId('theme-modal');

        // The default theme is always considered "installed"

        await modal.getByRole('button', {name: /Casper/}).click();

        await expect(modal.getByRole('button', {name: 'Activate Casper'})).toBeVisible();

        await expect(page.locator('iframe[title="Theme preview"]')).toHaveAttribute('src', 'https://demo.ghost.io/');

        await modal.getByRole('button', {name: 'Change theme'}).click();

        // Try installing another theme

        await modal.getByRole('button', {name: /Headline/}).click();

        await modal.getByRole('button', {name: 'Install Headline'}).click();

        await expect(page.getByTestId('confirmation-modal')).toHaveText(/successfully installed/);

        await page.getByRole('button', {name: 'Activate'}).click();

        await expect(page.getByTestId('toast-success')).toHaveText(/headline is now your active theme/);

        expect(lastApiRequests.installTheme?.url).toMatch(/\?source=github&ref=TryGhost%2FHeadline/);
    });

    test('Managing installed themes', async ({page}) => {
        const {lastApiRequests} = await mockApi({page, requests: {
            ...globalDataRequests,
            browseThemes: {method: 'GET', path: '/themes/', response: responseFixtures.themes},
            activateTheme: {method: 'PUT', path: '/themes/casper/activate/', response: {
                themes: [{
                    ...responseFixtures.themes.themes.find(theme => theme.name === 'casper')!,
                    active: true
                }]
            }},
            deleteTheme: {method: 'DELETE', path: '/themes/edition/', response: {}}
        }});

        await page.goto('/');

        const designSection = page.getByTestId('design');

        await designSection.getByRole('button', {name: 'Customize'}).click();

        const designModal = page.getByTestId('design-modal');

        await designModal.getByTestId('change-theme').click();

        const modal = page.getByTestId('theme-modal');

        await modal.getByRole('tab', {name: 'Installed'}).click();

        await expect(modal.getByTestId('theme-list-item')).toHaveCount(2);

        const casper = modal.getByTestId('theme-list-item').filter({hasText: /casper/});
        const edition = modal.getByTestId('theme-list-item').filter({hasText: /edition/});

        // Activate the inactive theme

        await expect(casper.getByRole('button', {name: 'Activate'})).toBeVisible();
        await expect(edition).toHaveText(/Active/);

        await casper.getByRole('button', {name: 'Activate'}).click();

        await expect(casper).toHaveText(/Active/);
        await expect(edition.getByRole('button', {name: 'Activate'})).toBeVisible();

        expect(lastApiRequests.activateTheme?.url).toMatch(/\/themes\/casper\/activate\//);

        // Download the active theme

        await casper.getByRole('button', {name: 'Menu'}).click();
        await page.getByTestId('popover-content').getByRole('button', {name: 'Download'}).click();

        await expect(page.locator('iframe#iframeDownload')).toHaveAttribute('src', /\/api\/admin\/themes\/casper\/download/);

        // Delete the inactive theme

        await edition.getByRole('button', {name: 'Menu'}).click();
        await page.getByTestId('popover-content').getByRole('button', {name: 'Delete'}).click();

        const confirmation = page.getByTestId('confirmation-modal');
        await confirmation.getByRole('button', {name: 'Delete'}).click();

        await expect(modal.getByTestId('theme-list-item')).toHaveCount(1);

        expect(lastApiRequests.deleteTheme?.url).toMatch(/\/themes\/edition\/$/);
    });

    test('Uploading a new theme', async ({page}) => {
        const {lastApiRequests} = await mockApi({page, requests: {
            ...globalDataRequests,
            browseThemes: {method: 'GET', path: '/themes/', response: responseFixtures.themes},
            uploadTheme: {method: 'POST', path: '/themes/upload/', response: {
                themes: [{
                    name: 'mytheme',
                    package: {},
                    active: false,
                    templates: []
                }]
            }}
        }});

        await page.goto('/');

        const designSection = page.getByTestId('design');

        await designSection.getByRole('button', {name: 'Customize'}).click();

        const designModal = page.getByTestId('design-modal');

        await designModal.getByTestId('change-theme').click();

        const modal = page.getByTestId('theme-modal');

        await modal.getByRole('button', {name: 'Upload theme'}).click();

        const fileChooserPromise = page.waitForEvent('filechooser');

        await page.getByTestId('confirmation-modal').locator('label[for=theme-upload]').click();

        const fileChooser = await fileChooserPromise;
        await fileChooser.setFiles(`${__dirname}/../../utils/responses/theme.zip`);

        await expect(page.getByTestId('confirmation-modal')).toHaveText(/successful/);

        await expect(modal.getByTestId('theme-list-item')).toHaveCount(3);

        expect(lastApiRequests.uploadTheme).toBeTruthy();
    });

    test('Limits uploading new themes', async ({page}) => {
        await mockApi({page, requests: {
            ...globalDataRequests,
            ...limitRequests,
            browseThemes: {method: 'GET', path: '/themes/', response: responseFixtures.themes},
            browseConfig: {
                ...globalDataRequests.browseConfig,
                response: {
                    config: {
                        ...responseFixtures.config.config,
                        hostSettings: {
                            limits: {
                                customThemes: {
                                    allowlist: ['casper'],
                                    error: 'Upgrade to enable custom themes'
                                }
                            }
                        }
                    }
                }
            }
        }});

        await page.goto('/');

        const designSection = page.getByTestId('design');

        await designSection.getByRole('button', {name: 'Customize'}).click();

        const designModal = page.getByTestId('design-modal');

        await designModal.getByTestId('change-theme').click();

        const modal = page.getByTestId('theme-modal');

        await modal.getByRole('button', {name: 'Upload theme'}).click();

        await expect(page.getByTestId('limit-modal')).toHaveText(/Upgrade to enable custom themes/);
    });
});
