/**
 * Background job actions for automatic backups
 * These functions run without user context (internal/system use only)
 */

import * as fs from 'fs';
import * as path from 'path';
import { readStorageConfig, writeStorageConfig } from './backup-config';

const dbRoot = path.join(process.cwd(), 'db');
const defaultBackupRoot = path.join(dbRoot, 'backups');

function readJsonSafe(fullPath: string): any {
  try {
    const content = fs.readFileSync(fullPath, 'utf-8');
    return content.trim() ? JSON.parse(content) : [];
  } catch {
    return [];
  }
}

function ensureBackupDir(backupRoot: string): string {
  if (!fs.existsSync(backupRoot)) {
    fs.mkdirSync(backupRoot, { recursive: true });
  }
  const stamp = new Date().toISOString().replace(/[:.]/g, '-');
  const dir = path.join(backupRoot, stamp);
  fs.mkdirSync(dir, { recursive: true });
  return dir;
}

/**
 * Get list of database files to backup
 * Looks for JSON files in db directory (for JSON runtime storage)
 * Falls back to all JSON files if specific files don't exist
 */
function getDefaultBackupFiles(): string[] {
  const specificFiles = [
    'invoices.json',
    'payments.json',
    'customers.json',
    'materials.json',
    'expenses.json',
    'suppliers.json',
    'purchase_orders.json',
    'general_banks.json',
    'currencies.json',
    'chart_of_accounts.json',
    'journal_entries.json',
    'checks_issued.json',
    'checks_received.json',
    'internal_transfers.json',
    'inventory_movements.json',
    'employees.json',
    'daily_exchange_rates.json',
    'customer_categories.json',
    'customer_pricing.json',
    'checks_received.json',
    'item_groups.json',
    'item_units.json',
    'managed_units.json',
    'production_reports.json',
    'exchange_rate_sources.json',
  ];

  // Try to get specific files that exist
  const existingSpecificFiles = specificFiles.filter((file) =>
    fs.existsSync(path.join(dbRoot, file))
  );

  // If we found some specific files, use them
  if (existingSpecificFiles.length > 0) {
    return existingSpecificFiles;
  }

  // Fallback: get ALL JSON files from db directory
  try {
    if (fs.existsSync(dbRoot)) {
      const allFiles = fs.readdirSync(dbRoot);
      const jsonFiles = allFiles
        .filter((f) => f.endsWith('.json') && f !== '_sequences.json')
        .map((f) => f);
      
      if (jsonFiles.length > 0) {
        return jsonFiles;
      }
    }
  } catch (error) {
    // Continue
  }

  // If still nothing found, return empty but don't error
  // PostgreSQL deployments won't have JSON files
  return [];
}

/**
 * Perform automatic backup (called by scheduler or API route)
 * No password required, no user context needed
 */
export async function performAutomaticBackup(): Promise<{
  success: boolean;
  backupId?: string;
  backupPath?: string;
  error?: string;
}> {
  try {
    const config = readStorageConfig();
    const backupRoot = config.backupPath || defaultBackupRoot;
    const files = getDefaultBackupFiles();

    // If no JSON files found, this is likely a PostgreSQL-only deployment
    if (!files.length) {
      // Create a marker file to indicate the backup was attempted
      const backupDir = ensureBackupDir(backupRoot);
      const markerFile = path.join(backupDir, '.postgres-deployment');
      fs.writeFileSync(
        markerFile,
        JSON.stringify(
          {
            timestamp: new Date().toISOString(),
            message: 'PostgreSQL deployment detected - JSON files not found',
            note: 'Configure PostgreSQL backups separately if needed',
          },
          null,
          2
        ),
        'utf-8'
      );

      // Update config with last backup time
      writeStorageConfig({
        lastBackupTime: new Date().toISOString(),
      });

      return {
        success: true,
        backupId: path.basename(backupDir),
        backupPath: backupDir,
      };
    }

    const backupDir = ensureBackupDir(backupRoot);
    const backupId = path.basename(backupDir);

    // Copy all files
    files.forEach((file) => {
      const src = path.join(dbRoot, file);
      if (!fs.existsSync(src)) return;

      try {
        const data = readJsonSafe(src);
        const backupTarget = path.join(backupDir, file);
        fs.writeFileSync(backupTarget, JSON.stringify(data, null, 2), 'utf-8');
      } catch (error: any) {
        console.error(`Failed to backup file ${file}:`, error?.message);
        // Continue with other files on error
      }
    });

    // Update config with last backup time
    writeStorageConfig({
      lastBackupTime: new Date().toISOString(),
    });

    return { success: true, backupId, backupPath: backupDir };
  } catch (error: any) {
    return {
      success: false,
      error: error?.message || 'Automatic backup failed',
    };
  }
}
