import { describe, it, expect, vi, beforeEach } from 'vitest'
import { render, screen, waitFor } from '@testing-library/react'
import userEvent from '@testing-library/user-event'
import { Sidebar } from './sidebar'

// Mock next/navigation
const mockPush = vi.fn()
const mockPathname = vi.fn()

vi.mock('next/navigation', () => ({
  useRouter: () => ({
    push: mockPush,
  }),
  usePathname: () => mockPathname(),
}))

// Mock supabase
const mockSignOut = vi.fn()
vi.mock('@/lib/supabase', () => ({
  supabase: {
    auth: {
      signOut: () => mockSignOut(),
    },
  },
}))

describe('Sidebar', () => {
  beforeEach(() => {
    vi.clearAllMocks()
    mockPathname.mockReturnValue('/')
  })

  it('should render sidebar with logo and navigation', () => {
    render(<Sidebar />)

    expect(screen.getByText('TabataFit')).toBeInTheDocument()
    expect(screen.getByText('Admin Dashboard')).toBeInTheDocument()
    expect(screen.getByRole('button', { name: /logout/i })).toBeInTheDocument()
  })

  it('should render all navigation items', () => {
    render(<Sidebar />)

    expect(screen.getByRole('link', { name: /dashboard/i })).toBeInTheDocument()
    expect(screen.getByRole('link', { name: /workouts/i })).toBeInTheDocument()
    expect(screen.getByRole('link', { name: /trainers/i })).toBeInTheDocument()
    expect(screen.getByRole('link', { name: /collections/i })).toBeInTheDocument()
    expect(screen.getByRole('link', { name: /media/i })).toBeInTheDocument()
  })

  it('should highlight active navigation item', () => {
    mockPathname.mockReturnValue('/workouts')
    render(<Sidebar />)

    const workoutsLink = screen.getByRole('link', { name: /workouts/i })
    expect(workoutsLink).toHaveClass('text-orange-500')
    expect(workoutsLink).toHaveClass('bg-orange-500/10')
  })

  it('should not highlight inactive navigation items', () => {
    mockPathname.mockReturnValue('/workouts')
    render(<Sidebar />)

    const dashboardLink = screen.getByRole('link', { name: /dashboard/i })
    expect(dashboardLink).toHaveClass('text-neutral-400')
    expect(dashboardLink).not.toHaveClass('bg-orange-500/10')
  })

  it('should navigate to correct routes when clicking links', () => {
    render(<Sidebar />)

    const workoutsLink = screen.getByRole('link', { name: /workouts/i })
    expect(workoutsLink).toHaveAttribute('href', '/workouts')

    const trainersLink = screen.getByRole('link', { name: /trainers/i })
    expect(trainersLink).toHaveAttribute('href', '/trainers')
  })

  it('should handle logout', async () => {
    mockSignOut.mockResolvedValue({ error: null })
    render(<Sidebar />)

    const logoutButton = screen.getByRole('button', { name: /logout/i })
    await userEvent.click(logoutButton)

    await waitFor(() => {
      expect(mockSignOut).toHaveBeenCalled()
    })

    expect(mockPush).toHaveBeenCalledWith('/login')
  })

  it('should handle logout errors gracefully', async () => {
    mockSignOut.mockRejectedValueOnce(new Error('Network error'))
    
    render(<Sidebar />)

    const logoutButton = screen.getByRole('button', { name: /logout/i })
    await userEvent.click(logoutButton)

    await waitFor(() => {
      expect(mockSignOut).toHaveBeenCalled()
    })
  })

  it('should have correct styling for navigation', () => {
    render(<Sidebar />)

    const nav = screen.getByRole('navigation')
    expect(nav).toBeInTheDocument()

    const links = screen.getAllByRole('link')
    links.forEach(link => {
      expect(link).toHaveClass('flex', 'items-center', 'gap-3')
    })
  })

  it('should display icons for navigation items', () => {
    render(<Sidebar />)

    // All nav links should have icons (lucide icons render as svg)
    const links = screen.getAllByRole('link')
    links.forEach(link => {
      const icon = link.querySelector('svg')
      expect(icon).toBeInTheDocument()
    })
  })

  it('should be sticky positioned', () => {
    render(<Sidebar />)

    const sidebar = screen.getByRole('complementary') || document.querySelector('aside')
    expect(sidebar).toHaveClass('sticky', 'top-0')
  })
})