import { describe, it, expect } from 'vitest';

/**
 * Test animation utilities
 * These tests verify that animation configurations are correctly structured
 */

describe('Animation Utilities', () => {
  describe('Spin Animation Configuration', () => {
    it('should generate correct spin animation CSS', () => {
      const duration = 1500;
      const rotations = 3;
      const degrees = rotations * 360;
      
      const css = `
        animation: spinReel ${duration}ms cubic-bezier(0.25, 0.46, 0.45, 0.94) forwards;
        transform: rotateY(${degrees}deg);
      `;
      
      expect(css).toContain('spinReel');
      expect(css).toContain('1500ms');
      expect(css).toContain('1080deg');
    });

    it('should calculate correct rotation degrees', () => {
      const rotations = 3;
      const degrees = rotations * 360;
      expect(degrees).toBe(1080);
    });

    it('should support variable rotations', () => {
      const testCases = [
        { rotations: 1, expected: 360 },
        { rotations: 2, expected: 720 },
        { rotations: 3, expected: 1080 },
        { rotations: 5, expected: 1800 },
      ];

      testCases.forEach(({ rotations, expected }) => {
        const degrees = rotations * 360;
        expect(degrees).toBe(expected);
      });
    });
  });

  describe('Confetti Particle Generation', () => {
    it('should generate correct number of particles', () => {
      const count = 30;
      const particles = Array.from({ length: count }).map((_, i) => ({
        id: i,
        left: Math.random() * 100,
        delay: Math.random() * 0.3,
        duration: 2 + Math.random() * 1,
        color: ['#FFD700', '#2563eb', '#FF6347', '#32CD32', '#1E90FF'][
          Math.floor(Math.random() * 5)
        ],
      }));

      expect(particles).toHaveLength(count);
    });

    it('should generate particles with valid properties', () => {
      const particles = Array.from({ length: 5 }).map((_, i) => ({
        id: i,
        left: Math.random() * 100,
        delay: Math.random() * 0.3,
        duration: 2 + Math.random() * 1,
        color: '#FFD700',
      }));

      particles.forEach(particle => {
        expect(particle.id).toBeGreaterThanOrEqual(0);
        expect(particle.left).toBeGreaterThanOrEqual(0);
        expect(particle.left).toBeLessThanOrEqual(100);
        expect(particle.delay).toBeGreaterThanOrEqual(0);
        expect(particle.delay).toBeLessThanOrEqual(0.3);
        expect(particle.duration).toBeGreaterThanOrEqual(2);
        expect(particle.duration).toBeLessThanOrEqual(3);
        expect(particle.color).toMatch(/^#[0-9A-F]{6}$/i);
      });
    });
  });

  describe('Win Announcement Configuration', () => {
    it('should identify big wins correctly', () => {
      const betAmount = 10;
      const testCases = [
        { winAmount: 100, isBigWin: true }, // 10x multiplier > 5x
        { winAmount: 60, isBigWin: true },  // 6x multiplier > 5x
        { winAmount: 51, isBigWin: true },  // 5.1x multiplier > 5x
        { winAmount: 50, isBigWin: false }, // 5x multiplier = 5x (not greater)
        { winAmount: 49, isBigWin: false }, // 4.9x multiplier < 5x
        { winAmount: 20, isBigWin: false }, // 2x multiplier < 5x
        { winAmount: 10, isBigWin: false }, // 1x multiplier < 5x
      ];

      testCases.forEach(({ winAmount, isBigWin: expected }) => {
        const isBigWin = winAmount > betAmount * 5;
        expect(isBigWin).toBe(expected);
      });
    });

    it('should calculate multipliers correctly', () => {
      const testCases = [
        { winAmount: 100, betAmount: 10, expected: 10 },
        { winAmount: 50, betAmount: 10, expected: 5 },
        { winAmount: 25, betAmount: 10, expected: 2.5 },
        { winAmount: 10, betAmount: 10, expected: 1 },
        { winAmount: 0, betAmount: 10, expected: 0 },
      ];

      testCases.forEach(({ winAmount, betAmount, expected }) => {
        const multiplier = winAmount / betAmount;
        expect(multiplier).toBe(expected);
      });
    });
  });

  describe('Animation Timing', () => {
    it('should have valid animation durations', () => {
      const durations = {
        fast: 300,
        normal: 500,
        slow: 1000,
        verySlow: 2000,
      };

      Object.values(durations).forEach(duration => {
        expect(duration).toBeGreaterThan(0);
        expect(typeof duration).toBe('number');
      });
    });

    it('should support standard easing functions', () => {
      const timings = ['ease-in', 'ease-out', 'ease-in-out', 'linear'];
      
      timings.forEach(timing => {
        expect(timing).toMatch(/^(ease-in|ease-out|ease-in-out|linear)$/);
      });
    });
  });

  describe('Sound Effect Timing', () => {
    it('should play big win sound at correct volume', () => {
      const isBigWin = true;
      const volume = isBigWin ? 0.8 : 0.6;
      
      expect(volume).toBe(0.8);
      expect(volume).toBeGreaterThan(0);
      expect(volume).toBeLessThanOrEqual(1);
    });

    it('should play regular win sound at correct volume', () => {
      const isBigWin = false;
      const volume = isBigWin ? 0.8 : 0.6;
      
      expect(volume).toBe(0.6);
      expect(volume).toBeGreaterThan(0);
      expect(volume).toBeLessThanOrEqual(1);
    });

    it('should have valid announcement display times', () => {
      const announcementTime = 3000; // 3 seconds
      const confettiTime = 2500;     // 2.5 seconds
      
      expect(announcementTime).toBeGreaterThan(confettiTime);
      expect(announcementTime).toBeGreaterThan(0);
      expect(confettiTime).toBeGreaterThan(0);
    });
  });
});
