import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest'
import { useUserStore } from '../../shared/stores/userStore'
import { ENTITLEMENT_ID } from '../../shared/services/purchases'
import type { SubscriptionPlan } from '../../shared/types'

interface MockCustomerInfo {
  entitlements: {
    active: Record<string, { identifier: string; isActive: boolean }>
    all: Record<string, unknown>
  }
  activeSubscriptions: string[]
  allPurchasedProductIdentifiers: string[]
}

const mockCustomerInfoFree: MockCustomerInfo = {
  entitlements: { active: {}, all: {} },
  activeSubscriptions: [],
  allPurchasedProductIdentifiers: [],
}

const mockCustomerInfoPremium: MockCustomerInfo = {
  entitlements: {
    active: {
      [ENTITLEMENT_ID]: {
        identifier: ENTITLEMENT_ID,
        isActive: true,
      },
    },
    all: {},
  },
  activeSubscriptions: ['tabatafit.premium.yearly'],
  allPurchasedProductIdentifiers: ['tabatafit.premium.yearly'],
}

const mockCustomerInfoMonthly: MockCustomerInfo = {
  entitlements: {
    active: {
      [ENTITLEMENT_ID]: {
        identifier: ENTITLEMENT_ID,
        isActive: true,
      },
    },
    all: {},
  },
  activeSubscriptions: ['tabatafit.premium.monthly'],
  allPurchasedProductIdentifiers: ['tabatafit.premium.monthly'],
}

function hasPremiumEntitlement(info: MockCustomerInfo | null): boolean {
  if (!info) return false
  return ENTITLEMENT_ID in info.entitlements.active
}

function determineSubscriptionPlan(info: MockCustomerInfo): SubscriptionPlan {
  if (!hasPremiumEntitlement(info)) return 'free'

  const activeSubscriptions = info.activeSubscriptions
  if (activeSubscriptions.length === 0) return 'free'

  const subId = activeSubscriptions[0].toLowerCase()
  if (subId.includes('yearly') || subId.includes('annual')) {
    return 'premium-yearly'
  } else if (subId.includes('monthly')) {
    return 'premium-monthly'
  }
  return 'premium-yearly'
}

describe('usePurchases', () => {
  beforeEach(() => {
    vi.clearAllMocks()
    useUserStore.setState({
      profile: {
        name: 'Test User',
        email: 'test@example.com',
        joinDate: new Date().toISOString(),
        subscription: 'free',
        onboardingCompleted: true,
        fitnessLevel: 'beginner',
        goal: 'strength',
        weeklyFrequency: 3,
        barriers: [],
        syncStatus: 'never-synced',
        supabaseUserId: null,
        savedWorkouts: [],
      },
    })
  })

  afterEach(() => {
    vi.restoreAllMocks()
  })

  describe('hasPremiumEntitlement', () => {
    it('should return false for null customerInfo', () => {
      expect(hasPremiumEntitlement(null)).toBe(false)
    })

    it('should return false for free user', () => {
      expect(hasPremiumEntitlement(mockCustomerInfoFree)).toBe(false)
    })

    it('should return true for premium user', () => {
      expect(hasPremiumEntitlement(mockCustomerInfoPremium)).toBe(true)
    })
  })

  describe('determineSubscriptionPlan', () => {
    it('should return free for user without entitlement', () => {
      const plan = determineSubscriptionPlan(mockCustomerInfoFree)
      expect(plan).toBe('free')
    })

    it('should return premium-yearly for annual subscription', () => {
      const plan = determineSubscriptionPlan(mockCustomerInfoPremium)
      expect(plan).toBe('premium-yearly')
    })

    it('should return premium-monthly for monthly subscription', () => {
      const plan = determineSubscriptionPlan(mockCustomerInfoMonthly)
      expect(plan).toBe('premium-monthly')
    })

    it('should return free when activeSubscriptions is empty', () => {
      const info: MockCustomerInfo = {
        ...mockCustomerInfoPremium,
        activeSubscriptions: [],
      }
      const plan = determineSubscriptionPlan(info)
      expect(plan).toBe('free')
    })
  })

  describe('purchasePackage', () => {
    it('should detect user cancellation', () => {
      const error = { userCancelled: true }
      expect(error.userCancelled).toBe(true)
    })

    it('should detect purchase success', () => {
      const success = hasPremiumEntitlement(mockCustomerInfoPremium)
      expect(success).toBe(true)
    })

    it('should detect purchase failure', () => {
      const success = hasPremiumEntitlement(mockCustomerInfoFree)
      expect(success).toBe(false)
    })
  })

  describe('restorePurchases', () => {
    it('should return true when premium is restored', () => {
      const hasPremium = hasPremiumEntitlement(mockCustomerInfoPremium)
      expect(hasPremium).toBe(true)
    })

    it('should return false when no purchases to restore', () => {
      const hasPremium = hasPremiumEntitlement(mockCustomerInfoFree)
      expect(hasPremium).toBe(false)
    })
  })

  describe('subscription sync to store', () => {
    it('should sync premium-yearly to userStore', () => {
      const plan = determineSubscriptionPlan(mockCustomerInfoPremium)
      useUserStore.getState().setSubscription(plan)

      expect(useUserStore.getState().profile.subscription).toBe('premium-yearly')
    })

    it('should sync premium-monthly to userStore', () => {
      const plan = determineSubscriptionPlan(mockCustomerInfoMonthly)
      useUserStore.getState().setSubscription(plan)

      expect(useUserStore.getState().profile.subscription).toBe('premium-monthly')
    })

    it('should sync free to userStore', () => {
      const plan = determineSubscriptionPlan(mockCustomerInfoFree)
      useUserStore.getState().setSubscription(plan)

      expect(useUserStore.getState().profile.subscription).toBe('free')
    })
  })

  describe('package identification', () => {
    it('should identify monthly package by identifier', () => {
      const pkg = {
        identifier: 'monthly',
        product: { identifier: 'tabatafit.premium.monthly', priceString: '$9.99' },
      }
      const isMonthly = pkg.identifier === 'monthly'
      expect(isMonthly).toBe(true)
    })

    it('should identify annual package by identifier', () => {
      const pkg = {
        identifier: 'annual',
        product: { identifier: 'tabatafit.premium.yearly', priceString: '$79.99' },
      }
      const isAnnual = pkg.identifier === 'annual'
      expect(isAnnual).toBe(true)
    })
  })

  describe('price calculations', () => {
    it('should format monthly price', () => {
      const price = '$9.99'
      expect(price).toBe('$9.99')
    })

    it('should format annual price', () => {
      const price = '$79.99'
      expect(price).toBe('$79.99')
    })

    it('should calculate annual savings', () => {
      const monthlyPrice = 9.99
      const annualPrice = 79.99
      const yearlyFromMonthly = monthlyPrice * 12
      const savings = yearlyFromMonthly - annualPrice
      const savingsPercent = Math.round((savings / yearlyFromMonthly) * 100)

      expect(savings).toBeCloseTo(39.89, 0)
      expect(savingsPercent).toBe(33)
    })

    it('should calculate monthly equivalent of annual', () => {
      const annualPrice = 79.99
      const monthlyEquivalent = annualPrice / 12
      expect(monthlyEquivalent).toBeCloseTo(6.67, 1)
    })
  })

  describe('entitlement ID', () => {
    it('should use correct entitlement ID', () => {
      expect(ENTITLEMENT_ID).toBe('1000 Corp Pro')
    })
  })
})
