import { describe, it, expect } from 'vitest'
import { ACHIEVEMENTS } from '../../shared/data/achievements'

describe('achievements data', () => {
  describe('ACHIEVEMENTS structure', () => {
    it('should have exactly 8 achievements', () => {
      expect(ACHIEVEMENTS).toHaveLength(8)
    })

    it('should have all required properties', () => {
      ACHIEVEMENTS.forEach(achievement => {
        expect(achievement.id).toBeDefined()
        expect(achievement.title).toBeDefined()
        expect(achievement.description).toBeDefined()
        expect(achievement.icon).toBeDefined()
        expect(achievement.requirement).toBeDefined()
        expect(achievement.type).toBeDefined()
      })
    })

    it('should have unique achievement IDs', () => {
      const ids = ACHIEVEMENTS.map(a => a.id)
      const uniqueIds = new Set(ids)
      expect(uniqueIds.size).toBe(ids.length)
    })

    it('should have unique achievement titles', () => {
      const titles = ACHIEVEMENTS.map(a => a.title)
      const uniqueTitles = new Set(titles)
      expect(uniqueTitles.size).toBe(titles.length)
    })

    it('should have positive requirements', () => {
      ACHIEVEMENTS.forEach(achievement => {
        expect(achievement.requirement).toBeGreaterThan(0)
      })
    })
  })

  describe('achievement types', () => {
    it('should have valid achievement types', () => {
      const validTypes = ['workouts', 'streak', 'calories', 'minutes']
      ACHIEVEMENTS.forEach(achievement => {
        expect(validTypes).toContain(achievement.type)
      })
    })

    it('should have workouts type achievements', () => {
      const workoutAchievements = ACHIEVEMENTS.filter(a => a.type === 'workouts')
      expect(workoutAchievements.length).toBeGreaterThan(0)
    })

    it('should have streak type achievements', () => {
      const streakAchievements = ACHIEVEMENTS.filter(a => a.type === 'streak')
      expect(streakAchievements.length).toBeGreaterThan(0)
    })

    it('should have calories type achievements', () => {
      const calorieAchievements = ACHIEVEMENTS.filter(a => a.type === 'calories')
      expect(calorieAchievements.length).toBeGreaterThan(0)
    })

    it('should have minutes type achievements', () => {
      const minutesAchievements = ACHIEVEMENTS.filter(a => a.type === 'minutes')
      expect(minutesAchievements.length).toBeGreaterThan(0)
    })
  })

  describe('specific achievements', () => {
    it('should have First Burn achievement', () => {
      const achievement = ACHIEVEMENTS.find(a => a.id === 'first-burn')
      expect(achievement).toBeDefined()
      expect(achievement!.title).toBe('First Burn')
      expect(achievement!.requirement).toBe(1)
      expect(achievement!.type).toBe('workouts')
    })

    it('should have Week Warrior achievement', () => {
      const achievement = ACHIEVEMENTS.find(a => a.id === 'week-warrior')
      expect(achievement).toBeDefined()
      expect(achievement!.title).toBe('Week Warrior')
      expect(achievement!.requirement).toBe(7)
      expect(achievement!.type).toBe('streak')
    })

    it('should have Century Club achievement', () => {
      const achievement = ACHIEVEMENTS.find(a => a.id === 'century-club')
      expect(achievement).toBeDefined()
      expect(achievement!.title).toBe('Century Club')
      expect(achievement!.requirement).toBe(100)
      expect(achievement!.type).toBe('calories')
    })

    it('should have Iron Will achievement', () => {
      const achievement = ACHIEVEMENTS.find(a => a.id === 'iron-will')
      expect(achievement).toBeDefined()
      expect(achievement!.title).toBe('Iron Will')
      expect(achievement!.requirement).toBe(10)
      expect(achievement!.type).toBe('workouts')
    })

    it('should have Tabata Master achievement', () => {
      const achievement = ACHIEVEMENTS.find(a => a.id === 'tabata-master')
      expect(achievement).toBeDefined()
      expect(achievement!.title).toBe('Tabata Master')
      expect(achievement!.requirement).toBe(50)
      expect(achievement!.type).toBe('workouts')
    })

    it('should have Marathon Burner achievement', () => {
      const achievement = ACHIEVEMENTS.find(a => a.id === 'marathon-burner')
      expect(achievement).toBeDefined()
      expect(achievement!.title).toBe('Marathon Burner')
      expect(achievement!.requirement).toBe(100)
      expect(achievement!.type).toBe('minutes')
    })

    it('should have Unstoppable achievement', () => {
      const achievement = ACHIEVEMENTS.find(a => a.id === 'unstoppable')
      expect(achievement).toBeDefined()
      expect(achievement!.title).toBe('Unstoppable')
      expect(achievement!.requirement).toBe(30)
      expect(achievement!.type).toBe('streak')
    })

    it('should have Calorie Crusher achievement', () => {
      const achievement = ACHIEVEMENTS.find(a => a.id === 'calorie-crusher')
      expect(achievement).toBeDefined()
      expect(achievement!.title).toBe('Calorie Crusher')
      expect(achievement!.requirement).toBe(1000)
      expect(achievement!.type).toBe('calories')
    })
  })

  describe('achievement progression', () => {
    it('should have increasing workout requirements', () => {
      const workoutAchievements = ACHIEVEMENTS
        .filter(a => a.type === 'workouts')
        .sort((a, b) => a.requirement - b.requirement)
      
      for (let i = 1; i < workoutAchievements.length; i++) {
        expect(workoutAchievements[i].requirement).toBeGreaterThan(workoutAchievements[i-1].requirement)
      }
    })

    it('should have increasing streak requirements', () => {
      const streakAchievements = ACHIEVEMENTS
        .filter(a => a.type === 'streak')
        .sort((a, b) => a.requirement - b.requirement)
      
      for (let i = 1; i < streakAchievements.length; i++) {
        expect(streakAchievements[i].requirement).toBeGreaterThan(streakAchievements[i-1].requirement)
      }
    })

    it('should have increasing calorie requirements', () => {
      const calorieAchievements = ACHIEVEMENTS
        .filter(a => a.type === 'calories')
        .sort((a, b) => a.requirement - b.requirement)
      
      for (let i = 1; i < calorieAchievements.length; i++) {
        expect(calorieAchievements[i].requirement).toBeGreaterThan(calorieAchievements[i-1].requirement)
      }
    })
  })

  describe('icon types', () => {
    it('should have string icon names', () => {
      ACHIEVEMENTS.forEach(achievement => {
        expect(typeof achievement.icon).toBe('string')
        expect(achievement.icon.length).toBeGreaterThan(0)
      })
    })

    it('should use SF Symbol-like names', () => {
      const expectedIcons = ['flame', 'calendar', 'trophy', 'star', 'time', 'rocket']
      ACHIEVEMENTS.forEach(achievement => {
        expect(expectedIcons).toContain(achievement.icon)
      })
    })
  })
})
