import * as dotenv from 'dotenv';
import * as path from 'path';

dotenv.config();

function int(name: string, fallback: number): number {
  const v = process.env[name];
  return v !== undefined && v !== '' ? parseInt(v, 10) : fallback;
}

function bigint(name: string, fallback: string): bigint {
  const v = process.env[name];
  return BigInt(v !== undefined && v !== '' ? v : fallback);
}

const repoRoot = process.env.PROXMOX_ROOT || path.resolve(__dirname, '../../../../..');

export const checkpointAggregatorConfig = {
  chain138Rpc: process.env.CHAIN138_RPC_URL || 'http://192.168.11.211:8545',
  mainnetRpc:
    process.env.MAINNET_RPC_URL ||
    process.env.ETHEREUM_MAINNET_RPC ||
    'https://ethereum-rpc.publicnode.com',
  checkpointProxy: process.env.CHAIN138_MAINNET_CHECKPOINT_PROXY || '',
  blockOracleExtension: process.env.EXT_BLOCK_ORACLE || '',
  batchSize: int('CHECKPOINT_BATCH_SIZE', 10),
  maxWaitMs: int('CHECKPOINT_MAX_WAIT_MS', 300_000),
  confirmationBlocks: int('CHECKPOINT_CONFIRMATION_BLOCKS', 2),
  minValueWei: bigint('CHECKPOINT_MIN_VALUE_WEI', '0'),
  blockscoutApi:
    process.env.CHECKPOINT_BLOCKSCOUT_API || 'https://explorer.d-bis.org/api/v2',
  useBlockscout: process.env.CHECKPOINT_USE_BLOCKSCOUT !== '0',
  scanFromBlock: int('CHECKPOINT_SCAN_FROM_BLOCK', 0),
  scanChunkBlocks: int('CHECKPOINT_SCAN_CHUNK_BLOCKS', 100),
  scanPollMs: int('CHECKPOINT_SCAN_POLL_MS', 15_000),
  scanStatePath:
    process.env.CHECKPOINT_SCAN_STATE_PATH ||
    path.join(repoRoot, 'reports/status/checkpoint-aggregator-scan-state.json'),
  ipfsApiUrl: process.env.CHECKPOINT_IPFS_API_URL || '',
  payloadPublicUrl: process.env.CHECKPOINT_PAYLOAD_PUBLIC_URL || '',
  batchPayloadDir:
    process.env.CHECKPOINT_BATCH_PAYLOAD_DIR ||
    path.join(repoRoot, 'reports/checkpoint-indexer/batches'),
  updateBlockOracle: process.env.CHECKPOINT_UPDATE_BLOCK_ORACLE !== '0',
  requireValidatorSigs: process.env.CHECKPOINT_REQUIRE_VALIDATOR_SIGS !== 'false',
  /** hashes (default) | commitment | leaves | leaves-v2 — official hub on 0xe2D6… */
  submitMode: (process.env.CHECKPOINT_SUBMIT_MODE || 'hashes') as
    | 'hashes'
    | 'commitment'
    | 'leaves'
    | 'leaves-v2',
  batchEmitter138: process.env.CHAIN138_BATCH_EMITTER || '',
  ccipIngressEnabled: process.env.CHECKPOINT_CCIP_INGRESS === '1',
  usdEnrichEnabled: process.env.CHECKPOINT_USD_ENRICH !== '0',
  tokenAggregationApiUrl:
    process.env.CHECKPOINT_TOKEN_AGGREGATION_URL ||
    process.env.TOKEN_AGGREGATION_API_URL ||
    'https://explorer.d-bis.org/api/v1',
  usdRequestDelayMs: int('CHECKPOINT_USD_REQUEST_DELAY_MS', 80),
  dualWriteV1Mirror: process.env.CHECKPOINT_DUAL_WRITE_V1_MIRROR !== '0',
  recordAddressActivity:
    process.env.CHECKPOINT_RECORD_ADDRESS_ACTIVITY !== '0',
  addressActivityRegistry:
    process.env.ADDRESS_ACTIVITY_REGISTRY_MAINNET || '',
  transactionMirrorMainnet:
    process.env.TRANSACTION_MIRROR_MAINNET ||
    '0x4CF42c4F1dBa748601b8938be3E7ABD732E87cE9',
  attachReceiptMeta: process.env.CHECKPOINT_ATTACH_RECEIPT_META !== '0',
  isoEnrichEnabled: process.env.CHECKPOINT_ISO_ENRICH !== '0',
  recordIsoAttestation: process.env.CHECKPOINT_RECORD_ISO_ATTESTATION !== '0',
  addressActivityRegistryV2: process.env.ADDRESS_ACTIVITY_REGISTRY_V2_MAINNET || '',
  participantSurface: process.env.CHAIN138_PARTICIPANT_SURFACE_MAINNET || '',
  surfaceParticipants: process.env.CHECKPOINT_SURFACE_PARTICIPANTS !== '0',
  /** Default on: both sender and receiver get a mainnet Transactions-tab entry per 138 tx. */
  surfaceTopLevelZeroEth: process.env.CHECKPOINT_SURFACE_TOPLEVEL_ZERO_ETH !== '0',
} as const;

export function assertAggregatorConfig(): void {
  if (!process.env.PRIVATE_KEY) throw new Error('PRIVATE_KEY required');
  if (!checkpointAggregatorConfig.checkpointProxy) {
    throw new Error('CHAIN138_MAINNET_CHECKPOINT_PROXY required');
  }
  if (process.env.CHECKPOINT_RECORD_ADDRESS_ACTIVITY === '1' &&
    !checkpointAggregatorConfig.addressActivityRegistry) {
    throw new Error(
      'CHECKPOINT_RECORD_ADDRESS_ACTIVITY=1 requires ADDRESS_ACTIVITY_REGISTRY_MAINNET (deploy: bash scripts/deployment/deploy-address-activity-registry.sh)'
    );
  }
  if (
    checkpointAggregatorConfig.dualWriteV1Mirror &&
    !checkpointAggregatorConfig.transactionMirrorMainnet
  ) {
    throw new Error('CHECKPOINT_DUAL_WRITE_V1_MIRROR=1 requires TRANSACTION_MIRROR_MAINNET');
  }
  if (
    process.env.CHECKPOINT_RECORD_ISO_ATTESTATION === '1' &&
    !checkpointAggregatorConfig.addressActivityRegistryV2
  ) {
    throw new Error(
      'CHECKPOINT_RECORD_ISO_ATTESTATION=1 requires ADDRESS_ACTIVITY_REGISTRY_V2_MAINNET'
    );
  }
}
