import '@testing-library/jest-dom'

import { fireEvent, render, screen } from '@testing-library/react'
import { axe, toHaveNoViolations } from 'jest-axe'
import { vi } from 'vitest'

import { PktHeader } from './Header'

expect.extend(toHaveNoViolations)

// Mock useWindowWidth hook to control viewport size
let mockedWidth = 1400
vi.mock('../../hooks/useWindowWidth', () => ({
  useWindowWidth: () => mockedWidth,
}))

describe('PktHeader', () => {
  beforeAll(() => {
    // jsdom does not implement scrollTo; our scroll lock hook uses it
    window.scrollTo = vi.fn()
  })

  beforeEach(() => {
    mockedWidth = 1400 // Reset to desktop by default
    vi.clearAllMocks()
  })

  const mockUser = {
    name: 'John Doe',
    lastLoggedIn: '2023-08-20T12:34:56Z',
  }

  const mockUserMenu = [
    { title: 'Profile', target: '/profile', iconName: 'profile' },
    { title: 'Settings', target: '/settings', iconName: 'settings' },
  ]

  const mockRepresenting = {
    name: 'Org Name',
    orgNumber: '123456789',
  }

  it('renders header with service name', () => {
    const { container } = render(<PktHeader serviceName="Test Service" />)
    expect(container.querySelector('.pkt-header-service')).toBeInTheDocument()
    expect(screen.getByText('Test Service')).toBeInTheDocument()
  })

  it('renders user menu when user is present', () => {
    render(<PktHeader serviceName="Test" user={mockUser} userMenu={mockUserMenu} />)
    const userButton = screen.getByRole('button', { name: /John Doe/ })
    fireEvent.click(userButton)
    expect(screen.getByText('Profile')).toBeInTheDocument()
    expect(screen.getByText('Settings')).toBeInTheDocument()
  })

  it('renders representing organization when representing is present', () => {
    render(<PktHeader serviceName="Test" user={mockUser} representing={mockRepresenting} />)
    const userButton = screen.getByRole('button', { name: /Org Name/ })
    fireEvent.click(userButton)
    expect(screen.getByText('Org.nr. 123456789')).toBeInTheDocument()
  })

  it('calls logOut function when Log Out button is clicked', async () => {
    const mockLogOut = vi.fn()
    render(<PktHeader serviceName="Test" logOutButtonPlacement="header" logOut={mockLogOut} />)
    const logOutButton = screen.getByRole('button', { name: 'Logg ut' })
    await fireEvent.click(logOutButton)
    expect(mockLogOut).toHaveBeenCalled()
  })

  it('toggles user menu when user button is clicked', () => {
    render(<PktHeader serviceName="Test" user={mockUser} userMenu={mockUserMenu} />)
    const userButton = screen.getByRole('button', { name: /John Doe/ })
    fireEvent.click(userButton)
    // User menu should be open - check for menu items
    expect(screen.getByText('Profile')).toBeInTheDocument()
  })

  describe('accessibility', () => {
    it('renders with no wcag errors with axe', async () => {
      const { container } = render(<PktHeader serviceName="Test" user={mockUser} userMenu={mockUserMenu} />)
      const results = await axe(container)
      expect(results).toHaveNoViolations()
    })
  })
})
