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

describe('Progress Component', () => {
  describe('Linear variant', () => {
    it('renders linear progress bar', () => {
      render(<Progress value={50} />);

      const progressBar = screen.getByRole('progressbar');
      expect(progressBar).toBeInTheDocument();
    });

    it('renders with correct percentage', () => {
      const { container } = render(<Progress value={50} />);

      const progressFill = container.querySelector('.h-full');
      expect(progressFill).toHaveStyle({ width: '50%' });
    });

    it('clamps value to max', () => {
      const { container } = render(<Progress value={150} max={100} />);

      const progressFill = container.querySelector('.h-full');
      expect(progressFill).toHaveStyle({ width: '100%' });
    });

    it('clamps value to 0 minimum', () => {
      const { container } = render(<Progress value={-10} />);

      const progressFill = container.querySelector('.h-full');
      expect(progressFill).toHaveStyle({ width: '0%' });
    });

    it('shows label when provided', () => {
      render(<Progress value={50} label="Upload progress" />);

      expect(screen.getByText('Upload progress')).toBeInTheDocument();
    });

    it('shows percentage when showLabel is true', () => {
      render(<Progress value={75} showLabel />);

      expect(screen.getByText('75%')).toBeInTheDocument();
    });

    it('shows both label and percentage', () => {
      render(<Progress value={60} label="Download" showLabel />);

      expect(screen.getByText('Download')).toBeInTheDocument();
      expect(screen.getByText('60%')).toBeInTheDocument();
    });

    it('applies custom color', () => {
      const { container } = render(<Progress value={50} color="#ff0000" />);

      const progressFill = container.querySelector('.h-full');
      expect(progressFill).toHaveStyle({ backgroundColor: '#ff0000' });
    });

    it('has correct aria attributes', () => {
      render(<Progress value={50} max={100} label="Progress" />);

      const progressBar = screen.getByRole('progressbar');
      expect(progressBar).toHaveAttribute('aria-valuenow', '50');
      expect(progressBar).toHaveAttribute('aria-valuemin', '0');
      expect(progressBar).toHaveAttribute('aria-valuemax', '100');
      expect(progressBar).toHaveAttribute('aria-label');
      const ariaLabel = progressBar.getAttribute('aria-label');
      expect(ariaLabel).toContain('50%');
    });

    it('applies custom className', () => {
      const { container } = render(
        <Progress value={50} className="custom-progress" />,
      );

      const wrapper = container.firstChild;
      expect(wrapper).toHaveClass('custom-progress');
    });
  });

  describe('Circular variant', () => {
    it('renders circular progress', () => {
      render(<Progress value={50} variant="circular" />);

      const progressBar = screen.getByRole('progressbar');
      expect(progressBar).toBeInTheDocument();
      expect(progressBar.tagName).toBe('svg');
    });

    it('renders with correct percentage', () => {
      const { container } = render(<Progress value={50} variant="circular" />);

      const svg = container.querySelector('svg');
      expect(svg).toBeInTheDocument();
    });

    it('shows percentage when showLabel is true', () => {
      render(<Progress value={75} variant="circular" showLabel />);

      expect(screen.getByText('75%')).toBeInTheDocument();
    });

    it('does not show percentage when showLabel is false', () => {
      render(<Progress value={75} variant="circular" showLabel={false} />);

      expect(screen.queryByText('75%')).not.toBeInTheDocument();
    });

    it('applies custom color', () => {
      const { container } = render(
        <Progress value={50} variant="circular" color="#00ff00" />,
      );

      const circle = container.querySelector('circle[stroke-dasharray]');
      expect(circle).toHaveStyle({ stroke: '#00ff00' });
    });

    it('has correct aria attributes', () => {
      render(<Progress value={50} variant="circular" max={100} />);

      const progressBar = screen.getByRole('progressbar');
      expect(progressBar).toHaveAttribute('aria-valuenow', '50');
      expect(progressBar).toHaveAttribute('aria-valuemin', '0');
      expect(progressBar).toHaveAttribute('aria-valuemax', '100');
    });

    it('applies custom className', () => {
      const { container } = render(
        <Progress value={50} variant="circular" className="custom-circular" />,
      );

      const wrapper = container.firstChild;
      expect(wrapper).toHaveClass('custom-circular');
    });

    it('clamps value to max in circular variant', () => {
      const { container } = render(
        <Progress value={150} variant="circular" max={100} />,
      );

      const svg = container.querySelector('svg');
      expect(svg).toBeInTheDocument();
    });
  });

  describe('Edge cases', () => {
    it('handles zero value', () => {
      const { container } = render(<Progress value={0} />);

      const progressFill = container.querySelector('.h-full');
      expect(progressFill).toHaveStyle({ width: '0%' });
    });

    it('handles max value', () => {
      const { container } = render(<Progress value={100} />);

      const progressFill = container.querySelector('.h-full');
      expect(progressFill).toHaveStyle({ width: '100%' });
    });

    it('handles custom max value', () => {
      const { container } = render(<Progress value={50} max={200} />);

      const progressFill = container.querySelector('.h-full');
      expect(progressFill).toHaveStyle({ width: '25%' });
    });

    it('handles decimal values', () => {
      const { container } = render(<Progress value={33.33} />);

      const progressFill = container.querySelector('.h-full');
      expect(progressFill).toHaveStyle({ width: '33%' });
    });
  });
});
