/**
 * Tests for Skeleton component
 */

import { describe, it, expect } from 'vitest';
import { render } from '@testing-library/react';
import {
  Skeleton,
  SkeletonText,
  SkeletonCard,
  SkeletonTable,
  SkeletonAvatar,
  SkeletonButton,
} from './Skeleton';

describe('Skeleton', () => {
  describe('base Skeleton', () => {
    it('should render with default props', () => {
      const { container } = render(<Skeleton />);
      const skeleton = container.firstChild as HTMLElement;

      expect(skeleton).toBeInTheDocument();
      expect(skeleton).toHaveClass('bg-gray-200', 'dark:bg-gray-700');
      expect(skeleton).toHaveClass('animate-pulse');
      expect(skeleton).toHaveClass('rounded'); // text variant default
    });

    it('should apply rectangular variant', () => {
      const { container } = render(<Skeleton variant="rectangular" />);
      const skeleton = container.firstChild as HTMLElement;

      expect(skeleton).toHaveClass('rounded-md');
    });

    it('should apply circular variant', () => {
      const { container } = render(<Skeleton variant="circular" />);
      const skeleton = container.firstChild as HTMLElement;

      expect(skeleton).toHaveClass('rounded-full');
    });

    it('should apply wave animation', () => {
      const { container } = render(<Skeleton animation="wave" />);
      const skeleton = container.firstChild as HTMLElement;

      expect(skeleton).toHaveClass('animate-shimmer');
      expect(skeleton).not.toHaveClass('animate-pulse');
    });

    it('should not animate with none', () => {
      const { container } = render(<Skeleton animation="none" />);
      const skeleton = container.firstChild as HTMLElement;

      expect(skeleton).not.toHaveClass('animate-pulse');
      expect(skeleton).not.toHaveClass('animate-shimmer');
    });

    it('should apply custom width and height as numbers', () => {
      const { container } = render(<Skeleton width={100} height={50} />);
      const skeleton = container.firstChild as HTMLElement;

      expect(skeleton).toHaveStyle({ width: '100px', height: '50px' });
    });

    it('should apply custom width and height as strings', () => {
      const { container } = render(<Skeleton width="50%" height="2rem" />);
      const skeleton = container.firstChild as HTMLElement;

      expect(skeleton).toHaveStyle({ width: '50%', height: '2rem' });
    });

    it('should be aria-hidden', () => {
      const { container } = render(<Skeleton />);
      const skeleton = container.firstChild as HTMLElement;

      expect(skeleton).toHaveAttribute('aria-hidden', 'true');
    });

    it('should apply custom className', () => {
      const { container } = render(<Skeleton className="my-custom-class" />);
      const skeleton = container.firstChild as HTMLElement;

      expect(skeleton).toHaveClass('my-custom-class');
    });
  });

  describe('SkeletonText', () => {
    it('should render default 3 lines', () => {
      const { container } = render(<SkeletonText />);
      const wrapper = container.firstChild as HTMLElement;
      const lines = wrapper.querySelectorAll('[aria-hidden="true"]');

      expect(lines).toHaveLength(3);
    });

    it('should render custom number of lines', () => {
      const { container } = render(<SkeletonText lines={5} />);
      const wrapper = container.firstChild as HTMLElement;
      const lines = wrapper.querySelectorAll('[aria-hidden="true"]');

      expect(lines).toHaveLength(5);
    });

    it('should apply gap classes', () => {
      const { container } = render(<SkeletonText gap="lg" />);
      const wrapper = container.firstChild as HTMLElement;

      expect(wrapper).toHaveClass('gap-3');
    });
  });

  describe('SkeletonCard', () => {
    it('should render with header by default', () => {
      const { container } = render(<SkeletonCard />);
      const skeletons = container.querySelectorAll('[aria-hidden="true"]');

      // Header (2 skeletons) + content lines (3) = 5
      expect(skeletons.length).toBeGreaterThanOrEqual(5);
    });

    it('should render avatar when showAvatar is true', () => {
      const { container } = render(<SkeletonCard showAvatar />);
      const circular = container.querySelector('.rounded-full');

      expect(circular).toBeInTheDocument();
    });

    it('should render footer when showFooter is true', () => {
      const { container } = render(<SkeletonCard showFooter />);
      const rectangles = container.querySelectorAll('.rounded-md');

      expect(rectangles.length).toBeGreaterThanOrEqual(2);
    });
  });

  describe('SkeletonTable', () => {
    it('should render correct number of rows', () => {
      const { container } = render(<SkeletonTable rows={3} columns={4} />);
      const rows = container.querySelectorAll('.divide-y > div');

      expect(rows).toHaveLength(3);
    });

    it('should render header when showHeader is true', () => {
      const { container } = render(<SkeletonTable showHeader />);
      const header = container.querySelector('.bg-background-subtle');

      expect(header).toBeInTheDocument();
    });
  });

  describe('SkeletonAvatar', () => {
    it('should render with correct size', () => {
      const { container } = render(<SkeletonAvatar size="lg" />);
      const avatar = container.firstChild as HTMLElement;

      expect(avatar).toHaveStyle({ width: '48px', height: '48px' });
    });

    it('should be circular', () => {
      const { container } = render(<SkeletonAvatar />);
      const avatar = container.firstChild as HTMLElement;

      expect(avatar).toHaveClass('rounded-full');
    });
  });

  describe('SkeletonButton', () => {
    it('should render with correct height for size', () => {
      const { container } = render(<SkeletonButton size="lg" />);
      const button = container.firstChild as HTMLElement;

      expect(button).toHaveStyle({ height: '48px' });
    });

    it('should apply custom width', () => {
      const { container } = render(<SkeletonButton width={200} />);
      const button = container.firstChild as HTMLElement;

      expect(button).toHaveStyle({ width: '200px' });
    });
  });
});
