// Track Storage Abstraction Layer
// Provides a unified interface for storing/retrieving audio blobs
// Default implementation uses IndexedDB, can be swapped for Electron file API

const TrackStorage = (function() {
  const DB_NAME = 'musicroom';
  const DB_VERSION = 1;
  const STORE_NAME = 'tracks';
  
  let db = null;
  let initPromise = null;

  // Initialize IndexedDB
  function init() {
    if (initPromise) return initPromise;
    
    initPromise = new Promise((resolve, reject) => {
      const request = indexedDB.open(DB_NAME, DB_VERSION);
      
      request.onerror = () => {
        console.warn('TrackStorage: IndexedDB failed to open');
        resolve(false);
      };
      
      request.onsuccess = () => {
        db = request.result;
        resolve(true);
      };
      
      request.onupgradeneeded = (event) => {
        const database = event.target.result;
        if (!database.objectStoreNames.contains(STORE_NAME)) {
          database.createObjectStore(STORE_NAME, { keyPath: 'filename' });
        }
      };
    });
    
    return initPromise;
  }

  // Check if a track is cached
  async function has(filename) {
    await init();
    if (!db) return false;
    
    return new Promise((resolve) => {
      const transaction = db.transaction(STORE_NAME, 'readonly');
      const store = transaction.objectStore(STORE_NAME);
      const request = store.getKey(filename);
      
      request.onsuccess = () => resolve(request.result !== undefined);
      request.onerror = () => resolve(false);
    });
  }

  // Get a track blob, returns { blob, contentType } or null
  async function get(filename) {
    await init();
    if (!db) return null;
    
    return new Promise((resolve) => {
      const transaction = db.transaction(STORE_NAME, 'readonly');
      const store = transaction.objectStore(STORE_NAME);
      const request = store.get(filename);
      
      request.onsuccess = () => {
        const result = request.result;
        if (result) {
          resolve({ blob: result.blob, contentType: result.contentType });
        } else {
          resolve(null);
        }
      };
      request.onerror = () => resolve(null);
    });
  }

  // Store a track blob
  async function set(filename, blob, contentType) {
    await init();
    if (!db) return false;
    
    return new Promise((resolve) => {
      const transaction = db.transaction(STORE_NAME, 'readwrite');
      const store = transaction.objectStore(STORE_NAME);
      const request = store.put({ filename, blob, contentType, cachedAt: Date.now() });
      
      request.onsuccess = () => resolve(true);
      request.onerror = () => resolve(false);
    });
  }

  // Remove a track from cache
  async function remove(filename) {
    await init();
    if (!db) return false;
    
    return new Promise((resolve) => {
      const transaction = db.transaction(STORE_NAME, 'readwrite');
      const store = transaction.objectStore(STORE_NAME);
      const request = store.delete(filename);
      
      request.onsuccess = () => resolve(true);
      request.onerror = () => resolve(false);
    });
  }

  // Clear all cached tracks
  async function clear() {
    await init();
    if (!db) return false;
    
    return new Promise((resolve) => {
      const transaction = db.transaction(STORE_NAME, 'readwrite');
      const store = transaction.objectStore(STORE_NAME);
      const request = store.clear();
      
      request.onsuccess = () => resolve(true);
      request.onerror = () => resolve(false);
    });
  }

  // List all cached track filenames
  async function list() {
    await init();
    if (!db) return [];
    
    return new Promise((resolve) => {
      const transaction = db.transaction(STORE_NAME, 'readonly');
      const store = transaction.objectStore(STORE_NAME);
      const request = store.getAllKeys();
      
      request.onsuccess = () => resolve(request.result || []);
      request.onerror = () => resolve([]);
    });
  }

  // Get storage stats
  async function getStats() {
    await init();
    if (!db) return { count: 0, totalSize: 0 };
    
    return new Promise((resolve) => {
      const transaction = db.transaction(STORE_NAME, 'readonly');
      const store = transaction.objectStore(STORE_NAME);
      const request = store.getAll();
      
      request.onsuccess = () => {
        const tracks = request.result || [];
        const totalSize = tracks.reduce((sum, t) => sum + (t.blob?.size || 0), 0);
        resolve({ count: tracks.length, totalSize });
      };
      request.onerror = () => resolve({ count: 0, totalSize: 0 });
    });
  }

  return {
    init,
    has,
    get,
    set,
    remove,
    clear,
    list,
    getStats
  };
})();
