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

const path = require('path');
const persistentStore = require('../services/persistentStore');
const mongoObservation = require('../services/mongoLedgerObservationAdapter');
const mongoLiveWriter = require('../services/mongoLedgerLiveWriterAdapter');
const {
  buildAudit,
  writeJsonAtomic
} = require('./finality-backlog-audit');

const dataDir = path.join(__dirname, '..', 'data');
const resultPath = path.join(dataDir, 'finality-backlog-archive-latest.json');

async function main() {
  const apply = process.argv.includes('--apply');
  const confirmed = process.argv.includes('--confirm-legacy-archive');
  const state = persistentStore.readState();
  const audit = buildAudit(state);

  if (process.env.AISFOR_CHAIN_MOCK_BLOCK_WRITES_ENABLED !== '0') {
    throw new Error('Mock block writes must be locked before backlog disposition.');
  }
  if (!audit.ok) throw new Error('Block-chain integrity audit failed; archive is not allowed.');
  if (apply && !confirmed) throw new Error('Pass --confirm-legacy-archive with --apply.');

  const planByBlockId = new Map(audit.plans.map((row) => [String(row.blockId), row]));
  const appliedAt = new Date().toISOString();
  let changed = 0;
  for (const block of state.blocks || []) {
    const plan = planByBlockId.get(String(block.id));
    if (!plan || !apply) continue;
    const targetStatus = plan.disposition === 'QUARANTINE_LEGACY_MOCK'
      ? 'QUARANTINED_LEGACY_MOCK'
      : 'ARCHIVED_LEGACY_MOCK';
    block.legacyDisposition = {
      auditVersion: audit.auditVersion,
      auditFingerprint: audit.fingerprint,
      originalStatus: plan.originalStatus,
      disposition: plan.disposition,
      reasons: plan.dispositionReasons,
      missingReferences: plan.missingReferences,
      validationSnapshot: {
        assignedValidatorCount: plan.assignedValidatorCount,
        requiredVotes: plan.requiredVotes,
        approveVotes: plan.approveVotes,
        rejectVotes: plan.rejectVotes,
        voteRows: plan.voteRows
      },
      appliedAt
    };
    block.status = targetStatus;
    changed += 1;
  }

  if (apply) {
    if (changed !== audit.totals.targetBacklog) {
      throw new Error(`Backlog changed during archive: ${changed} != ${audit.totals.targetBacklog}`);
    }
    persistentStore.writeState(state);
    await mongoObservation.syncState(state, { reason: 'legacy-mock-finality-archive' });
    await mongoLiveWriter.syncState(state, { reason: 'legacy-mock-finality-archive' });
  }

  const result = {
    ok: true,
    mode: apply ? 'legacy-mock-finality-archive-applied' : 'legacy-mock-finality-archive-dry-run',
    applied: apply,
    appliedAt: apply ? appliedAt : null,
    sourceFingerprint: audit.fingerprint,
    planned: audit.totals.targetBacklog,
    changed,
    archiveUnvalidated: audit.totals.archiveUnvalidated,
    quarantine: audit.totals.quarantine,
    safeToAutoFinalize: audit.safeToAutoFinalize,
    resultPath
  };
  writeJsonAtomic(resultPath, result);
  console.log(JSON.stringify(result, null, 2));
}

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