'use strict';

const fs = require('node:fs/promises');
const path = require('node:path');
const config = require('./config');
const { pool } = require('./db');
const { riyadhDate } = require('./utils');

const BACKUP_TABLES = [
  'admins',
  'users',
  'user_permissions',
  'products',
  'custodies',
  'custody_items',
  'audit_logs',
];

async function createBackup({ force = false } = {}) {
  await fs.mkdir(config.backupDir, { recursive: true });
  const date = riyadhDate();
  const filename = `vegetable-backup-${date}.json`;
  const targetPath = path.join(config.backupDir, filename);
  const temporaryPath = `${targetPath}.tmp`;

  if (!force) {
    try {
      await fs.access(targetPath);
      return { created: false, path: targetPath, reason: 'exists' };
    } catch (_) {
      // A new backup is needed.
    }
  }

  const data = {
    format: 'ayman-mark-vegetable-backup',
    version: 1,
    createdAt: new Date().toISOString(),
    database: config.db.name,
    tables: {},
  };

  for (const table of BACKUP_TABLES) {
    const [rows] = await pool.query(`SELECT * FROM \`${table}\` ORDER BY 1`);
    data.tables[table] = rows;
  }

  await fs.writeFile(temporaryPath, JSON.stringify(data, null, 2), { encoding: 'utf8', mode: 0o600 });
  await fs.rename(temporaryPath, targetPath);
  await cleanupOldBackups();
  return { created: true, path: targetPath };
}

async function cleanupOldBackups() {
  const files = await fs.readdir(config.backupDir, { withFileTypes: true });
  const cutoff = Date.now() - config.backupRetentionDays * 24 * 60 * 60 * 1000;
  await Promise.all(files
    .filter((entry) => entry.isFile() && /^vegetable-backup-\d{4}-\d{2}-\d{2}\.json$/.test(entry.name))
    .map(async (entry) => {
      const filePath = path.join(config.backupDir, entry.name);
      const stat = await fs.stat(filePath);
      if (stat.mtimeMs < cutoff) await fs.unlink(filePath);
    }));
}

function startBackupScheduler() {
  const run = () => createBackup().catch((error) => console.error('Daily backup failed:', error.message));
  setTimeout(run, 15_000).unref();
  setInterval(run, 60 * 60 * 1000).unref();
}

module.exports = { createBackup, cleanupOldBackups, startBackupScheduler, BACKUP_TABLES };
