import React from 'react';
import { render, screen } from '@testing-library/react';
import { MemoryRouter } from 'react-router-dom';
import { beforeEach, describe, expect, it, vi } from 'vitest';

const state = vi.hoisted(() => ({ items: [] as any[], appLoadError: null as Error | null }));
vi.mock('react-router-dom', async () => await import('@nexuscrm/test-real-router'));
vi.mock('@nexuscrm/host-sdk', () => ({
    useApp: () => ({
        currentAppId: 'chosen', currentFrontendAppId: 'crm', appLoadError: state.appLoadError, refreshApps: async () => [],
        currentApp: { id: 'chosen', navigationItems: state.items },
        visibleApps: [{ id: 'other', navigationItems: [{ id: 'other-home', type: 'page', label: 'Other app home', pageUrl: '/' }] }],
    }),
    useSystemPermission: () => false,
    hostApps: { apps: { get: () => undefined } },
}));
vi.mock('../src/platform/core/navigation/appNavigationCapabilities', () => ({ tryBuildAppNavigationPath: () => undefined }));
vi.mock('../src/platform/core/navigation/setupPagePaths', () => ({ tryGetSetupBasePath: () => undefined, tryGetSetupCapabilityPagePath: () => undefined }));
vi.mock('../src/platform/core/constants/Routes', () => ({ ROUTES: { OBJECT: { LIST: (name: string) => `/object/${name}` } } }));
import { Sidebar } from '../src/platform/components/shell/Sidebar';

const mount = () => render(<MemoryRouter><Sidebar isSidebarCollapsed={false} setIsSidebarCollapsed={() => {}} mobileMenuOpen={false} setMobileMenuOpen={() => {}} /></MemoryRouter>);
beforeEach(() => { state.items = []; state.appLoadError = null; });

describe('current navigation targets', () => {
    it.each(['javascript:alert(1)', 'java\tscript:alert(1)', 'data:text/html,<script>alert(1)</script>'])('does not expose unsafe saved URL %j as a clickable sidebar link', href => {
        state.items = [
            { id: 'unsafe-web', type: 'web', label: 'Unsafe web', pageUrl: href },
            { id: 'unsafe-page', type: 'page', label: 'Unsafe page', pageUrl: href },
            { id: 'safe', type: 'web', label: 'Safe docs', pageUrl: '/help/docs?q=1#part' },
        ];
        mount();
        expect(screen.queryByRole('link', { name: 'Unsafe web' })).not.toBeInTheDocument();
        expect(screen.queryByRole('link', { name: 'Unsafe page' })).not.toBeInTheDocument();
        expect(screen.getByRole('link', { name: 'Safe docs' })).toHaveAttribute('href', '/help/docs?q=1#part');
    });
    it('never redirects an unavailable page or dashboard to Home', () => {
        state.items = [
            { id: 'retired', type: 'page', label: 'Retired page' },
            { id: 'dashboard', type: 'dashboard', dashboardId: 'gone', label: 'Unavailable dashboard' },
            { id: 'home', type: 'page', pageUrl: '/', label: 'Actual home' },
            { id: 'object', type: 'object', objectApiName: 'Account', label: 'Accounts' },
            { id: 'web', type: 'web', pageUrl: 'https://example.com/docs?q=1#section', label: 'Docs' },
        ];
        mount();
        expect(screen.queryByRole('link', { name: 'Retired page' })).not.toBeInTheDocument();
        expect(screen.queryByRole('link', { name: 'Unavailable dashboard' })).not.toBeInTheDocument();
        expect(screen.getByRole('link', { name: 'Actual home' })).toHaveAttribute('href', '/');
        expect(screen.getByRole('link', { name: 'Accounts' })).toHaveAttribute('href', '/object/Account');
        expect(screen.getByRole('link', { name: 'Docs' })).toHaveAttribute('href', 'https://example.com/docs?q=1#section');
    });

    it('hides a stale serving projection and exposes a retry when navigation is unavailable', () => {
        state.items = [{ id: 'stale', type: 'page', label: 'Stale menu', pageUrl: '/' }];
        state.appLoadError = new Error('Unavailable');
        mount();
        expect(screen.queryByRole('link', { name: 'Stale menu' })).not.toBeInTheDocument();
        expect(screen.getByRole('alert')).toHaveTextContent('Navigation is unavailable.');
        expect(screen.getByRole('button', { name: 'Retry navigation' })).toBeInTheDocument();
    });

    it('preserves an explicitly empty selected menu', () => {
        mount();
        expect(screen.queryAllByRole('link')).toHaveLength(0);
        expect(screen.queryByText('Other app home')).not.toBeInTheDocument();
    });
});
