// In-memory + localStorage cache for ALL products — fetched once at app
// startup so navigation between catalog pages is instant (no per-page API
// calls).
//
// The full catalog (~540 products, ~480KB JSON) is small enough to hold in
// memory AND persist to localStorage. This means:
//   - First visit: shows a brief loading overlay while downloading
//   - Return visits (< 24h): catalog is available INSTANTLY from localStorage
//   - All page navigations: zero API calls (filtered client-side)
import type { Product } from '@/lib/types'

const STORAGE_KEY = 'abelha-rainha-products-cache-v14'
const CACHE_TTL_MS = 24 * 60 * 60 * 1000 // 24 hours

let productsPromise: Promise<Product[]> | null = null
let cachedProducts: Product[] | null = null

interface StoredCache {
  products: Product[]
  timestamp: number
}

/** Load the persisted cache from localStorage (if fresh enough). */
function loadFromStorage(): Product[] | null {
  if (typeof window === 'undefined') return null
  try {
    const raw = localStorage.getItem(STORAGE_KEY)
    if (!raw) return null
    const stored = JSON.parse(raw) as StoredCache
    if (!stored?.products || !Array.isArray(stored.products)) return null
    if (Date.now() - stored.timestamp > CACHE_TTL_MS) return null
    return stored.products
  } catch {
    return null // corrupt JSON or quota issue — ignore
  }
}

/** Save the cache to localStorage for next visit. */
function saveToStorage(products: Product[]) {
  if (typeof window === 'undefined') return
  try {
    const stored: StoredCache = { products, timestamp: Date.now() }
    localStorage.setItem(STORAGE_KEY, JSON.stringify(stored))
  } catch {
    // localStorage quota exceeded or unavailable — the in-memory cache
    // still works for this session, just won't persist across reloads.
  }
}

export function fetchAllProducts(): Promise<Product[]> {
  // 1. In-memory copy (fastest)
  if (cachedProducts) return Promise.resolve(cachedProducts)
  // 2. Reuse in-flight promise (dedupes concurrent callers)
  if (!productsPromise) {
    // 3. Try localStorage (instant — no network)
    const fromStorage = loadFromStorage()
    if (fromStorage && fromStorage.length > 0) {
      cachedProducts = fromStorage
      productsPromise = Promise.resolve(fromStorage)
      return productsPromise
    }
    // 4. Fall back to network fetch
    productsPromise = fetch('/api/products?limit=2000')
      .then(r => r.json())
      .then(res => {
        if (res.data) {
          cachedProducts = res.data as Product[]
          saveToStorage(cachedProducts)
          return cachedProducts
        }
        throw new Error('No products data')
      })
      .catch(err => {
        productsPromise = null // allow retry on next call
        throw err
      })
  }
  return productsPromise
}

/** Synchronous access to the cached products (null if not loaded yet). */
export function getCachedProducts(): Product[] | null {
  if (cachedProducts) return cachedProducts
  // Try localStorage synchronously so the very first render can have data
  const fromStorage = loadFromStorage()
  if (fromStorage) {
    cachedProducts = fromStorage
    return cachedProducts
  }
  return null
}

/** Force a refresh (e.g. after admin edits a product). */
export function refreshProductsCache(): Promise<Product[]> {
  cachedProducts = null
  productsPromise = null
  return fetchAllProducts()
}
