import fs from 'node:fs';
import path from 'node:path';
import { fileURLToPath } from 'node:url';
import {
  createVacuumBackup,
  inspectDatabaseFile,
  quarantineDatabaseFiles
} from '../server/src/database-health.js';

const __dirname = path.dirname(fileURLToPath(import.meta.url));
const rootDir = path.resolve(__dirname, '..');
process.chdir(rootDir);

function parseEnvFile(filePath) {
  if (!fs.existsSync(filePath)) return {};
  const result = {};
  for (const rawLine of fs.readFileSync(filePath, 'utf8').split(/\r?\n/)) {
    const line = rawLine.trim();
    if (!line || line.startsWith('#')) continue;
    const index = line.indexOf('=');
    if (index < 1) continue;
    const key = line.slice(0, index).trim();
    let value = line.slice(index + 1).trim();
    if ((value.startsWith('"') && value.endsWith('"')) || (value.startsWith("'") && value.endsWith("'"))) {
      value = value.slice(1, -1).replace(/\\n/g, '\n').replace(/\\r/g, '\r').replace(/\\"/g, '"').replace(/\\\\/g, '\\');
    }
    result[key] = value;
  }
  return result;
}

function argument(name) {
  const prefix = `${name}=`;
  const entry = process.argv.slice(2).find((value) => value.startsWith(prefix));
  return entry ? entry.slice(prefix.length).replace(/^['"]|['"]$/g, '') : '';
}

function has(name) {
  return process.argv.slice(2).includes(name);
}

function timestamp() {
  return new Date().toISOString().replace(/[-:]/g, '').replace(/\.\d{3}Z$/, 'Z');
}

function copyAtomic(source, destination) {
  fs.mkdirSync(path.dirname(destination), { recursive: true });
  const temporary = `${destination}.${process.pid}.${Date.now()}.tmp`;
  fs.copyFileSync(source, temporary);
  fs.renameSync(temporary, destination);
}

function describe(health) {
  console.log(`Dosya : ${health.dbPath}`);
  console.log(`Durum : ${health.status}`);
  console.log(`Detay : ${health.details || '-'}`);
}

function main() {
  const envPath = path.resolve(process.env.ONLYCOIN_ENV_PATH || path.join(rootDir, '.env'));
  const fileEnv = parseEnvFile(envPath);
  const environment = process.env.NODE_ENV || fileEnv.NODE_ENV || 'production';
  const dataDir = path.resolve(rootDir, process.env.DATA_DIR || fileEnv.DATA_DIR || './data');
  const dbPath = path.join(dataDir, environment === 'test' ? 'onlycoin-test.db' : 'onlycoin.db');
  const installLockPath = path.join(dataDir, 'installed.json');
  const installed = fs.existsSync(installLockPath);
  const restorePathRaw = argument('--restore');

  console.log('\nONLYCOIN VERİTABANI KURTARMA ARACI');
  console.log('===================================');
  console.log(`Kurulum: ${installed ? 'tamamlanmış' : 'tamamlanmamış'}`);
  console.log(`Ortam   : ${environment}`);

  if (restorePathRaw) {
    const restorePath = path.resolve(restorePathRaw);
    const sourceHealth = inspectDatabaseFile(restorePath, { full: true });
    console.log('\nYEDEK KONTROLÜ');
    describe(sourceHealth);
    if (sourceHealth.status !== 'healthy') {
      throw new Error('Geri yüklenecek yedek tam SQLite bütünlük kontrolünü geçemedi. İşlem durduruldu.');
    }
    if (has('--confirm') === false && argument('--confirm') !== 'GERI-YUKLE') {
      throw new Error('Geri yüklemeyi onaylamak için --confirm=GERI-YUKLE kullanın.');
    }

    const currentHealth = inspectDatabaseFile(dbPath, { full: true });
    let recoveryDir = '';
    if (!['missing', 'empty'].includes(currentHealth.status)) {
      const recovery = quarantineDatabaseFiles(dbPath, {
        reason: `Verified backup restore requested from ${restorePath}`
      });
      recoveryDir = recovery.targetDir;
    } else {
      for (const suffix of ['-wal', '-shm', '-journal']) fs.rmSync(`${dbPath}${suffix}`, { force: true });
    }

    copyAtomic(restorePath, dbPath);
    for (const suffix of ['-wal', '-shm', '-journal']) fs.rmSync(`${dbPath}${suffix}`, { force: true });
    const restored = inspectDatabaseFile(dbPath, { full: true });
    if (restored.status !== 'healthy') {
      throw new Error(`Yedek kopyalandı fakat son doğrulama başarısız: ${restored.details || restored.status}`);
    }
    console.log('\nGERİ YÜKLEME TAMAMLANDI');
    console.log(`Kaynak yedek : ${restorePath}`);
    console.log(`Yeni veritabanı: ${dbPath}`);
    if (recoveryDir) console.log(`Önceki dosyalar: ${recoveryDir}`);
    return;
  }

  const health = inspectDatabaseFile(dbPath, { full: true });
  describe(health);

  if (has('--check-only')) {
    if (health.status === 'healthy') return;
    if (!installed && health.status === 'missing') return;
    process.exitCode = 2;
    return;
  }

  if (health.status === 'locked') {
    throw new Error('Veritabanı kullanımda. Bütün OnlyCoin/Node.js süreçlerini kapatıp yeniden deneyin.');
  }

  if (health.status === 'healthy') {
    const destination = path.join(dataDir, 'backups', `onlycoin-${timestamp()}.db`);
    const backup = createVacuumBackup(dbPath, destination);
    console.log(`\nDoğrulanmış yedek oluşturuldu: ${backup.destination}`);
    return;
  }

  if (!has('--quarantine') || argument('--confirm') !== 'KARANTINA') {
    const guidance = installed
      ? 'Canlı veritabanı otomatik olarak oluşturulmaz veya sıfırlanmaz. Doğrulanmış bir yedeği --restore=<dosya> --confirm=GERI-YUKLE ile geri yükleyin; bozuk dosyaları korumak için --quarantine --confirm=KARANTINA kullanın.'
      : 'Kurulum tamamlanmamışsa bozuk dosyaları korumak için --quarantine --confirm=KARANTINA kullanın; ardından BASLAT-WINDOWS.bat ile dört aşamalı kurulumu yeniden açın.';
    throw new Error(guidance);
  }

  if (health.status === 'missing') {
    console.log('Karantinaya alınacak veritabanı bulunmuyor.');
    return;
  }
  const recovery = quarantineDatabaseFiles(dbPath, {
    reason: `${health.status}: ${health.details || 'database quarantine requested'}`
  });
  console.log('\nKARANTİNA TAMAMLANDI');
  console.log(`Korunan dosyalar: ${recovery.targetDir}`);
  if (installed) {
    console.log('Canlı kurulumu başlatmadan önce doğrulanmış bir yedeği geri yükleyin. Sistem boş veritabanı üretmez.');
  } else {
    console.log('Kurulum henüz tamamlanmadı. BASLAT-WINDOWS.bat ile dört aşamalı kurulumu yeniden başlatabilirsiniz.');
  }
}

try {
  main();
} catch (error) {
  console.error('\n[VERİTABANI KURTARMA HATASI]');
  console.error(error?.stack || error?.message || String(error));
  process.exitCode = 1;
}
