require('../config/loadEnv')();

const fs = require('fs');
const path = require('path');
const mongoReadAdapter = require('../services/mongoLedgerReadAdapter');
const snapshotService = require('../services/mongoReadSnapshotService');

const root = path.join(__dirname, '..');
const dataDir = path.join(root, 'data');
const ledgerPath = path.join(dataDir, 'ledger.json');
const snapshotPath = snapshotService.snapshotPath;
const fallbackPath = path.join(dataDir, 'mongo-read-snapshot.json.bak-before-final-trx-collateral-fix-20260704');

function readFallbackState() {
  try {
    const value = JSON.parse(fs.readFileSync(fallbackPath, 'utf8'));
    return value && value.state && typeof value.state === 'object' ? value.state : {};
  } catch (_) {
    return {};
  }
}

function writeReplacement(filePath, value, suffix) {
  const body = `${JSON.stringify(value, null, 2)}\n`;
  JSON.parse(body);

  const tempPath = `${filePath}.recovery-${suffix}.tmp`;
  const corruptPath = `${filePath}.corrupt-${suffix}`;
  fs.writeFileSync(tempPath, body, { flag: 'wx' });

  if (fs.existsSync(filePath)) fs.renameSync(filePath, corruptPath);
  fs.renameSync(tempPath, filePath);
  return { filePath, corruptPath, bytes: Buffer.byteLength(body) };
}

async function main() {
  const mongo = await mongoReadAdapter.readStateFromMongo({ ignoreGate: true });
  const fallbackState = readFallbackState();
  const state = snapshotService.normalizeState({ ...fallbackState, ...mongo.state });
  const totalDocuments = snapshotService.countRows(state);
  if (!mongo.ok || totalDocuments !== Number(mongo.totalDocuments || 0)) {
    throw new Error(`Mongo recovery count mismatch: ${totalDocuments} != ${mongo.totalDocuments}`);
  }

  const suffix = new Date().toISOString().replace(/[:.]/g, '-');
  const snapshot = {
    ok: true,
    mode: 'mongo-read-snapshot',
    source: 'mongodb-zeroed-file-recovery',
    sourceReadAt: mongo.readAt,
    compareCheckedAt: null,
    totalDocuments,
    state,
    createdAt: new Date().toISOString(),
    path: snapshotPath
  };

  const snapshotResult = writeReplacement(snapshotPath, snapshot, suffix);
  const ledgerResult = writeReplacement(ledgerPath, state, suffix);
  const verifiedSnapshot = snapshotService.readSnapshot();
  const verifiedLedger = JSON.parse(fs.readFileSync(ledgerPath, 'utf8'));

  console.log(JSON.stringify({
    ok: true,
    sourceDocuments: mongo.totalDocuments,
    snapshotDocuments: verifiedSnapshot.totalRows,
    ledgerDocuments: snapshotService.countRows(verifiedLedger),
    preserved: [snapshotResult.corruptPath, ledgerResult.corruptPath],
    bytes: { snapshot: snapshotResult.bytes, ledger: ledgerResult.bytes }
  }, null, 2));
}

main().catch((err) => {
  console.error(JSON.stringify({ ok: false, error: err.message }, null, 2));
  process.exitCode = 1;
});
