import { describe, test, expect, vi } from 'vitest'
import { render, screen, fireEvent } from '@testing-library/react'
import { ZoomControlsUI } from './zoom-controls'

describe('ZoomControlsUI', () => {
  const defaultProps = {
    zoom: 10,
    onChange: vi.fn(),
  }

  test('renders correctly with default props', () => {
    render(<ZoomControlsUI {...defaultProps} />)

    expect(screen.getByLabelText('Increase zoom')).toBeTruthy()
    expect(screen.getByLabelText('Decrease zoom')).toBeTruthy()
    expect(screen.getByText('10')).toBeTruthy()
  })

  test('handles zoom increase correctly', () => {
    render(<ZoomControlsUI {...defaultProps} />)

    fireEvent.click(screen.getByLabelText('Increase zoom'))
    expect(defaultProps.onChange).toHaveBeenCalledWith(11)
  })

  test('handles zoom decrease correctly', () => {
    render(<ZoomControlsUI {...defaultProps} />)

    fireEvent.click(screen.getByLabelText('Decrease zoom'))
    expect(defaultProps.onChange).toHaveBeenCalledWith(9)
  })

  test('respects min and max zoom limits', () => {
    const props = {
      ...defaultProps,
      zoom: 24,
      maxZoom: 24,
      minZoom: 5,
    }

    const { rerender } = render(<ZoomControlsUI {...props} />)

    fireEvent.click(screen.getByLabelText('Increase zoom'))
    expect(props.onChange).toHaveBeenCalledWith(24) // Should not exceed maxZoom

    props.zoom = 5
    rerender(<ZoomControlsUI {...props} />)

    fireEvent.click(screen.getByLabelText('Decrease zoom'))
    expect(props.onChange).toHaveBeenCalledWith(5) // Should not go below minZoom
  })

  test('renders reset button when onReset is provided', () => {
    const props = {
      ...defaultProps,
      onReset: vi.fn(),
    }

    render(<ZoomControlsUI {...props} />)

    const resetButton = screen.getByLabelText('Reset action')
    expect(resetButton).toBeTruthy()

    fireEvent.click(resetButton)
    expect(props.onReset).toHaveBeenCalledTimes(1)
  })

  test('does not render reset button when onReset is not provided', () => {
    render(<ZoomControlsUI {...defaultProps} />)

    expect(screen.queryByLabelText('Reset action')).toBeNull()
  })

  test('hides zoom display when showZoom is false', () => {
    render(<ZoomControlsUI {...defaultProps} showZoom={false} />)

    expect(screen.queryByText('10')).toBeNull()
  })

  test('shows loading indicator when isLoading is true', () => {
    render(<ZoomControlsUI {...defaultProps} isLoading={true} />)

    expect(screen.getByRole('progressbar')).toBeTruthy()
  })

  test('renders in horizontal direction when specified', () => {
    render(<ZoomControlsUI {...defaultProps} direction='horizontal' />)

    // We can't check styles directly without jest-dom, so we'll skip this assertion
    expect(screen.getByText('10')).toBeTruthy()
  })

  test('disables buttons when disabled prop is true', () => {
    render(<ZoomControlsUI {...defaultProps} disabled={true} />)

    const increaseButton = screen.getByLabelText('Increase zoom')
    const decreaseButton = screen.getByLabelText('Decrease zoom')
    expect(increaseButton.hasAttribute('disabled')).toBeTruthy()
    expect(decreaseButton.hasAttribute('disabled')).toBeTruthy()
  })
})
