/**
 * Tests for AppHeader Component
 * Verifies header rendering, project switcher integration, and responsive behavior
 */

import { render, screen } from '@testing-library/react';
import { AppHeader } from '@/components/layout/AppHeader';
import { useAuth } from '@/lib/auth/AuthContext';
import { useLogout } from '@/lib/api/hooks/useAuth';
import type { User } from '@/lib/stores/authStore';

// Mock dependencies
jest.mock('@/lib/auth/AuthContext', () => ({
  useAuth: jest.fn(),
  AuthProvider: ({ children }: { children: React.ReactNode }) => <>{children}</>,
}));

jest.mock('@/lib/api/hooks/useAuth', () => ({
  useLogout: jest.fn(),
}));

jest.mock('@/components/theme', () => ({
  ThemeToggle: () => <div data-testid="theme-toggle">Theme Toggle</div>,
}));

jest.mock('@/components/i18n', () => ({
  LocaleSwitcher: () => <div data-testid="locale-switcher">Locale Switcher</div>,
}));

// Helper to create mock user
function createMockUser(overrides: Partial<User> = {}): User {
  return {
    id: 'user-123',
    email: 'test@example.com',
    first_name: 'Test',
    last_name: 'User',
    phone_number: null,
    is_active: true,
    is_superuser: false,
    created_at: new Date().toISOString(),
    updated_at: null,
    ...overrides,
  };
}

describe('AppHeader', () => {
  const mockProjects = [
    { id: '1', slug: 'project-one', name: 'Project One' },
    { id: '2', slug: 'project-two', name: 'Project Two' },
  ];

  beforeEach(() => {
    jest.clearAllMocks();

    (useAuth as unknown as jest.Mock).mockReturnValue({
      user: createMockUser(),
    });

    (useLogout as jest.Mock).mockReturnValue({
      mutate: jest.fn(),
      isPending: false,
    });
  });

  describe('Rendering', () => {
    it('renders header element', () => {
      render(<AppHeader />);
      expect(screen.getByTestId('app-header')).toBeInTheDocument();
    });

    it('renders with sticky positioning', () => {
      render(<AppHeader />);

      const header = screen.getByTestId('app-header');
      expect(header).toHaveClass('sticky', 'top-0');
    });

    it('renders theme toggle', () => {
      render(<AppHeader />);
      expect(screen.getByTestId('theme-toggle')).toBeInTheDocument();
    });

    it('renders locale switcher', () => {
      render(<AppHeader />);
      // LocaleSwitcher renders a button with aria-label="switchLanguage"
      expect(screen.getByRole('button', { name: /switchLanguage/i })).toBeInTheDocument();
    });

    it('renders user menu', () => {
      render(<AppHeader />);
      expect(screen.getByTestId('user-menu-trigger')).toBeInTheDocument();
    });
  });

  describe('Logo', () => {
    it('renders logo on mobile', () => {
      render(<AppHeader />);

      const logoLink = screen.getByRole('link', { name: /syndarix home/i });
      expect(logoLink).toBeInTheDocument();
      expect(logoLink).toHaveAttribute('href', '/');
    });

    it('contains syndarix text', () => {
      render(<AppHeader />);

      expect(screen.getByText('Syndarix')).toBeInTheDocument();
    });
  });

  describe('Project Switcher', () => {
    it('renders project switcher when projects are provided', () => {
      render(<AppHeader projects={mockProjects} />);

      // Multiple switchers may render for desktop/mobile - just check at least one exists
      expect(screen.getAllByTestId('project-switcher-trigger').length).toBeGreaterThan(0);
    });

    it('does not render project switcher when no projects', () => {
      render(<AppHeader projects={[]} />);

      expect(screen.queryByTestId('project-switcher-trigger')).not.toBeInTheDocument();
    });

    it('displays current project name', () => {
      render(
        <AppHeader
          projects={mockProjects}
          currentProject={mockProjects[0]}
        />
      );

      // Multiple instances may show the project name
      expect(screen.getAllByText('Project One').length).toBeGreaterThan(0);
    });

    it('calls onProjectChange when project is changed', async () => {
      const mockOnChange = jest.fn();

      render(
        <AppHeader
          projects={mockProjects}
          onProjectChange={mockOnChange}
        />
      );

      // The actual test of project switching is in ProjectSwitcher.test.tsx
      // Here we just verify the prop is passed by checking switcher exists
      expect(screen.getAllByTestId('project-switcher-trigger').length).toBeGreaterThan(0);
    });
  });

  describe('Accessibility', () => {
    it('header has proper element type', () => {
      render(<AppHeader />);

      const header = screen.getByTestId('app-header');
      expect(header.tagName).toBe('HEADER');
    });

    it('logo link is accessible', () => {
      render(<AppHeader />);

      const logoLink = screen.getByRole('link', { name: /syndarix home/i });
      expect(logoLink).toBeInTheDocument();
    });
  });

  describe('Custom className', () => {
    it('applies custom className', () => {
      render(<AppHeader className="custom-class" />);

      const header = screen.getByTestId('app-header');
      expect(header).toHaveClass('custom-class');
    });
  });
});
