/**
 * 存储类，用于处理 localStorage 和 sessionStorage
 * 支持设置过期时间、JSON对象存储等功能
 */

// 存储项的数据结构
interface StorageData<T = any> {
  value: T; // 存储的值
  expire?: number; // 过期时间的时间戳
}

// 存储类型
type StorageType = 'localStorage' | 'sessionStorage';

/**
 * 存储类，提供对 localStorage 和 sessionStorage 的封装
 * 支持设置过期时间、JSON对象存储等功能
 */
class Storage {
  private storage: globalThis.Storage;

  /**
   * 构造函数
   * @param type 存储类型，可选 'localStorage' 或 'sessionStorage'
   */
  constructor(type: StorageType = 'localStorage') {
    this.storage = type === 'localStorage' ? window.localStorage : window.sessionStorage;
  }

  /**
   * 设置存储项
   * @param key 键名
   * @param value 值
   * @param expire 过期时间（单位：毫秒），不设置则永不过期
   */
  set<T>(key: string, value: T, expire?: number): void {
    const data: StorageData<T> = {
      value
    };
    
    // 如果设置了过期时间，计算过期的时间戳
    if (expire) {
      data.expire = Date.now() + expire;
    }
    
    // 将数据转换为 JSON 字符串存储
    this.storage.setItem(key, JSON.stringify(data));
  }

  /**
   * 获取存储项
   * @param key 键名
   * @returns 存储的值，如果不存在或已过期则返回 null
   */
  get<T>(key: string): T | null {
    const item = this.storage.getItem(key);
    
    // 如果项不存在，返回 null
    if (!item) return null;
    
    try {
      const data: StorageData<T> = JSON.parse(item);
      
      // 检查是否过期
      if (data.expire && Date.now() > data.expire) {
        // 已过期，删除该项并返回 null
        this.remove(key);
        return null;
      }
      
      return data.value;
    } catch (error) {
      // 解析 JSON 出错，返回 null
      console.error(`Error parsing storage item with key "${key}":`, error);
      return null;
    }
  }

  /**
   * 删除存储项
   * @param key 键名
   */
  remove(key: string): void {
    this.storage.removeItem(key);
  }

  /**
   * 清空所有存储项
   */
  clear(): void {
    this.storage.clear();
  }

  /**
   * 检查是否存在某个键
   * @param key 键名
   * @returns 是否存在且未过期
   */
  has(key: string): boolean {
    return this.get(key) !== null;
  }

  /**
   * 获取所有未过期的键
   * @returns 键名数组
   */
  keys(): string[] {
    const keys: string[] = [];
    for (let i = 0; i < this.storage.length; i++) {
      const key = this.storage.key(i);
      if (key && this.has(key)) {
        keys.push(key);
      }
    }
    return keys;
  }
}

// 创建默认实例
export const localStorage = new Storage('localStorage');
export const sessionStorage = new Storage('sessionStorage');

// 导出类和默认实例
export default Storage; 