interface CacheEntry {
  data: any;
  cachedAt: Date;
}

class OrgStructureCache {
  private cache: Map<string, CacheEntry> = new Map();
  private readonly CACHE_TTL = 30 * 60 * 1000; // 30 minutes
  private isInitialized = false;
  private cleanupTimer: NodeJS.Timeout | null = null;

  constructor() {
    // Don't auto-initialize - wait for AppDataSource to be ready
  }

  initialize() {
    if (this.isInitialized) return;

    this.isInitialized = true;
    // Cleanup expired entries every 30 minutes
    this.cleanupTimer = setInterval(() => {
      this.cleanup();
    }, this.CACHE_TTL);

    console.log("[OrgStructureCache] Initialized");
  }

  private generateKey(revisionId: string, rootId?: string): string {
    return `org-structure-${revisionId}-${rootId || "all"}`;
  }

  private cleanup() {
    const now = Date.now();
    let cleaned = 0;

    for (const [key, entry] of this.cache.entries()) {
      const age = now - entry.cachedAt.getTime();
      if (age > this.CACHE_TTL) {
        this.cache.delete(key);
        cleaned++;
      }
    }

    if (cleaned > 0) {
      console.log(`[OrgStructureCache] Cleaned ${cleaned} expired entries`);
    }
  }

  async get(revisionId: string, rootId?: string): Promise<any | null> {
    const key = this.generateKey(revisionId, rootId);
    const entry = this.cache.get(key);

    if (!entry) {
      return null;
    }

    // Check if expired
    const age = Date.now() - entry.cachedAt.getTime();
    if (age > this.CACHE_TTL) {
      this.cache.delete(key);
      return null;
    }

    console.log(`[OrgStructureCache] HIT: ${key}`);
    return entry.data;
  }

  async set(revisionId: string, rootId: string | undefined, data: any): Promise<void> {
    const key = this.generateKey(revisionId, rootId);
    this.cache.set(key, {
      data,
      cachedAt: new Date(),
    });
    console.log(`[OrgStructureCache] SET: ${key}`);
  }

  invalidate(revisionId: string): void {
    // Invalidate all entries for this revision
    for (const key of this.cache.keys()) {
      if (key.startsWith(`org-structure-${revisionId}`)) {
        this.cache.delete(key);
      }
    }
    console.log(`[OrgStructureCache] INVALIDATED: ${revisionId}`);
  }

  destroy() {
    if (this.cleanupTimer) {
      clearInterval(this.cleanupTimer);
      this.cleanupTimer = null;
    }
    this.cache.clear();
  }
}

export const orgStructureCache = new OrgStructureCache();
