import { describe, it, expect, beforeEach } from 'vitest'
import { useUserStore } from '../../shared/stores/userStore'
import type { FitnessLevel, FitnessGoal, WeeklyFrequency } from '../../shared/types'

describe('userStore', () => {
  beforeEach(() => {
    useUserStore.setState({
      profile: {
        name: '',
        email: '',
        joinDate: 'March 2026',
        subscription: 'free',
        onboardingCompleted: false,
        fitnessLevel: 'beginner',
        goal: 'cardio',
        weeklyFrequency: 3,
        barriers: [],
        syncStatus: 'never-synced',
        supabaseUserId: null,
        savedWorkouts: [],
      },
      settings: {
        haptics: true,
        soundEffects: true,
        voiceCoaching: true,
        musicEnabled: true,
        musicVolume: 0.5,
        reminders: false,
        reminderTime: '09:00',
      },
    })
  })

  describe('initial state', () => {
    it('should have correct default profile values', () => {
      const { profile } = useUserStore.getState()
      
      expect(profile.name).toBe('')
      expect(profile.email).toBe('')
      expect(profile.subscription).toBe('free')
      expect(profile.onboardingCompleted).toBe(false)
      expect(profile.fitnessLevel).toBe('beginner')
      expect(profile.goal).toBe('cardio')
      expect(profile.weeklyFrequency).toBe(3)
      expect(profile.barriers).toEqual([])
      expect(profile.syncStatus).toBe('never-synced')
      expect(profile.supabaseUserId).toBeNull()
    })

    it('should have correct default settings values', () => {
      const { settings } = useUserStore.getState()
      
      expect(settings.haptics).toBe(true)
      expect(settings.soundEffects).toBe(true)
      expect(settings.voiceCoaching).toBe(true)
      expect(settings.musicEnabled).toBe(true)
      expect(settings.musicVolume).toBe(0.5)
      expect(settings.reminders).toBe(false)
      expect(settings.reminderTime).toBe('09:00')
    })
  })

  describe('updateProfile', () => {
    it('should update profile fields', () => {
      const store = useUserStore.getState()
      
      store.updateProfile({ name: 'John Doe' })
      expect(useUserStore.getState().profile.name).toBe('John Doe')
    })

    it('should merge updates with existing profile', () => {
      const store = useUserStore.getState()
      
      store.updateProfile({ name: 'Jane' })
      store.updateProfile({ email: 'jane@example.com' })
      
      const profile = useUserStore.getState().profile
      expect(profile.name).toBe('Jane')
      expect(profile.email).toBe('jane@example.com')
    })

    it('should update fitness level', () => {
      const store = useUserStore.getState()
      const levels: FitnessLevel[] = ['beginner', 'intermediate', 'advanced']
      
      levels.forEach((level) => {
        store.updateProfile({ fitnessLevel: level })
        expect(useUserStore.getState().profile.fitnessLevel).toBe(level)
      })
    })

    it('should update fitness goal', () => {
      const store = useUserStore.getState()
      const goals: FitnessGoal[] = ['weight-loss', 'cardio', 'strength', 'wellness']
      
      goals.forEach((goal) => {
        store.updateProfile({ goal })
        expect(useUserStore.getState().profile.goal).toBe(goal)
      })
    })

    it('should update weekly frequency', () => {
      const store = useUserStore.getState()
      const frequencies: WeeklyFrequency[] = [2, 3, 5]
      
      frequencies.forEach((freq) => {
        store.updateProfile({ weeklyFrequency: freq })
        expect(useUserStore.getState().profile.weeklyFrequency).toBe(freq)
      })
    })

    it('should update barriers array', () => {
      const store = useUserStore.getState()
      
      store.updateProfile({ barriers: ['no-time', 'low-motivation'] })
      expect(useUserStore.getState().profile.barriers).toEqual(['no-time', 'low-motivation'])
    })
  })

  describe('updateSettings', () => {
    it('should update individual settings', () => {
      const store = useUserStore.getState()
      
      store.updateSettings({ haptics: false })
      expect(useUserStore.getState().settings.haptics).toBe(false)
    })

    it('should merge updates with existing settings', () => {
      const store = useUserStore.getState()
      
      store.updateSettings({ haptics: false })
      store.updateSettings({ soundEffects: false })
      store.updateSettings({ musicVolume: 0.8 })
      
      const settings = useUserStore.getState().settings
      expect(settings.haptics).toBe(false)
      expect(settings.soundEffects).toBe(false)
      expect(settings.musicVolume).toBe(0.8)
      expect(settings.voiceCoaching).toBe(true)
    })

    it('should update reminder settings', () => {
      const store = useUserStore.getState()
      
      store.updateSettings({ reminders: true, reminderTime: '07:30' })
      
      const settings = useUserStore.getState().settings
      expect(settings.reminders).toBe(true)
      expect(settings.reminderTime).toBe('07:30')
    })
  })

  describe('setSubscription', () => {
    it('should update subscription plan', () => {
      const store = useUserStore.getState()
      
      store.setSubscription('premium-monthly')
      expect(useUserStore.getState().profile.subscription).toBe('premium-monthly')
      
      store.setSubscription('premium-yearly')
      expect(useUserStore.getState().profile.subscription).toBe('premium-yearly')
      
      store.setSubscription('free')
      expect(useUserStore.getState().profile.subscription).toBe('free')
    })
  })

  describe('completeOnboarding', () => {
    it('should set onboarding completed flag', () => {
      const store = useUserStore.getState()
      
      store.completeOnboarding({
        name: 'Test User',
        fitnessLevel: 'intermediate',
        goal: 'strength',
        weeklyFrequency: 5,
        barriers: ['no-time'],
      })
      
      const profile = useUserStore.getState().profile
      expect(profile.onboardingCompleted).toBe(true)
      expect(profile.name).toBe('Test User')
      expect(profile.fitnessLevel).toBe('intermediate')
      expect(profile.goal).toBe('strength')
      expect(profile.weeklyFrequency).toBe(5)
      expect(profile.barriers).toEqual(['no-time'])
    })
  })

  describe('setSyncStatus', () => {
    it('should update sync status', () => {
      const store = useUserStore.getState()
      
      store.setSyncStatus('prompt-pending')
      expect(useUserStore.getState().profile.syncStatus).toBe('prompt-pending')
      
      store.setSyncStatus('synced', 'user-123')
      const profile = useUserStore.getState().profile
      expect(profile.syncStatus).toBe('synced')
      expect(profile.supabaseUserId).toBe('user-123')
    })
  })

  describe('setPromptPending', () => {
    it('should set sync status to prompt-pending', () => {
      const store = useUserStore.getState()
      
      store.setPromptPending()
      expect(useUserStore.getState().profile.syncStatus).toBe('prompt-pending')
    })
  })
})
