// ============================================================
// AUDIO BACKUP — Server-side audio backup with local IndexedDB fallback
// Saves audio to server (gzip compressed in PostgreSQL), auto-deletes 24h.
// Falls back to IndexedDB if server save fails.
// ============================================================

var DB_NAME = 'PedScribeAudioBackup';
var STORE_NAME = 'recordings';
var DB_VERSION = 1;
var MAX_AGE_MS = 24 * 60 * 60 * 1000;

var _db = null;

  function openDB() {
    if (_db) return Promise.resolve(_db);
    return new Promise(function(resolve, reject) {
      var request = indexedDB.open(DB_NAME, DB_VERSION);
      request.onupgradeneeded = function(e) {
        var db = e.target.result;
        if (!db.objectStoreNames.contains(STORE_NAME)) {
          var store = db.createObjectStore(STORE_NAME, { keyPath: 'id', autoIncrement: true });
          store.createIndex('timestamp', 'timestamp', { unique: false });
        }
      };
      request.onsuccess = function(e) { _db = e.target.result; resolve(_db); };
      request.onerror = function() { reject(new Error('IndexedDB open failed')); };
    });
  }

  // Save audio — tries server first, falls back to IndexedDB
  window.saveAudioBackup = function(blob, module) {
    // Try server save first
    return saveToServer(blob, module).then(function(serverId) {
      if (serverId) {
        window._lastAudioBackupId = 'server_' + serverId;
        return serverId;
      }
      // Fallback to IndexedDB
      return saveToIndexedDB(blob, module);
    }).catch(function() {
      return saveToIndexedDB(blob, module);
    });
  };

  function saveToServer(blob, module) {
    var formData = new FormData();
    formData.append('audio', blob, 'audio.webm');
    formData.append('module', module || 'encounter');

    var headers = {};
    var token = window.AUTH_TOKEN || localStorage.getItem('ped_scribe_token') || '';
    if (token) headers['Authorization'] = 'Bearer ' + token;

    return fetch('/api/audio-backups', {
      method: 'POST',
      headers: headers,
      credentials: 'same-origin',
      body: formData
    })
    .then(function(r) { return r.json(); })
    .then(function(data) {
      if (data.success) return data.id;
      return null;
    })
    .catch(function() { return null; });
  }

  function saveToIndexedDB(blob, module) {
    return openDB().then(function(db) {
      return new Promise(function(resolve, reject) {
        var tx = db.transaction(STORE_NAME, 'readwrite');
        var store = tx.objectStore(STORE_NAME);
        var record = {
          blob: blob,
          module: module || 'unknown',
          timestamp: Date.now(),
          size: blob.size,
          mimeType: blob.type
        };
        var req = store.add(record);
        req.onsuccess = function() { resolve(req.result); };
        req.onerror = function() { reject(new Error('Failed to save audio backup')); };
      });
    }).then(function(id) {
      window._lastAudioBackupId = 'local_' + id;
      cleanupOldLocalBackups();
      return id;
    }).catch(function(err) {
      console.warn('[AudioBackup] Save failed:', err.message);
      return null;
    });
  }

  // Delete a specific backup (server or local)
  window.deleteAudioBackup = function(id) {
    if (typeof id === 'string' && id.startsWith('server_')) {
      var serverId = id.replace('server_', '');
      return fetch('/api/audio-backups/' + serverId, {
        method: 'DELETE',
        headers: getAuthHeaders()
      }).then(function() {}).catch(function() {});
    }
    // Local IndexedDB delete
    var localId = typeof id === 'string' ? parseInt(id.replace('local_', '')) : id;
    return openDB().then(function(db) {
      return new Promise(function(resolve) {
        var tx = db.transaction(STORE_NAME, 'readwrite');
        tx.objectStore(STORE_NAME).delete(localId);
        tx.oncomplete = function() { resolve(); };
        tx.onerror = function() { resolve(); };
      });
    }).catch(function() {});
  };

  // Get all backups (merged: server + local)
  window.getAudioBackups = function() {
    var serverPromise = fetchServerBackups();
    var localPromise = getLocalBackups();

    return Promise.all([serverPromise, localPromise]).then(function(results) {
      var server = results[0].map(function(b) {
        return {
          id: 'server_' + b.id,
          module: b.module,
          timestamp: new Date(b.created_at).getTime(),
          size: b.size_bytes,
          compressedSize: b.compressed_bytes,
          source: 'server',
          expiresAt: b.expires_at
        };
      });
      var local = results[1].map(function(b) {
        return {
          id: 'local_' + b.id,
          module: b.module,
          timestamp: b.timestamp,
          size: b.size,
          source: 'local'
        };
      });
      return server.concat(local).sort(function(a, b) { return b.timestamp - a.timestamp; });
    });
  };

  function fetchServerBackups() {
    var headers = { 'Content-Type': 'application/json' };
    var token = window.AUTH_TOKEN || localStorage.getItem('ped_scribe_token') || '';
    if (token) headers['Authorization'] = 'Bearer ' + token;
    return fetch('/api/audio-backups', {
      headers: headers,
      credentials: 'same-origin'
    })
    .then(function(r) { return r.json(); })
    .then(function(data) { return data.success ? (data.backups || []) : []; })
    .catch(function() { return []; });
  }

  function getLocalBackups() {
    return openDB().then(function(db) {
      return new Promise(function(resolve) {
        var tx = db.transaction(STORE_NAME, 'readonly');
        var req = tx.objectStore(STORE_NAME).getAll();
        req.onsuccess = function() {
          var records = (req.result || []).filter(function(r) {
            return (Date.now() - r.timestamp) < MAX_AGE_MS;
          });
          resolve(records);
        };
        req.onerror = function() { resolve([]); };
      });
    }).catch(function() { return []; });
  }

  // Retry transcription from backup
  window.retryAudioBackup = function(id) {
    if (typeof id === 'string' && id.startsWith('server_')) {
      var serverId = id.replace('server_', '');
      showLoading('Downloading and re-transcribing...');
      var token = window.AUTH_TOKEN || localStorage.getItem('ped_scribe_token') || '';
      return fetch('/api/audio-backups/' + serverId + '/audio', {
        headers: { 'Authorization': 'Bearer ' + token }
      })
      .then(function(r) { if (!r.ok) throw new Error('Download failed'); return r.blob(); })
      .then(function(blob) {
        window._lastAudioBackupId = id;
        return transcribeAudio(blob).then(function(data) {
          hideLoading();
          if (data.success) {
            showToast('Backup transcribed!', 'success');
            if (navigator.clipboard && navigator.clipboard.writeText) {
              navigator.clipboard.writeText(data.text);
              showToast('Transcript copied to clipboard', 'info');
            }
          } else {
            showToast('Retry failed: ' + (data.error || 'unknown'), 'error');
          }
          return data;
        });
      })
      .catch(function(err) { hideLoading(); showToast('Retry failed: ' + err.message, 'error'); });
    }

    // Local IndexedDB retry
    var localId = typeof id === 'string' ? parseInt(id.replace('local_', '')) : id;
    return openDB().then(function(db) {
      return new Promise(function(resolve, reject) {
        var tx = db.transaction(STORE_NAME, 'readonly');
        var req = tx.objectStore(STORE_NAME).get(localId);
        req.onsuccess = function() {
          if (!req.result) { reject(new Error('Backup not found')); return; }
          resolve(req.result);
        };
        req.onerror = function() { reject(new Error('Failed to read backup')); };
      });
    }).then(function(record) {
      showLoading('Re-transcribing audio backup...');
      window._lastAudioBackupId = id;
      return transcribeAudio(record.blob).then(function(data) {
        hideLoading();
        if (data.success) {
          showToast('Backup transcribed!', 'success');
          if (navigator.clipboard && navigator.clipboard.writeText) {
            navigator.clipboard.writeText(data.text);
            showToast('Transcript copied to clipboard', 'info');
          }
        } else {
          showToast('Retry failed: ' + (data.error || 'unknown'), 'error');
        }
        return data;
      });
    });
  };

  function cleanupOldLocalBackups() {
    openDB().then(function(db) {
      var tx = db.transaction(STORE_NAME, 'readwrite');
      var store = tx.objectStore(STORE_NAME);
      var index = store.index('timestamp');
      var cutoff = Date.now() - MAX_AGE_MS;
      var range = IDBKeyRange.upperBound(cutoff);
      var req = index.openCursor(range);
      req.onsuccess = function(e) {
        var cursor = e.target.result;
        if (cursor) { cursor.delete(); cursor.continue(); }
      };
    }).catch(function() {});
  }

  // Render audio backups list in settings
  window.renderAudioBackups = function() {
    var container = document.getElementById('audio-backups-list');
    if (!container) return;
    getAudioBackups().then(function(backups) {
      container.textContent = '';
      if (backups.length === 0) {
        var empty = document.createElement('p');
        empty.style.color = 'var(--g400)';
        empty.style.fontSize = '13px';
        empty.textContent = 'No audio backups. Recordings are saved automatically to the server and kept for 24 hours.';
        container.appendChild(empty);
        return;
      }
      backups.forEach(function(b) {
        var date = new Date(b.timestamp);
        var sizeKb = Math.round(b.size / 1024);
        var age = Math.round((Date.now() - b.timestamp) / 60000);
        var ageStr = age < 60 ? age + 'm ago' : Math.round(age / 60) + 'h ago';
        var compInfo = b.compressedSize ? ' (' + Math.round(b.compressedSize / 1024) + ' KB compressed)' : '';
        var row = document.createElement('div');
        row.className = 'saved-enc-item';
        row.style.padding = '8px 12px';

        var body = document.createElement('div');
        body.style.flex = '1';

        var title = document.createElement('div');
        title.style.fontWeight = '600';
        title.style.fontSize = '13px';
        title.style.display = 'flex';
        title.style.alignItems = 'center';
        title.style.gap = '6px';
        title.appendChild(document.createTextNode((b.module || '') + ' recording '));

        var sourceTag = document.createElement('span');
        sourceTag.style.fontSize = '10px';
        sourceTag.style.padding = '1px 5px';
        sourceTag.style.borderRadius = '3px';
        sourceTag.style.background = b.source === 'server' ? 'var(--blue-light)' : 'var(--g100)';
        sourceTag.style.color = b.source === 'server' ? 'var(--blue)' : 'var(--g500)';
        sourceTag.textContent = b.source === 'server' ? 'server' : 'local';
        title.appendChild(sourceTag);

        var meta = document.createElement('div');
        meta.style.fontSize = '11px';
        meta.style.color = 'var(--g500)';
        meta.textContent = date.toLocaleString() + ' · ' + sizeKb + ' KB' + compInfo + ' · ' + ageStr;

        body.appendChild(title);
        body.appendChild(meta);

        var retryBtn = document.createElement('button');
        retryBtn.className = 'btn-sm btn-primary audio-backup-retry';
        retryBtn.dataset.id = b.id;
        var retryIcon = document.createElement('i');
        retryIcon.className = 'fas fa-rotate-right';
        retryBtn.appendChild(retryIcon);
        retryBtn.appendChild(document.createTextNode(' Retry'));

        var deleteBtn = document.createElement('button');
        deleteBtn.className = 'btn-sm btn-ghost audio-backup-delete';
        deleteBtn.dataset.id = b.id;
        deleteBtn.style.color = 'var(--red)';
        var deleteIcon = document.createElement('i');
        deleteIcon.className = 'fas fa-trash';
        deleteBtn.appendChild(deleteIcon);

        row.appendChild(body);
        row.appendChild(retryBtn);
        row.appendChild(deleteBtn);
        container.appendChild(row);
      });
      container.querySelectorAll('.audio-backup-retry').forEach(function(btn) {
        btn.addEventListener('click', function() { retryAudioBackup(btn.dataset.id); });
      });
      container.querySelectorAll('.audio-backup-delete').forEach(function(btn) {
        btn.addEventListener('click', function() {
          deleteAudioBackup(btn.dataset.id).then(function() {
            showToast('Backup deleted', 'info');
            renderAudioBackups();
          });
        });
      });
    });
  };

cleanupOldLocalBackups();
