/**
 * IndexedStorage - Type definitions
 */

export interface IndexedStorageConfig {
  /** Enable console logging for debugging (default: false) */
  enableLogging?: boolean;
  /** IndexedDB database configuration */
  indexedDB?: {
    /** Database name (default: 'LocalStorageDB') */
    dbName?: string;
    /** Database version (default: 1) */
    dbVersion?: number;
    /** Object store name (default: 'localStates') */
    storeName?: string;
    /** Array of additional store names to create in the same database */
    additionalStores?: string[];
  };
}

export interface StorageManager {
  storage: {
    getItem(key: string): Promise<any>;
    setItem(key: string, value: any): Promise<void>;
    removeItem(key: string): Promise<void>;
    hasItem(key: string): Promise<boolean>;
    clear(): Promise<void>;
    getAllKeys(): Promise<string[]>;
    testAvailability(): Promise<boolean>;
  };
  createStoreManager(storeName: string): StorageManager & { storeName: string };
  getAllStoresData(): Promise<Record<string, any[]>>;
  clearAllStores(): Promise<void>;
  getAvailableStores(): string[];
  dbName: string;
  dbVersion: number;
  primaryStore: string;
  allStores: string[];
}

export interface IndexedDBManager {
  get(key: string, storeName?: string): Promise<any>;
  save(key: string, data: any, storeName?: string): Promise<void>;
  remove(key: string, storeName?: string): Promise<void>;
  getAll(storeName?: string): Promise<any[]>;
  exists(key: string, storeName?: string): Promise<boolean>;
  clear(storeName?: string): Promise<void>;
  openDB(): Promise<IDBDatabase>;
  calculateUsage(storeName?: string): Promise<{ totalSize: number; items: Record<string, number> }>;
  testAvailability(): Promise<boolean>;
  getAvailableStores(): string[];
  createStoreAPI(storeName: string): StoreAPI;
  clearAllStores(): Promise<void>;
  getAllStoresData(): Promise<Record<string, any[]>>;
  dbName: string;
  dbVersion: number;
  primaryStore: string;
  allStores: string[];
}

export interface StoreAPI {
  get(key: string): Promise<any>;
  save(key: string, data: any): Promise<void>;
  remove(key: string): Promise<void>;
  getAll(): Promise<any[]>;
  exists(key: string): Promise<boolean>;
  clear(): Promise<void>;
  calculateUsage(): Promise<{ totalSize: number; items: Record<string, number> }>;
  storeName: string;
}

export interface IndexedStorageAPI {
  /**
   * Configure IndexedStorage options
   * @param options - Configuration options
   */
  configure(options?: IndexedStorageConfig): void;

  /**
   * Get current configuration
   * @returns Current configuration object
   */
  getConfig(): IndexedStorageConfig;

  /**
   * Retrieve an item from storage
   * @param key - The key to retrieve
   * @returns The stored value or null if not found
   */
  getItem(key: string): Promise<any | null>;

  /**
   * Store an item in storage
   * @param key - The key to store under
   * @param value - The value to store (will be serialized)
   */
  setItem(key: string, value: any): Promise<void>;

  /**
   * Remove an item from storage
   * @param key - The key to remove
   */
  removeItem(key: string): Promise<void>;

  /**
   * Check if an item exists in storage
   * @param key - The key to check
   * @returns True if the key exists
   */
  hasItem(key: string): Promise<boolean>;

  /**
   * Clear all items from storage
   */
  clear(): Promise<void>;

  /**
   * Get all keys from storage
   * @returns Array of all keys
   */
  getAllKeys(): Promise<string[]>;

  /**
   * Get the number of items in storage
   * @returns Number of stored items
   */
  length(): Promise<number>;

  /**
   * Get a key by index (for iteration)
   * @param index - The index of the key
   * @returns The key at the specified index or null
   */
  key(index: number): Promise<string | null>;

  /**
   * Test if storage is available and working
   * @returns True if storage is available
   */
  isAvailable(): Promise<boolean>;

  /**
   * Iterate over all items in storage
   * @param callback - Function called for each item (key, value, index)
   */
  forEach(callback: (key: string, value: any, index: number) => void | Promise<void>): Promise<void>;

  /**
   * Get multiple items at once
   * @param keys - Array of keys to retrieve
   * @returns Object with key-value pairs
   */
  getMultiple(keys: string[]): Promise<Record<string, any>>;

  /**
   * Set multiple items at once
   * @param items - Object with key-value pairs to store
   */
  setMultiple(items: Record<string, any>): Promise<void>;

  /**
   * Remove multiple items at once
   * @param keys - Array of keys to remove
   */
  removeMultiple(keys: string[]): Promise<void>;

  /**
   * Get a store-specific API for working with a particular store
   * @param storeName - Name of the store to get API for
   * @returns Store-specific API with same methods as IndexedStorage
   */
  getStore(storeName: string): StoreSpecificAPI;

  /**
   * Get list of all available stores
   * @returns Array of store names
   */
  getAvailableStores(): string[];

  /**
   * Clear all stores in the database
   */
  clearAllStores(): Promise<void>;

  /**
   * Get data from all stores
   * @returns Object with store names as keys and their data as values
   */
  getAllStoresData(): Promise<Record<string, any[]>>;
}

export interface StoreSpecificAPI {
  getItem(key: string): Promise<any | null>;
  setItem(key: string, value: any): Promise<void>;
  removeItem(key: string): Promise<void>;
  hasItem(key: string): Promise<boolean>;
  clear(): Promise<void>;
  getAllKeys(): Promise<string[]>;
  length(): Promise<number>;
  key(index: number): Promise<string | null>;
  isAvailable(): Promise<boolean>;
  storeName: string;
}
