'use client'

/**
 * useAvatarCache — cache de avatares em IndexedDB.
 *
 * Chave de cache: `${jid}:${version}` (version = hash curto do avatarUrl no banco).
 * Quando a versão muda (novo avatar no banco), a chave muda e o cache invalida
 * automaticamente — sem TTL fixo, sem stale data visível ao usuário.
 *
 * Armazenamento: dataURL base64 do JPEG/WebP (compatível com <img src>).
 * Limpeza: entradas com mais de 30 dias são removidas na abertura do DB.
 */

const DB_NAME    = 'nw-avatars'
const STORE_NAME = 'blobs'
const DB_VERSION = 1
const MAX_AGE_MS = 30 * 24 * 60 * 60 * 1000 // 30 dias

interface CacheEntry {
  key: string     // `${jid}:${version}`
  dataUrl: string
  savedAt: number
}

let dbPromise: Promise<IDBDatabase> | null = null

function openDB(): Promise<IDBDatabase> {
  if (dbPromise) return dbPromise
  dbPromise = new Promise((resolve, reject) => {
    const req = indexedDB.open(DB_NAME, DB_VERSION)
    req.onupgradeneeded = () => {
      const db = req.result
      if (!db.objectStoreNames.contains(STORE_NAME)) {
        db.createObjectStore(STORE_NAME, { keyPath: 'key' })
      }
    }
    req.onsuccess = () => {
      const db = req.result
      pruneOldEntries(db)
      resolve(db)
    }
    req.onerror = () => { dbPromise = null; reject(req.error) }
  })
  return dbPromise
}

function pruneOldEntries(db: IDBDatabase): void {
  const tx    = db.transaction(STORE_NAME, 'readwrite')
  const store = tx.objectStore(STORE_NAME)
  const cutoff = Date.now() - MAX_AGE_MS
  const req = store.openCursor()
  req.onsuccess = () => {
    const cursor = req.result
    if (!cursor) return
    if ((cursor.value as CacheEntry).savedAt < cutoff) cursor.delete()
    cursor.continue()
  }
}

export async function getAvatarFromCache(jid: string, version: string): Promise<string | null> {
  if (typeof window === 'undefined') return null
  try {
    const db    = await openDB()
    const key   = `${jid}:${version}`
    return new Promise((resolve) => {
      const tx  = db.transaction(STORE_NAME, 'readonly')
      const req = tx.objectStore(STORE_NAME).get(key)
      req.onsuccess = () => resolve((req.result as CacheEntry | undefined)?.dataUrl ?? null)
      req.onerror   = () => resolve(null)
    })
  } catch {
    return null
  }
}

export async function setAvatarInCache(jid: string, version: string, dataUrl: string): Promise<void> {
  if (typeof window === 'undefined') return
  try {
    const db  = await openDB()
    const key = `${jid}:${version}`
    await new Promise<void>((resolve, reject) => {
      const tx    = db.transaction(STORE_NAME, 'readwrite')
      const entry: CacheEntry = { key, dataUrl, savedAt: Date.now() }
      const req   = tx.objectStore(STORE_NAME).put(entry)
      req.onsuccess = () => resolve()
      req.onerror   = () => reject(req.error)
    })
  } catch { /* quota exceeded ou IDB indisponível — ignora silenciosamente */ }
}
