import { render, screen, fireEvent } from '@testing-library/react'
import { Sidebar, SidebarLayout } from '../sidebar'

// next/link and next/navigation are mocked via jest.config.js moduleNameMapper

const sections = [
  {
    title: 'Main',
    links: [
      { href: '/', label: 'Dashboard', icon: <span data-testid="icon-dashboard" /> },
      { href: '/contacts', label: 'Contacts' },
    ],
  },
  {
    title: 'Admin',
    links: [
      { href: '/settings', label: 'Account Settings' },
    ],
  },
]

describe('Sidebar', () => {
  it('renders app name', () => {
    render(<Sidebar appName="MarketSimpli" sections={sections} />)
    expect(screen.getByText('MarketSimpli')).toBeInTheDocument()
  })

  it('renders section titles', () => {
    render(<Sidebar appName="MarketSimpli" sections={sections} />)
    expect(screen.getByText('Main')).toBeInTheDocument()
    expect(screen.getByText('Admin')).toBeInTheDocument()
  })

  it('renders all nav links', () => {
    render(<Sidebar appName="MarketSimpli" sections={sections} />)
    expect(screen.getByText('Dashboard')).toBeInTheDocument()
    expect(screen.getByText('Contacts')).toBeInTheDocument()
    expect(screen.getByText('Account Settings')).toBeInTheDocument()
  })

  it('renders icons for links that have icons', () => {
    render(<Sidebar appName="MarketSimpli" sections={sections} />)
    expect(screen.getByTestId('icon-dashboard')).toBeInTheDocument()
  })

  it('renders collapse toggle button when collapsible is true (default)', () => {
    render(<Sidebar appName="MarketSimpli" sections={sections} />)
    expect(screen.getByText('Collapse')).toBeInTheDocument()
  })

  it('does not render collapse toggle when collapsible is false', () => {
    render(<Sidebar appName="MarketSimpli" sections={sections} collapsible={false} />)
    expect(screen.queryByText('Collapse')).not.toBeInTheDocument()
  })

  it('collapses when toggle button is clicked', () => {
    const { container } = render(
      <Sidebar appName="MarketSimpli" sections={sections} />
    )
    fireEvent.click(screen.getByText('Collapse'))
    // After collapse, the sidebar should have w-20 class
    expect(container.firstChild).toHaveClass('w-20')
  })

  it('expands back when toggle is clicked again', () => {
    const { container } = render(
      <Sidebar appName="MarketSimpli" sections={sections} />
    )
    // Collapse
    fireEvent.click(screen.getByText('Collapse'))
    // Expand — the chevron button is still present, click it
    const expandBtn = screen.getByRole('button')
    fireEvent.click(expandBtn)
    expect(container.firstChild).toHaveClass('w-64')
  })

  it('hides link labels when collapsed', () => {
    render(
      <Sidebar appName="MarketSimpli" sections={sections} defaultCollapsed />
    )
    // Labels are wrapped in a <span> that only renders when not collapsed
    expect(screen.queryByText('Dashboard')).not.toBeInTheDocument()
    expect(screen.queryByText('Contacts')).not.toBeInTheDocument()
  })

  it('hides section titles when collapsed', () => {
    render(
      <Sidebar appName="MarketSimpli" sections={sections} defaultCollapsed />
    )
    expect(screen.queryByText('Main')).not.toBeInTheDocument()
  })

  it('shows abbreviated app name when collapsed', () => {
    render(
      <Sidebar appName="MarketSimpli" sections={sections} defaultCollapsed />
    )
    expect(screen.getByText('MA')).toBeInTheDocument()
  })

  it('renders user dropdown when provided', () => {
    render(
      <Sidebar
        appName="App"
        sections={sections}
        userDropdown={<div data-testid="user-menu">User Menu</div>}
      />
    )
    expect(screen.getByTestId('user-menu')).toBeInTheDocument()
  })

  it('applies custom className', () => {
    const { container } = render(
      <Sidebar appName="App" sections={sections} className="my-sidebar" />
    )
    expect(container.firstChild).toHaveClass('my-sidebar')
  })

  it('active link uses primary background (pathname matches)', () => {
    // The mock usePathname returns '/test-path'
    // We add a link with that href
    const customSections = [
      {
        links: [
          { href: '/test-path', label: 'Active Link' },
          { href: '/other', label: 'Inactive Link' },
        ],
      },
    ]
    render(<Sidebar appName="App" sections={customSections} />)
    const activeLink = screen.getByText('Active Link').closest('a')
    // Semantic token, not a numeric ramp — `bg-primary-600` is undefined in apps
    // that only declare --color-primary, so the active pill vanished (startsim-1f3n).
    expect(activeLink).toHaveClass('bg-primary')
    expect(activeLink).toHaveClass('text-primary-foreground')
  })

  it('inactive link uses gray text', () => {
    const customSections = [
      {
        links: [
          { href: '/test-path', label: 'Active Link' },
          { href: '/other', label: 'Inactive Link' },
        ],
      },
    ]
    render(<Sidebar appName="App" sections={customSections} />)
    const inactiveLink = screen.getByText('Inactive Link').closest('a')
    expect(inactiveLink).toHaveClass('text-gray-300')
  })

  it('root href "/" is active only for exact match', () => {
    // usePathname returns '/test-path', so '/' should not be active
    const customSections = [
      {
        links: [{ href: '/', label: 'Home' }],
      },
    ]
    render(<Sidebar appName="App" sections={customSections} />)
    const homeLink = screen.getByText('Home').closest('a')
    expect(homeLink).not.toHaveClass('bg-primary')
  })
})

// ---------------------------------------------------------------------------
// SidebarLayout
// ---------------------------------------------------------------------------

describe('SidebarLayout', () => {
  it('renders children', () => {
    render(
      <SidebarLayout>
        <p>Page content</p>
      </SidebarLayout>
    )
    expect(screen.getByText('Page content')).toBeInTheDocument()
  })

  it('applies expanded width spacer by default', () => {
    const { container } = render(
      <SidebarLayout>
        <p>Content</p>
      </SidebarLayout>
    )
    const spacer = container.querySelector('.w-64')
    expect(spacer).toBeInTheDocument()
  })

  it('applies collapsed width spacer when collapsed is true', () => {
    const { container } = render(
      <SidebarLayout collapsed>
        <p>Content</p>
      </SidebarLayout>
    )
    const spacer = container.querySelector('.w-20')
    expect(spacer).toBeInTheDocument()
  })
})
