// ============================================================
// AUDIO BACKUPS ROUTES — Server-side audio backup storage
// Stores compressed audio in PostgreSQL, auto-deletes after 24h
// ============================================================

import express = require('express');
import type { Request, Response } from 'express';
import zlib = require('zlib');
import multer = require('multer');
const db = require('../db/database');
const { authMiddleware } = require('../middleware/auth');
const cryptoUtil = require('../utils/crypto');
const { serverError } = require('../utils/errors');

const upload = multer({ storage: multer.memoryStorage(), limits: { fileSize: 25 * 1024 * 1024 } });

const router = express.Router();
router.use(authMiddleware);

router.post('/audio-backups', upload.single('audio'), async function (req: Request, res: Response) {
  console.log('[AudioBackup] POST received, hasFile=' + !!req.file + ', user=' + (req.user ? req.user.id : 'none'));
  try {
    if (!req.file) return res.status(400).json({ error: 'No audio file' });

    const module = req.body.module || 'encounter';
    const originalSize = req.file.size;

    const compressed: Buffer = await new Promise((resolve, reject) => {
      zlib.gzip(req.file!.buffer, { level: 6 }, (err, result) => {
        if (err) reject(err); else resolve(result);
      });
    });
    const stored = cryptoUtil.encryptBuffer(compressed);

    const result = await db.run(
      'INSERT INTO audio_backups (user_id, module, mime_type, size_bytes, compressed_bytes, audio_data) VALUES ($1,$2,$3,$4,$5,$6)',
      [req.user!.id, module, req.file.mimetype || 'audio/webm', originalSize, stored.length, stored]
    );

    const ratio = originalSize > 0 ? Math.round((1 - compressed.length / originalSize) * 100) : 0;
    console.log('[AudioBackup] Saved ' + (originalSize / 1024).toFixed(0) + 'KB → ' + (compressed.length / 1024).toFixed(0) + 'KB (' + ratio + '% compression) id=' + result.lastInsertRowid + ' user=' + req.user!.id);

    res.json({ success: true, id: result.lastInsertRowid, originalSize, compressedSize: compressed.length });
  } catch (e) {
    return serverError(res, 'AudioBackup save', e, 'Could not save audio backup');
  }
});

router.get('/audio-backups', async function (req: Request, res: Response) {
  try {
    const rows = await db.all(
      "SELECT id, module, mime_type, size_bytes, compressed_bytes, created_at, expires_at FROM audio_backups WHERE user_id = $1 AND expires_at > NOW() ORDER BY created_at DESC",
      [req.user!.id]
    );
    res.json({ success: true, backups: rows });
  } catch (e) { return serverError(res, 'AudioBackup list', e, 'Could not list backups'); }
});

router.get('/audio-backups/:id/audio', async function (req: Request, res: Response) {
  try {
    const row = await db.get(
      'SELECT audio_data, mime_type, size_bytes FROM audio_backups WHERE id = $1 AND user_id = $2 AND expires_at > NOW()',
      [req.params.id, req.user!.id]
    );
    if (!row) return res.status(404).json({ error: 'Backup not found or expired' });

    const ciphertext = row.audio_data;
    const gzipped: Buffer = cryptoUtil.isEncryptedBuffer(ciphertext) ? cryptoUtil.decryptBuffer(ciphertext) : ciphertext;
    const decompressed: Buffer = await new Promise((resolve, reject) => {
      zlib.gunzip(gzipped, (err, result) => {
        if (err) reject(err); else resolve(result);
      });
    });

    res.setHeader('Content-Type', row.mime_type || 'audio/webm');
    res.setHeader('Content-Length', decompressed.length);
    res.send(decompressed);
  } catch (e) { return serverError(res, 'AudioBackup read', e, 'Could not retrieve audio backup'); }
});

router.delete('/audio-backups/:id', async function (req: Request, res: Response) {
  try {
    const result = await db.run(
      'DELETE FROM audio_backups WHERE id = $1 AND user_id = $2',
      [req.params.id, req.user!.id]
    );
    if (result.changes === 0) return res.status(404).json({ error: 'Not found' });
    res.json({ success: true });
  } catch (e) { return serverError(res, 'AudioBackup delete', e, 'Could not delete backup'); }
});

export = router;
