bookwiz.io / lib / hooks / useUsageStats.ts
useUsageStats.ts
Raw
'use client'

import { useState, useEffect, useRef } from 'react'
import { useAuth } from '@/components/AuthProvider'
import { useUsageRefresh } from '@/lib/contexts/UsageContext'

export interface UsageStats {
  booksCreated: number
  totalWords: number
  smartPrompts: number
  smartPromptsLimit: number
  fastPrompts: number
  fastPromptsLimit: number
}

export function useUsageStats() {
  const { user } = useAuth()
  const { registerRefreshFunction } = useUsageRefresh()
  const [usageStats, setUsageStats] = useState<UsageStats>({
    booksCreated: 0,
    totalWords: 0,
    smartPrompts: 0,
    smartPromptsLimit: 0,
    fastPrompts: 0,
    fastPromptsLimit: 0
  })
  const [loading, setLoading] = useState(true)
  const [error, setError] = useState<string | null>(null)
  const currentUserId = useRef<string | null>(null)
  const lastFetchTime = useRef<number>(0)
  const isFetching = useRef<boolean>(false)

  useEffect(() => {
    if (!user?.id) {
      setLoading(false)
      currentUserId.current = null
      lastFetchTime.current = 0
      return
    }

    // Only fetch if user changed or we haven't fetched for this user yet
    if (currentUserId.current !== user.id || lastFetchTime.current === 0) {
      currentUserId.current = user.id
      fetchUsageStats()
    }
  }, [user?.id])

  const fetchUsageStats = async () => {
    if (!user?.id || isFetching.current) return

    try {
      isFetching.current = true
      setLoading(true)
      setError(null)
      
      const response = await fetch(`/api/usage/stats?userId=${user.id}&t=${Date.now()}`)
      if (!response.ok) {
        throw new Error('Failed to fetch usage stats')
      }
      
      const data = await response.json()
      
      setUsageStats(data)
      lastFetchTime.current = Date.now()
    } catch (error) {
      console.error('Error fetching usage stats:', error)
      setError('Failed to load usage statistics')
    } finally {
      setLoading(false)
      isFetching.current = false
    }
  }

  // Force refresh by fetching fresh data
  const refetch = () => {
    if (!isFetching.current) {
      fetchUsageStats()
    }
  }

  // Register refetch function with usage context
  useEffect(() => {
    registerRefreshFunction(refetch)
  }, [registerRefreshFunction])

  const getSmartUsagePercentage = () => {
    if (usageStats.smartPromptsLimit === 0) return 0
    return Math.min((usageStats.smartPrompts / usageStats.smartPromptsLimit) * 100, 100)
  }

  const getFastUsagePercentage = () => {
    if (usageStats.fastPromptsLimit === 0) return 0
    if (usageStats.fastPromptsLimit > 99999) return Math.min((usageStats.fastPrompts / 100) * 100, 100) // Show progress for unlimited plans based on a small scale
    return Math.min((usageStats.fastPrompts / usageStats.fastPromptsLimit) * 100, 100)
  }

  // Optimistic update for immediate UI feedback
  const updateUsageOptimistically = (tier: 'smart' | 'fast', increment: number = 1) => {
    setUsageStats(prev => ({
      ...prev,
      smartPrompts: tier === 'smart' ? prev.smartPrompts + increment : prev.smartPrompts,
      fastPrompts: tier === 'fast' ? prev.fastPrompts + increment : prev.fastPrompts
    }))
  }

  return {
    usageStats,
    loading,
    error,
    getSmartUsagePercentage,
    getFastUsagePercentage,
    refetch,
    updateUsageOptimistically
  }
}