import { describe, it, expect } from 'vitest';
import { render, screen } from '@testing-library/react';
import ProgressBar from './ProgressBar';

describe('ProgressBar', () => {
  it('renders with role="progressbar" and accessible aria attributes', () => {
    render(<ProgressBar value={42} label="Uploading" />);
    const bar = screen.getByRole('progressbar', { name: 'Uploading' });
    expect(bar).toBeTruthy();
    expect(bar.getAttribute('aria-valuemin')).toBe('0');
    expect(bar.getAttribute('aria-valuemax')).toBe('100');
    expect(bar.getAttribute('aria-valuenow')).toBe('42');
    expect(bar.getAttribute('aria-label')).toBe('Uploading');
  });

  it('falls back to "Progress" for aria-label when label is omitted', () => {
    render(<ProgressBar value={10} />);
    expect(screen.getByRole('progressbar', { name: 'Progress' })).toBeTruthy();
  });

  it('clamps values above 100 to 100', () => {
    render(<ProgressBar value={150} />);
    expect(screen.getByRole('progressbar').getAttribute('aria-valuenow')).toBe('100');
  });

  it('clamps values below 0 to 0', () => {
    render(<ProgressBar value={-30} />);
    expect(screen.getByRole('progressbar').getAttribute('aria-valuenow')).toBe('0');
  });

  it('floors fractional values to an integer', () => {
    render(<ProgressBar value={42.9} />);
    expect(screen.getByRole('progressbar').getAttribute('aria-valuenow')).toBe('42');
  });

  it('treats non-finite values as 0', () => {
    render(<ProgressBar value={Number.NaN} />);
    expect(screen.getByRole('progressbar').getAttribute('aria-valuenow')).toBe('0');
  });

  it('renders label text when provided', () => {
    render(<ProgressBar value={50} label="Photos" />);
    expect(screen.getByText('Photos')).toBeTruthy();
  });

  it('renders the percent when showValue is true', () => {
    render(<ProgressBar value={73} showValue />);
    expect(screen.getByText('73%')).toBeTruthy();
  });

  it('omits the header row when no label and showValue are set', () => {
    const { container } = render(<ProgressBar value={30} />);
    expect(screen.queryByText('30%')).toBeNull();
    expect(screen.getByRole('progressbar')).toBeTruthy();
    expect(container.firstChild).toBeTruthy();
  });

  it('applies size-specific track heights', () => {
    const { rerender } = render(<ProgressBar value={10} size="xs" />);
    expect(screen.getByRole('progressbar').className).toContain('h-1');

    rerender(<ProgressBar value={10} size="sm" />);
    expect(screen.getByRole('progressbar').className).toContain('h-2');

    rerender(<ProgressBar value={10} size="md" />);
    expect(screen.getByRole('progressbar').className).toContain('h-3');
  });

  it('merges className onto the wrapper', () => {
    const { container } = render(<ProgressBar value={20} className="mt-4 max-w-xs" />);
    const wrapper = container.firstChild as HTMLElement;
    expect(wrapper.className).toContain('mt-4');
    expect(wrapper.className).toContain('max-w-xs');
    expect(wrapper.className).toContain('w-full');
  });
});