/**
 * Global Cache Service
 * 全局缓存服务 - 支持多种数据类型和不同的缓存策略
 * 
 * 缓存策略：
 * - registries: 30分钟 (registry 配置变化不频繁)
 * - repositories: 10分钟 (repository 列表相对稳定)
 * - tags: 5分钟 (tags 可能会更新，但也不是很频繁)
 * - clusters: 30分钟 (cluster 配置变化不频繁)
 * - instances: 2分钟 (instance 状态需要相对实时)
 */

import type { ArtifactListItem } from "@/api";

interface CacheEntry<T = any> {
  data: T;
  timestamp: number;
  loading: boolean;
}

type CacheType = 'registries' | 'repositories' | 'tags' | 'clusters' | 'instances';

// 不同数据类型的缓存时长配置（毫秒）
const CACHE_TTL: Record<CacheType, number> = {
  registries: 30 * 60 * 1000,   // 30分钟 - registry配置很少变化
  repositories: 10 * 60 * 1000,  // 10分钟 - repository列表相对稳定
  tags: 5 * 60 * 1000,           // 5分钟 - tags可能会更新
  clusters: 30 * 60 * 1000,      // 30分钟 - cluster配置很少变化
  instances: 2 * 60 * 1000,      // 2分钟 - instance状态需要相对实时
};

class GlobalCache {
  private cache: Map<string, CacheEntry> = new Map();

  /**
   * 生成缓存键
   */
  private getKey(type: CacheType, ...identifiers: string[]): string {
    return `${type}:${identifiers.join(':')}`;
  }

  /**
   * 获取缓存数据
   */
  get<T = any>(type: CacheType, ...identifiers: string[]): T | null {
    const key = this.getKey(type, ...identifiers);
    const entry = this.cache.get(key);

    if (!entry) {
      return null;
    }

    // 检查是否过期
    const ttl = CACHE_TTL[type];
    if (Date.now() - entry.timestamp > ttl) {
      console.log(`[GlobalCache] 缓存过期: ${key} (TTL: ${ttl}ms)`);
      this.cache.delete(key);
      return null;
    }

    console.log(`[GlobalCache] 命中缓存: ${key} (age: ${Math.floor((Date.now() - entry.timestamp) / 1000)}s)`);
    return entry.data as T;
  }

  /**
   * 设置缓存数据
   */
  set<T = any>(type: CacheType, data: T, ...identifiers: string[]): void {
    const key = this.getKey(type, ...identifiers);
    this.cache.set(key, {
      data,
      timestamp: Date.now(),
      loading: false,
    });
    console.log(`[GlobalCache] 已缓存: ${key} (TTL: ${CACHE_TTL[type]}ms)`);
  }

  /**
   * 标记为加载中
   */
  setLoading(type: CacheType, ...identifiers: string[]): void {
    const key = this.getKey(type, ...identifiers);
    const existing = this.cache.get(key);
    
    if (existing) {
      existing.loading = true;
    } else {
      this.cache.set(key, {
        data: null,
        timestamp: Date.now(),
        loading: true,
      });
    }
  }

  /**
   * 检查是否正在加载
   */
  isLoading(type: CacheType, ...identifiers: string[]): boolean {
    const key = this.getKey(type, ...identifiers);
    const entry = this.cache.get(key);
    return entry?.loading || false;
  }

  /**
   * 清除特定缓存
   */
  clear(type: CacheType, ...identifiers: string[]): void {
    const key = this.getKey(type, ...identifiers);
    this.cache.delete(key);
    console.log(`[GlobalCache] 已清除: ${key}`);
  }

  /**
   * 清除某个类型的所有缓存
   */
  clearType(type: CacheType): void {
    const prefix = `${type}:`;
    let count = 0;
    for (const key of this.cache.keys()) {
      if (key.startsWith(prefix)) {
        this.cache.delete(key);
        count++;
      }
    }
    console.log(`[GlobalCache] 已清除 ${count} 个 ${type} 缓存`);
  }

  /**
   * 清除所有缓存
   */
  clearAll(): void {
    const size = this.cache.size;
    this.cache.clear();
    console.log(`[GlobalCache] 已清除所有缓存 (${size} 个条目)`);
  }

  /**
   * 获取缓存统计信息
   */
  getStats(): { type: string; count: number; ttl: string }[] {
    const stats = new Map<CacheType, number>();
    
    for (const key of this.cache.keys()) {
      const type = key.split(':')[0] as CacheType;
      stats.set(type, (stats.get(type) || 0) + 1);
    }

    return Array.from(stats.entries()).map(([type, count]) => ({
      type,
      count,
      ttl: `${CACHE_TTL[type] / 1000}s`,
    }));
  }
}

// 单例导出
export const globalCache = new GlobalCache();

// 兼容旧的 artifactCache
export const artifactCache = {
  get: (registryId: string, repository: string) =>
    globalCache.get<ArtifactListItem[]>('tags', registryId, repository),
  set: (registryId: string, repository: string, data: ArtifactListItem[]) =>
    globalCache.set('tags', data, registryId, repository),
  setLoading: (registryId: string, repository: string) => 
    globalCache.setLoading('tags', registryId, repository),
  isLoading: (registryId: string, repository: string) => 
    globalCache.isLoading('tags', registryId, repository),
  clear: (registryId: string, repository: string) => 
    globalCache.clear('tags', registryId, repository),
  clearAll: () => globalCache.clearType('tags'),
};
