// src/components/Header.test.tsx
import React from 'react';
import { render, screen, fireEvent } from '@testing-library/react';
import { describe, it, expect, vi, beforeEach } from 'vitest';
import { MemoryRouter } from 'react-router-dom';
import { Header } from './Header';
import type { UserProfile } from '../types';
import { createMockUserProfile } from '../tests/utils/mockFactories';

// Unmock the component to test the real implementation
vi.unmock('./Header');

const mockUserProfile: UserProfile = createMockUserProfile({
  role: 'user',
  user: { user_id: 'user-123', email: 'test@example.com' },
});
const mockAdminProfile: UserProfile = createMockUserProfile({
  role: 'admin',
  user: { user_id: 'admin-123', email: 'admin@example.com' },
});

const mockOnOpenProfile = vi.fn();
const mockOnOpenVoiceAssistant = vi.fn();
const mockOnSignOut = vi.fn();

const defaultProps = {
  isDarkMode: false,
  unitSystem: 'imperial' as const,
  userProfile: null,
  authStatus: 'SIGNED_OUT' as const,
  onOpenProfile: mockOnOpenProfile,
  onOpenVoiceAssistant: mockOnOpenVoiceAssistant,
  onSignOut: mockOnSignOut,
};

// Helper to render with router context
const renderWithRouter = (props: Partial<React.ComponentProps<typeof Header>>) => {
  return render(
    <MemoryRouter>
      <Header {...defaultProps} {...props} />
    </MemoryRouter>,
  );
};

describe('Header', () => {
  beforeEach(() => {
    vi.clearAllMocks();
  });

  it('should render the application title', () => {
    renderWithRouter({});
    expect(screen.getByRole('heading', { name: /flyer crawler/i })).toBeInTheDocument();
  });

  it('should display unit system and theme mode', () => {
    renderWithRouter({ isDarkMode: true, unitSystem: 'metric' });
    expect(screen.getByText(/metric/i)).toBeInTheDocument();
    expect(screen.getByText(/dark mode/i)).toBeInTheDocument();
  });

  describe('When user is logged out', () => {
    it('should show a Login button', () => {
      renderWithRouter({ userProfile: null, authStatus: 'SIGNED_OUT' });
      expect(screen.getByRole('button', { name: /login/i })).toBeInTheDocument();
    });

    it('should call onOpenProfile when Login button is clicked', () => {
      renderWithRouter({ userProfile: null, authStatus: 'SIGNED_OUT' });
      fireEvent.click(screen.getByRole('button', { name: /login/i }));
      expect(mockOnOpenProfile).toHaveBeenCalledTimes(1);
    });

    it('should not show user-specific buttons', () => {
      renderWithRouter({ userProfile: null, authStatus: 'SIGNED_OUT' });
      expect(screen.queryByLabelText(/open voice assistant/i)).not.toBeInTheDocument();
      expect(screen.queryByLabelText(/open my account settings/i)).not.toBeInTheDocument();
      expect(screen.queryByRole('button', { name: /logout/i })).not.toBeInTheDocument();
    });
  });

  describe('When user is authenticated', () => {
    it('should display the user email', () => {
      renderWithRouter({ userProfile: mockUserProfile, authStatus: 'AUTHENTICATED' });
      expect(screen.getByText(mockUserProfile.user.email)).toBeInTheDocument();
    });

    it('should display "Guest" for anonymous users', () => {
      renderWithRouter({ userProfile: mockUserProfile, authStatus: 'SIGNED_OUT' });
      expect(screen.getByText(/guest/i)).toBeInTheDocument();
    });

    it('should call onOpenVoiceAssistant when microphone icon is clicked', () => {
      renderWithRouter({ userProfile: mockUserProfile, authStatus: 'AUTHENTICATED' });
      fireEvent.click(screen.getByLabelText(/open voice assistant/i));
      expect(mockOnOpenVoiceAssistant).toHaveBeenCalledTimes(1);
    });

    it('should call onOpenProfile when cog icon is clicked', () => {
      renderWithRouter({ userProfile: mockUserProfile, authStatus: 'AUTHENTICATED' });
      fireEvent.click(screen.getByLabelText(/open my account settings/i));
      expect(mockOnOpenProfile).toHaveBeenCalledTimes(1);
    });

    it('should call onSignOut when Logout button is clicked', () => {
      renderWithRouter({ userProfile: mockUserProfile, authStatus: 'AUTHENTICATED' });
      fireEvent.click(screen.getByRole('button', { name: /logout/i }));
      expect(mockOnSignOut).toHaveBeenCalledTimes(1);
    });
  });

  describe('Admin user', () => {
    it('should show the Admin Area link for admin users', () => {
      renderWithRouter({ userProfile: mockAdminProfile, authStatus: 'AUTHENTICATED' });
      const adminLink = screen.getByTitle(/admin area/i);
      expect(adminLink).toBeInTheDocument();
      expect(adminLink.closest('a')).toHaveAttribute('href', '/admin');
    });

    it('should not show the Admin Area link for non-admin users', () => {
      renderWithRouter({ userProfile: mockUserProfile, authStatus: 'AUTHENTICATED' });
      expect(screen.queryByTitle(/admin area/i)).not.toBeInTheDocument();
    });
  });
});
