const { MongoClient } = require('mongodb');
const readSwitchApprovalService = require('./ledgerReadSwitchApprovalService');

const LIVE_KIND = 'ledger-json-live-backfill';

const COLLECTIONS = [
  { key: 'proofs', collection: 'chain_proofs' },
  { key: 'transactions', collection: 'chain_transactions' },
  { key: 'blocks', collection: 'chain_blocks' },
  { key: 'callbackEvents', collection: 'chain_callbacks' },
  { key: 'nodes', collection: 'node_participants' },
  { key: 'nodeEconomyEntries', collection: 'node_economy_ledger' },
  { key: 'pointEntries', collection: 'point_ledger' },
  { key: 'validatorVotes', collection: 'validator_votes' },
  { key: 'backupIndexes', collection: 'backup_indexes' },
  { key: 'distributedChunks', collection: 'distributed_chunks' },
  { key: 'wallets', collection: 'wallets' },
  { key: 'walletTransactions', collection: 'wallet_transactions' },
  { key: 'rewardEntries', collection: 'reward_ledger' },
  { key: 'rewardAuditEntries', collection: 'reward_audit_log' },
  { key: 'rewardReviewDecisions', collection: 'reward_review_decisions' }
];

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

function isReadRequested() {
  return process.env.AISFOR_CHAIN_LEDGER_READ_BACKEND === 'mongodb' || process.env.AISFOR_CHAIN_LEDGER_BACKEND === 'mongodb';
}

function isReadEnabled() {
  return isReadRequested() && readSwitchApprovalService.getApproval().approved;
}

function getStatus() {
  const approval = readSwitchApprovalService.getApproval();
  const requested = isReadRequested();
  const enabled = requested && approval.approved;
  return {
    targetBackend: 'mongodb',
    requested,
    approved: approval.approved,
    enabled,
    mode: enabled ? 'mongodb-read-enabled' : (requested ? 'mongodb-read-requested-locked' : 'json-read-active'),
    reason: enabled ? 'Read backend request and manual approval are both present.' : (requested ? 'Read backend request exists but manual approval is missing.' : 'MongoDB read backend is not requested.'),
    approval
  };
}

async function readStateFromMongo(options = {}) {
  const uri = getDbUri();
  if (!uri) throw new Error('AISFOR_CHAIN_LEDGER_DB_URI is required for MongoDB read backend.');
  if (!options.ignoreGate && !isReadEnabled()) {
    throw new Error('MongoDB read backend is locked. Set read backend request and record manual approval first.');
  }

  const client = new MongoClient(uri, { serverSelectionTimeoutMS: 5000 });
  await client.connect();
  try {
    const db = client.db();
    const state = {};
    const rows = [];

    for (const item of COLLECTIONS) {
      const docs = await db.collection(item.collection)
        .find({ _ledgerLiveKind: LIVE_KIND }, { projection: { payload: 1, _sourceIndex: 1, _sourceHash: 1 } })
        .sort({ _sourceIndex: 1 })
        .toArray();
      state[item.key] = docs.map((doc) => doc.payload).filter((payload) => payload && typeof payload === 'object');
      rows.push({ key: item.key, collection: item.collection, documents: state[item.key].length, rawDocuments: docs.length });
    }

    return {
      ok: true,
      mode: 'mongodb-read-state',
      backend: 'mongodb',
      totalDocuments: rows.reduce((sum, row) => sum + row.documents, 0),
      rows,
      state,
      readAt: new Date().toISOString()
    };
  } finally {
    await client.close();
  }
}

module.exports = {
  COLLECTIONS,
  LIVE_KIND,
  getStatus,
  isReadRequested,
  isReadEnabled,
  readStateFromMongo
};

