/**
 * TabataFit Purchases Hook
 * Wraps RevenueCat API for subscription management
 *
 * DEV mode: If StoreKit purchase fails (no sandbox account / product mismatch),
 * shows an Alert offering to simulate the purchase for testing.
 */

import { useState, useEffect, useCallback } from 'react'
import { Alert } from 'react-native'
import Purchases, {
  CustomerInfo,
  PurchasesOfferings,
  PurchasesPackage,
} from 'react-native-purchases'

import { useUserStore } from '../stores'
import { ENTITLEMENT_ID } from '../services/purchases'
import type { SubscriptionPlan } from '../types'

interface PurchaseResult {
  success: boolean
  cancelled: boolean
  error?: string
}

interface UsePurchasesReturn {
  isPremium: boolean
  isLoading: boolean
  monthlyPackage: PurchasesPackage | null
  annualPackage: PurchasesPackage | null
  purchasePackage: (pkg: PurchasesPackage) => Promise<PurchaseResult>
  restorePurchases: () => Promise<boolean>
}

/**
 * Helper to check if user has premium entitlement
 */
function hasPremiumEntitlement(info: CustomerInfo | null): boolean {
  if (!info) return false
  return ENTITLEMENT_ID in info.entitlements.active
}

/**
 * Hook to manage RevenueCat subscriptions
 * Syncs subscription state with userStore
 */
export function usePurchases(): UsePurchasesReturn {
  const [isLoading, setIsLoading] = useState(true)
  const [offerings, setOfferings] = useState<PurchasesOfferings | null>(null)
  const [customerInfo, setCustomerInfo] = useState<CustomerInfo | null>(null)

  const subscription = useUserStore((s) => s.profile.subscription)
  const setSubscription = useUserStore((s) => s.setSubscription)

  // Derive premium status from RevenueCat entitlement or local state
  const isPremium = customerInfo
    ? hasPremiumEntitlement(customerInfo)
    : subscription !== 'free'

  // Get packages from offerings
  const monthlyPackage = offerings?.current?.monthly ?? null
  const annualPackage = offerings?.current?.annual ?? null

  // Sync RevenueCat state to userStore
  const syncSubscriptionToStore = useCallback(
    (info: CustomerInfo | null) => {
      if (!info) return

      const hasPremium = hasPremiumEntitlement(info)
      const activeSubscriptions = info.activeSubscriptions

      let newPlan: SubscriptionPlan = 'free'

      if (hasPremium && activeSubscriptions.length > 0) {
        // Determine plan type from subscription identifier
        const subId = activeSubscriptions[0].toLowerCase()
        if (subId.includes('yearly') || subId.includes('annual')) {
          newPlan = 'premium-yearly'
        } else if (subId.includes('monthly')) {
          newPlan = 'premium-monthly'
        } else {
          // Default to yearly for any premium entitlement
          newPlan = 'premium-yearly'
        }
      }

      // Only update if different
      if (subscription !== newPlan) {
        console.log('[Purchases] Syncing subscription to store:', newPlan)
        setSubscription(newPlan)
      }
    },
    [subscription, setSubscription]
  )

  // Fetch offerings and customer info on mount
  useEffect(() => {
    const fetchData = async () => {
      try {
        const [offeringsResult, customerInfoResult] = await Promise.all([
          Purchases.getOfferings(),
          Purchases.getCustomerInfo(),
        ])

        setOfferings(offeringsResult)
        setCustomerInfo(customerInfoResult)
        syncSubscriptionToStore(customerInfoResult)

        console.log('[Purchases] Offerings loaded:', {
          hasMonthly: !!offeringsResult.current?.monthly,
          hasAnnual: !!offeringsResult.current?.annual,
          monthlyProductId: offeringsResult.current?.monthly?.product.identifier,
          annualProductId: offeringsResult.current?.annual?.product.identifier,
          monthlyPrice: offeringsResult.current?.monthly?.product.priceString,
          annualPrice: offeringsResult.current?.annual?.product.priceString,
        })
      } catch (error) {
        console.error('[Purchases] Failed to fetch offerings/customerInfo:', error)
      } finally {
        setIsLoading(false)
      }
    }

    fetchData()
  }, [syncSubscriptionToStore])

  // Listen for customer info changes (renewals, expirations, etc.)
  useEffect(() => {
    const listener = (info: CustomerInfo) => {
      console.log('[Purchases] Customer info updated')
      setCustomerInfo(info)
      syncSubscriptionToStore(info)
    }

    Purchases.addCustomerInfoUpdateListener(listener)

    return () => {
      Purchases.removeCustomerInfoUpdateListener(listener)
    }
  }, [syncSubscriptionToStore])

  // Purchase a package
  const purchasePackage = useCallback(
    async (pkg: PurchasesPackage): Promise<PurchaseResult> => {
      try {
        console.log('[Purchases] Starting purchase for:', pkg.identifier, pkg.product.identifier)
        const { customerInfo: newInfo } = await Purchases.purchasePackage(pkg)

        setCustomerInfo(newInfo)
        syncSubscriptionToStore(newInfo)

        const success = hasPremiumEntitlement(newInfo)
        console.log('[Purchases] Purchase result:', { success })

        return { success, cancelled: false }
      } catch (error: any) {
        // Handle user cancellation
        if (error.userCancelled) {
          console.log('[Purchases] Purchase cancelled by user')
          return { success: false, cancelled: true }
        }

        console.error('[Purchases] Purchase error:', error)

        // DEV mode: offer to simulate the purchase when StoreKit fails
        if (__DEV__) {
          return new Promise((resolve) => {
            Alert.alert(
              'Purchase failed (DEV)',
              `StoreKit error: ${error.message || 'Unknown error'}\n\nProduct: ${pkg.product.identifier}\n\nSimulate a successful purchase for testing?`,
              [
                {
                  text: 'Cancel',
                  style: 'cancel',
                  onPress: () =>
                    resolve({ success: false, cancelled: true }),
                },
                {
                  text: 'Simulate Purchase',
                  onPress: () => {
                    // Determine plan from package identifier
                    const id = pkg.product.identifier.toLowerCase()
                    const plan: SubscriptionPlan =
                      id.includes('annual') || id.includes('year')
                        ? 'premium-yearly'
                        : 'premium-monthly'
                    setSubscription(plan)
                    console.log('[Purchases] DEV: Simulated purchase →', plan)
                    resolve({ success: true, cancelled: false })
                  },
                },
              ]
            )
          })
        }

        return {
          success: false,
          cancelled: false,
          error: error.message || 'Purchase failed',
        }
      }
    },
    [syncSubscriptionToStore, setSubscription]
  )

  // Restore purchases
  const restorePurchases = useCallback(async (): Promise<boolean> => {
    try {
      console.log('[Purchases] Restoring purchases...')
      const restoredInfo = await Purchases.restorePurchases()

      setCustomerInfo(restoredInfo)
      syncSubscriptionToStore(restoredInfo)

      const hasPremium = hasPremiumEntitlement(restoredInfo)
      console.log('[Purchases] Restore result:', { hasPremium })

      return hasPremium
    } catch (error) {
      console.error('[Purchases] Restore failed:', error)

      // DEV mode: offer to simulate restore
      if (__DEV__) {
        return new Promise((resolve) => {
          Alert.alert(
            'Restore failed (DEV)',
            'Simulate a restored premium subscription?',
            [
              { text: 'Cancel', style: 'cancel', onPress: () => resolve(false) },
              {
                text: 'Simulate Restore',
                onPress: () => {
                  setSubscription('premium-yearly')
                  console.log('[Purchases] DEV: Simulated restore → premium-yearly')
                  resolve(true)
                },
              },
            ]
          )
        })
      }

      return false
    }
  }, [syncSubscriptionToStore, setSubscription])

  return {
    isPremium,
    isLoading,
    monthlyPackage,
    annualPackage,
    purchasePackage,
    restorePurchases,
  }
}
