import crypto from 'crypto'
import type { PDFReport } from './types'

interface CacheEntry {
  pdfBuffer: Buffer
  hash: string
  expiresAt: number
  createdAt: number
  hits: number
}

export class PDFCacheManager {
  private cache: Map<string, CacheEntry> = new Map()
  private readonly TTL_MS = 5 * 60 * 1000
  private cleanupInterval: NodeJS.Timer | null = null

  constructor() {
    this.startCleanup()
  }

  private startCleanup(): void {
    this.cleanupInterval = setInterval(() => {
      const now = Date.now()
      let removed = 0

      for (const [key, entry] of this.cache.entries()) {
        if (now > entry.expiresAt) {
          this.cache.delete(key)
          removed++
        }
      }

      if (removed > 0) {
        console.log(`[PDFCache] Removed ${removed} expired entries`)
      }
    }, 60000)

    if (this.cleanupInterval.unref) {
      this.cleanupInterval.unref()
    }
  }

  get(cacheKey: string): CacheEntry | null {
    const entry = this.cache.get(cacheKey)

    if (!entry) return null

    if (Date.now() > entry.expiresAt) {
      this.cache.delete(cacheKey)
      return null
    }

    entry.hits++
    return entry
  }

  set(cacheKey: string, pdfBuffer: Buffer): void {
    const hash = crypto.createHash('sha256').update(pdfBuffer).digest('hex')
    const now = Date.now()

    this.cache.set(cacheKey, {
      pdfBuffer,
      hash,
      expiresAt: now + this.TTL_MS,
      createdAt: now,
      hits: 0,
    })

    console.log(`[PDFCache] Cached PDF: ${cacheKey} (${pdfBuffer.length} bytes)`)
  }

  generateKey(asn: number, format: string, date: string): string {
    return crypto
      .createHash('md5')
      .update(`${asn}:${format}:${date}`)
      .digest('hex')
  }

  getStats(): { size: number; entries: number; totalMemory: number } {
    let totalMemory = 0

    for (const entry of this.cache.values()) {
      totalMemory += entry.pdfBuffer.length
    }

    return {
      size: this.cache.size,
      entries: this.cache.size,
      totalMemory,
    }
  }

  clear(): void {
    this.cache.clear()
    console.log('[PDFCache] Cache cleared')
  }

  destroy(): void {
    if (this.cleanupInterval) {
      clearInterval(this.cleanupInterval)
    }
    this.clear()
  }
}
