/**
 * 缓存数据源实现
 * 基于内存和 AsyncStorage 的混合缓存实现
 */

import AsyncStorage from '@react-native-async-storage/async-storage';
import { ICacheDataSource, DataSourceError } from './interfaces';

interface CacheEntry<T> {
  value: T;
  expiry: number | null; // null 表示永不过期
}

export class CacheDataSource implements ICacheDataSource {
  private memoryCache: Map<string, CacheEntry<any>> = new Map();
  private maxSize: number;
  private defaultTtl: number; // 默认过期时间（毫秒）
  private persistPrefix: string;

  constructor(config?: {
    maxSize?: number;
    defaultTtl?: number; // 默认5分钟
    persistPrefix?: string;
  }) {
    this.maxSize = config?.maxSize || 100;
    this.defaultTtl = config?.defaultTtl || 5 * 60 * 1000;
    this.persistPrefix = config?.persistPrefix || 'cache_';
  }

  /**
   * 检查 key 是否过期
   */
  private isExpired(entry: CacheEntry<any>): boolean {
    if (entry.expiry === null) return false;
    return Date.now() > entry.expiry;
  }

  /**
   * 清理过期缓存
   */
  private cleanup(): void {
    const now = Date.now();
    for (const [key, entry] of this.memoryCache.entries()) {
      if (entry.expiry !== null && now > entry.expiry) {
        this.memoryCache.delete(key);
      }
    }

    // 如果仍然超过最大大小，删除最旧的条目
    while (this.memoryCache.size > this.maxSize) {
      const firstKey = this.memoryCache.keys().next().value;
      if (firstKey !== undefined) {
        this.memoryCache.delete(firstKey);
      }
    }
  }

  /**
   * 生成持久化存储 key
   */
  private getPersistKey(key: string): string {
    return `${this.persistPrefix}${key}`;
  }

  // ==================== ICacheDataSource 实现 ====================

  async get<T>(key: string): Promise<T | null> {
    try {
      // 先检查内存缓存
      const memoryEntry = this.memoryCache.get(key);
      if (memoryEntry) {
        if (!this.isExpired(memoryEntry)) {
          return memoryEntry.value as T;
        }
        // 过期了，从内存中删除
        this.memoryCache.delete(key);
      }

      // 尝试从持久化存储读取
      const persistKey = this.getPersistKey(key);
      const stored = await AsyncStorage.getItem(persistKey);
      if (stored) {
        const entry: CacheEntry<T> = JSON.parse(stored);
        if (!this.isExpired(entry)) {
          // 重新加载到内存缓存
          this.memoryCache.set(key, entry);
          this.cleanup();
          return entry.value;
        }
        // 过期了，删除
        await AsyncStorage.removeItem(persistKey);
      }

      return null;
    } catch (error) {
      console.warn(`[CacheDataSource] Failed to get ${key}:`, error);
      return null;
    }
  }

  async set<T>(key: string, value: T, ttl?: number): Promise<void> {
    try {
      const expiry = ttl === undefined 
        ? (this.defaultTtl > 0 ? Date.now() + this.defaultTtl : null)
        : (ttl > 0 ? Date.now() + ttl : null);

      const entry: CacheEntry<T> = { value, expiry };

      // 存入内存
      this.memoryCache.set(key, entry);
      this.cleanup();

      // 持久化存储（重要数据）
      if (ttl === undefined || ttl > 0) {
        const persistKey = this.getPersistKey(key);
        await AsyncStorage.setItem(persistKey, JSON.stringify(entry));
      }
    } catch (error) {
      throw new DataSourceError(
        `Failed to set cache ${key}`,
        'CACHE_SET_ERROR',
        'CacheDataSource',
        error instanceof Error ? error : undefined
      );
    }
  }

  async delete(key: string): Promise<void> {
    try {
      // 从内存删除
      this.memoryCache.delete(key);

      // 从持久化存储删除
      const persistKey = this.getPersistKey(key);
      await AsyncStorage.removeItem(persistKey);
    } catch (error) {
      throw new DataSourceError(
        `Failed to delete cache ${key}`,
        'CACHE_DELETE_ERROR',
        'CacheDataSource',
        error instanceof Error ? error : undefined
      );
    }
  }

  async clear(): Promise<void> {
    try {
      // 清空内存
      this.memoryCache.clear();

      // 清空持久化存储中的所有缓存项
      const keys = await AsyncStorage.getAllKeys();
      const cacheKeys = keys.filter(k => k.startsWith(this.persistPrefix));
      if (cacheKeys.length > 0) {
        await AsyncStorage.multiRemove(cacheKeys);
      }
    } catch (error) {
      throw new DataSourceError(
        'Failed to clear cache',
        'CACHE_CLEAR_ERROR',
        'CacheDataSource',
        error instanceof Error ? error : undefined
      );
    }
  }

  async has(key: string): Promise<boolean> {
    try {
      // 检查内存
      const memoryEntry = this.memoryCache.get(key);
      if (memoryEntry && !this.isExpired(memoryEntry)) {
        return true;
      }

      // 检查持久化存储
      const persistKey = this.getPersistKey(key);
      const stored = await AsyncStorage.getItem(persistKey);
      if (stored) {
        const entry: CacheEntry<any> = JSON.parse(stored);
        return !this.isExpired(entry);
      }

      return false;
    } catch (error) {
      return false;
    }
  }

  async getMultiple<T>(keys: string[]): Promise<(T | null)[]> {
    return Promise.all(keys.map(key => this.get<T>(key)));
  }

  async setMultiple<T>(entries: { key: string; value: T; ttl?: number }[]): Promise<void> {
    await Promise.all(entries.map(entry => this.set(entry.key, entry.value, entry.ttl)));
  }
}

// 导出单例实例
export const cacheDataSource = new CacheDataSource();
