import React from 'react';
import {fireEvent, render, screen, waitFor} from '@testing-library/react';
import HeaderV2 from '../HeaderV2';

// Mock dependencies
jest.mock('next/link', () => {
  return ({children, href, ...props}: {children: React.ReactNode; href: string; [key: string]: unknown}) => (
    <a href={href} {...props}>{children}</a>
  );
});

const mockUseAuth = jest.fn();
jest.mock('@/contexts/AuthContext', () => ({
  useAuth: () => mockUseAuth(),
}));

const mockUseScrollPosition = jest.fn();
jest.mock('@/hooks/useScrollPosition', () => ({
  useScrollPosition: (threshold?: number) => mockUseScrollPosition(threshold),
}));

jest.mock('@/components/Headers/SearchBar', () => ({
  SearchBar: () => <div data-testid="search-bar">SearchBar</div>,
}));

jest.mock('@/services/domaineService', () => ({
  getDomaines: jest.fn().mockResolvedValue([{dprId: 1, dprNom: 'Danse'}, {dprId: 2, dprNom: 'Musique'}]),
}));

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

jest.mock('../MobileMenu', () => {
  return (props: {isOpen: boolean; onClose: () => void; locale: string}) => (
    <div data-testid="mobile-menu" data-open={props.isOpen} />
  );
});

describe('HeaderV2', () => {
  beforeEach(() => {
    jest.clearAllMocks();
    mockUseAuth.mockReturnValue({isAuthenticated: false});
    mockUseScrollPosition.mockReturnValue(false);
  });

  it('renders the logo with Tamm and Kreiz spans', () => {
    render(<HeaderV2 locale="fr" />);
    expect(screen.getByText('Tamm')).toBeInTheDocument();
    expect(screen.getByText('Kreiz')).toBeInTheDocument();
    const tammSpan = screen.getByText('Tamm');
    const link = tammSpan.closest('a');
    expect(link).toHaveAttribute('href', '/fr');
  });

  it('renders navigation links', () => {
    render(<HeaderV2 locale="fr" />);
    expect(screen.getByText('home_link')).toBeInTheDocument();
    expect(screen.getByText('agenda_link')).toBeInTheDocument();
    expect(screen.getByText('annuaire_link')).toBeInTheDocument();
    expect(screen.getByText('mag_link')).toBeInTheDocument();
    expect(screen.getByText('canalbreizh_link')).toBeInTheDocument();
  });

  it('shouldRenderProposeEventCtaInHeader', () => {
    render(<HeaderV2 locale="fr" />);
    const cta = screen.getByText('propose_event_button');
    expect(cta).toBeInTheDocument();
    expect(cta.closest('a')).toHaveAttribute('href', '/fr/proposition-evenement');
  });

  it('renders login button when not authenticated', () => {
    mockUseAuth.mockReturnValue({isAuthenticated: false});
    render(<HeaderV2 locale="fr" />);
    expect(screen.getByText('login_button')).toBeInTheDocument();
  });

  it('renders profile button when authenticated', () => {
    mockUseAuth.mockReturnValue({isAuthenticated: true});
    render(<HeaderV2 locale="fr" />);
    expect(screen.getByText('profile_button')).toBeInTheDocument();
  });

  it('has no scrolled class by default', () => {
    mockUseScrollPosition.mockReturnValue(false);
    render(<HeaderV2 locale="fr" />);
    const header = screen.getByRole('banner');
    expect(header).not.toHaveClass('headerv2--scrolled');
  });

  it('adds scrolled class when scrolled past threshold', () => {
    mockUseScrollPosition.mockReturnValue(true);
    render(<HeaderV2 locale="fr" />);
    const header = screen.getByRole('banner');
    expect(header).toHaveClass('headerv2--scrolled');
  });

  it('renders LocaleSwitcher', () => {
    render(<HeaderV2 locale="fr" />);
    expect(screen.getByTestId('locale-switcher')).toBeInTheDocument();
  });

  it('renders burger button for mobile', () => {
    render(<HeaderV2 locale="fr" />);
    const burger = screen.getByLabelText('aria_open_menu');
    expect(burger).toBeInTheDocument();
  });

  it('renders MobileMenu outside of the header element', () => {
    const {container} = render(<HeaderV2 locale="fr" />);
    const header = container.querySelector('header[role="banner"]');
    const mobileMenu = container.querySelector('[data-testid="mobile-menu"]');
    expect(header).toBeInTheDocument();
    expect(mobileMenu).toBeInTheDocument();
    expect(header!.contains(mobileMenu)).toBe(false);
  });

  describe('tête de page (spec L313-L317)', () => {
    it('shouldUnfoldTheSearchBarBehindTheMagnifier', () => {
      render(<HeaderV2 locale="fr" />);
      expect(screen.queryByTestId('search-bar')).not.toBeInTheDocument();

      fireEvent.click(screen.getByLabelText('aria_search'));
      expect(screen.getByTestId('search-bar')).toBeInTheDocument();
      expect(screen.getByLabelText('aria_close_search')).toHaveAttribute('aria-expanded', 'true');

      fireEvent.click(screen.getByLabelText('aria_close_search'));
      expect(screen.queryByTestId('search-bar')).not.toBeInTheDocument();
    });

    it('shouldOfferSignUpAndMembershipShortcutsToVisitors', () => {
      render(<HeaderV2 locale="fr" />);
      expect(screen.getByText('signup_button').closest('a')).toHaveAttribute('href', '/fr/inscription');
      expect(screen.getByText('adhesion_link').closest('a')).toHaveAttribute('href', '/fr/adhesion');
      expect(screen.getByText('login_button').closest('a')).toHaveAttribute('href', '/fr/connexion');
    });

    it('shouldHideSignUpFromAuthenticatedMembers', () => {
      mockUseAuth.mockReturnValue({isAuthenticated: true});
      render(<HeaderV2 locale="fr" />);
      expect(screen.queryByText('signup_button')).not.toBeInTheDocument();
    });

    it('shouldShowTheMobileAppIcons', () => {
      render(<HeaderV2 locale="fr" />);
      expect(screen.getByLabelText('community_app_store')).toBeInTheDocument();
      expect(screen.getByLabelText('community_google_play')).toBeInTheDocument();
    });

    it('shouldListTheDomainsAsLinksToTheirHomePage', async () => {
      render(<HeaderV2 locale="fr" />);
      const menu = await screen.findByRole('button', {name: 'domaines_link'});
      expect(menu).toHaveAttribute('aria-expanded', 'false');

      fireEvent.click(menu);

      await waitFor(() => expect(screen.getByRole('link', {name: 'Danse'})).toHaveAttribute('href', '/fr/domaine/1/danse'));
      expect(screen.getByRole('link', {name: 'Musique'})).toHaveAttribute('href', '/fr/domaine/2/musique');
      expect(menu).toHaveAttribute('aria-expanded', 'true');
    });
  });
});
