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

const fs = require('fs');
const path = require('path');
const { MongoClient } = require('mongodb');
const persistentStore = require('../services/persistentStore');
const migrationService = require('../services/ledgerMigrationService');

function getDataDir() {
  const info = persistentStore.getStorageInfo ? persistentStore.getStorageInfo() : {};
  return info.dataDir || path.dirname(info.ledgerPath || persistentStore.getLedgerPath());
}

function getDbUri() {
  return process.env.AISFOR_CHAIN_LEDGER_DB_URI || process.env.DATABASE_URL || process.env.MONGODB_URI || '';
}

async function main() {
  const uri = getDbUri();
  if (!uri) throw new Error('AISFOR_CHAIN_LEDGER_DB_URI is required for staging compare.');

  const state = persistentStore.readState();
  const expected = migrationService.buildCollectionDocuments(state, 'compare-only');
  const client = new MongoClient(uri, { serverSelectionTimeoutMS: 5000 });

  await client.connect();
  try {
    const db = client.db();
    const rows = [];
    for (const item of expected) {
      const stagingCollection = `migration_staging_${item.collection}`;
      const col = db.collection(stagingCollection);
      const actualCount = await col.countDocuments({ _stagingKind: 'ledger-json-backfill' });
      const expectedHashes = item.docs.map((doc) => doc._sourceHash);
      const actualDocs = await col.find(
        { _stagingKind: 'ledger-json-backfill' },
        { projection: { _sourceHash: 1, _sourceIndex: 1 } }
      ).sort({ _sourceIndex: 1 }).toArray();
      const actualHashes = actualDocs.map((doc) => doc._sourceHash);
      const mismatches = [];
      const max = Math.max(expectedHashes.length, actualHashes.length);
      for (let i = 0; i < max && mismatches.length < 5; i += 1) {
        if (expectedHashes[i] !== actualHashes[i]) {
          mismatches.push({ index: i, expected: expectedHashes[i] || null, actual: actualHashes[i] || null });
        }
      }
      rows.push({
        key: item.key,
        stagingCollection,
        expectedCount: item.docs.length,
        actualCount,
        ok: actualCount === item.docs.length && mismatches.length === 0,
        mismatches
      });
    }

    const failed = rows.filter((row) => !row.ok);
    const output = {
      ok: failed.length === 0,
      mode: 'staging-compare-only',
      totalExpected: rows.reduce((sum, row) => sum + row.expectedCount, 0),
      totalActual: rows.reduce((sum, row) => sum + row.actualCount, 0),
      failedCollections: failed.length,
      rows,
      checkedAt: new Date().toISOString(),
      path: path.join(getDataDir(), 'migration-staging-compare.json')
    };
    fs.writeFileSync(output.path, JSON.stringify(output, null, 2) + '\n');
    console.log(JSON.stringify(output, null, 2));
    if (failed.length) process.exitCode = 1;
  } finally {
    await client.close();
  }
}

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


