import { jsx as _jsx } from "react/jsx-runtime";
// @vitest-environment happy-dom
import { beforeEach, describe, expect, it, vi } from 'vitest';
import { fireEvent, render, screen, waitFor, within } from '@testing-library/react';
// The SEO defaults tab reads four shared backends: /seo/config (meta defaults +
// verification), /seo/crawl-settings (sitemap toggles), /seo/sitemap/status
// (read-only summary), and /seo/index-status (environment).
const cmsApi = vi.fn(async (endpoint, options) => {
    const method = options?.method ?? 'GET';
    if (endpoint === '/seo/config' && method === 'GET') {
        return {
            data: {
                static: { site: null },
                overrides: { site: {} },
                effective: {
                    site: {
                        siteName: 'Acme',
                        siteUrl: 'https://acme.test',
                        titleTemplate: '%page% — %site%',
                        defaultMetaDescription: 'Seed description.',
                        verification: { googleSearchConsole: '', bingWebmasterTools: '' },
                    },
                },
                collections: [],
            },
            status: 200,
        };
    }
    if (endpoint === '/seo/crawl-settings' && method === 'GET') {
        return {
            data: {
                autoRegenerateSitemapOnPublish: true,
                pingSearchEnginesOnPublish: true,
                sitemapEnabled: true,
            },
            status: 200,
        };
    }
    if (endpoint === '/seo/sitemap/status' && method === 'GET') {
        return {
            data: {
                sitemapUrl: 'https://acme.test/sitemap.xml',
                lastGeneratedAt: '2026-01-02T03:04:05.000Z',
                pagesIncluded: 12,
                pagesExcluded: 1,
                warnings: [],
            },
            status: 200,
        };
    }
    if (endpoint === '/seo/index-status' && method === 'GET') {
        return { data: { environment: 'preview' }, status: 200 };
    }
    return { data: {}, status: 200 };
});
vi.mock('../../lib/api.js', () => ({
    cmsApi: (e, o) => cmsApi(e, o),
    ensureCsrfToken: vi.fn(async () => { }),
}));
// Stub the Media Center picker: when open, expose a button that selects a known
// asset (id + url), exercising the asset-id storage path without the real
// MediaBrowser/network stack.
vi.mock('../../components/MediaPickerModal.js', () => ({
    MediaPickerModal: ({ open, onSelect, onSelectItem, }) => open ? (_jsx("button", { type: "button", onClick: () => {
            onSelect('https://cdn.test/og.png');
            onSelectItem?.({ id: 'asset-123' });
        }, children: "pick-asset" })) : null,
}));
const { SeoSettingsTab } = await import('../../views/settings/SeoSettingsTab.js');
beforeEach(() => {
    cmsApi.mockClear();
});
describe('SeoSettingsTab', () => {
    it('renders the workspace callout and loads meta defaults from /seo/config', async () => {
        render(_jsx(SeoSettingsTab, { role: "ADMIN" }));
        expect(await screen.findByText('Looking for the full SEO workspace?')).toBeTruthy();
        expect(screen.getByLabelText('Title template').value).toBe('%page% — %site%');
        expect(screen.getByLabelText('Default meta description').value).toBe('Seed description.');
        // Clean form → Save disabled.
        expect(screen.getByRole('button', { name: 'Save Changes' }).disabled).toBe(true);
    });
    it('routes "Open SEO" to /seo', async () => {
        const onNavigate = vi.fn();
        render(_jsx(SeoSettingsTab, { role: "ADMIN", onNavigate: onNavigate }));
        await screen.findByText('Looking for the full SEO workspace?');
        fireEvent.click(screen.getByRole('button', { name: /Open SEO/ }));
        expect(onNavigate).toHaveBeenCalledWith('/seo');
    });
    it('rejects an unsupported title-template token and blocks save', async () => {
        render(_jsx(SeoSettingsTab, { role: "ADMIN" }));
        const tpl = (await screen.findByLabelText('Title template'));
        fireEvent.change(tpl, { target: { value: '%page% %bogus%' } });
        expect((await screen.findAllByText(/Unsupported token/i)).length).toBeGreaterThan(0);
        expect(screen.getByRole('button', { name: 'Save Changes' }).disabled).toBe(true);
    });
    it('shows a character count and warns when the description is too long', async () => {
        render(_jsx(SeoSettingsTab, { role: "ADMIN" }));
        const desc = (await screen.findByLabelText('Default meta description'));
        fireEvent.change(desc, { target: { value: 'x'.repeat(200) } });
        expect(screen.getByText('200/160')).toBeTruthy();
        expect((await screen.findAllByText(/truncate/i)).length).toBeGreaterThan(0);
    });
    it('persists meta defaults + verification to the shared /seo/config', async () => {
        render(_jsx(SeoSettingsTab, { role: "ADMIN" }));
        const google = (await screen.findByLabelText('Google Search Console'));
        fireEvent.change(google, { target: { value: 'goog-token' } });
        const save = screen.getByRole('button', { name: 'Save Changes' });
        expect(save.disabled).toBe(false);
        fireEvent.click(save);
        await waitFor(() => expect(cmsApi).toHaveBeenCalledWith('/seo/config', expect.objectContaining({ method: 'PUT' })));
        const putCall = cmsApi.mock.calls.find(([e, o]) => e === '/seo/config' && o?.method === 'PUT');
        const body = JSON.parse(putCall[1].body);
        expect(body.site.verification.googleSearchConsole).toBe('goog-token');
    });
    it('stores the selected social image asset id from the Media Center picker', async () => {
        render(_jsx(SeoSettingsTab, { role: "ADMIN" }));
        await screen.findByLabelText('Title template');
        fireEvent.click(screen.getByRole('button', { name: 'Choose image' }));
        fireEvent.click(screen.getByRole('button', { name: 'pick-asset' }));
        const save = screen.getByRole('button', { name: 'Save Changes' });
        expect(save.disabled).toBe(false);
        fireEvent.click(save);
        await waitFor(() => expect(cmsApi).toHaveBeenCalledWith('/seo/config', expect.objectContaining({ method: 'PUT' })));
        const putCall = cmsApi.mock.calls.find(([e, o]) => e === '/seo/config' && o?.method === 'PUT');
        const body = JSON.parse(putCall[1].body);
        expect(body.site.defaultSocialImageAssetId).toBe('asset-123');
        expect(body.site.defaultOgImage).toBe('https://cdn.test/og.png');
    });
    it('persists sitemap toggles to the shared /seo/crawl-settings', async () => {
        render(_jsx(SeoSettingsTab, { role: "ADMIN" }));
        await screen.findByLabelText('Title template');
        fireEvent.click(screen.getByRole('switch', { name: 'Ping search engines on publish' }));
        fireEvent.click(screen.getByRole('button', { name: 'Save Changes' }));
        await waitFor(() => expect(cmsApi).toHaveBeenCalledWith('/seo/crawl-settings', expect.objectContaining({ method: 'PUT' })));
    });
    it('shows the read-only sitemap summary', async () => {
        render(_jsx(SeoSettingsTab, { role: "ADMIN" }));
        await screen.findByLabelText('Title template');
        expect(screen.getByText('Included URLs')).toBeTruthy();
        expect(screen.getByText('12')).toBeTruthy();
        expect(screen.getByRole('link', { name: /View sitemap/ })).toBeTruthy();
    });
    it('is read-only for non-admins', async () => {
        render(_jsx(SeoSettingsTab, { role: "EDITOR" }));
        expect(await screen.findByText(/read-only access to SEO defaults/i)).toBeTruthy();
        // Scope to the Meta Defaults region: the advanced SEOConfigPanel disclosure
        // also mounts and can briefly produce overlapping label matches.
        const metaCard = screen.getByRole('region', { name: 'Meta Defaults' });
        expect(within(metaCard).getByLabelText('Title template').disabled).toBe(true);
    });
});
//# sourceMappingURL=seo-settings.render.test.js.map