import { ethers } from 'ethers';

/** Base URL for Chain 138 Blockscout (no trailing slash). */
export function chain138ExplorerBase(): string {
  const fromEnv = process.env.CHAIN138_EXPLORER_URL || process.env.CHECKPOINT_CHAIN138_EXPLORER_URL;
  if (fromEnv) return fromEnv.replace(/\/$/, '');
  const api = process.env.CHECKPOINT_BLOCKSCOUT_API || 'https://explorer.d-bis.org/api/v2';
  try {
    const u = new URL(api);
    return `${u.protocol}//${u.host}`;
  } catch {
    return 'https://explorer.d-bis.org';
  }
}

/** Full explorer link for a Chain 138 transaction hash. */
export function chain138ExplorerTxUrl(txHash: string, base?: string): string {
  const root = (base ?? chain138ExplorerBase()).replace(/\/$/, '');
  const hash = txHash.startsWith('0x') ? txHash : `0x${txHash}`;
  return `${root}/tx/${hash}`;
}

/** topic1 on ParticipantCredited/Debited is bytes32 chain138TxHash. */
export function chain138TxHashFromLogTopic(topic: string | undefined): string | null {
  if (!topic) return null;
  try {
    return ethers.hexlify(topic);
  } catch {
    return null;
  }
}

export type DecodedRegistryLogLink = {
  chain138TxHash: string;
  chain138ExplorerUrl: string;
  mainnetTxHash: string;
  mainnetExplorerUrl: string;
  blockNumber: string;
  logIndex: string;
};

type EtherscanLogRow = {
  topics?: string[];
  transactionHash?: string;
  blockNumber?: string;
  logIndex?: string;
};

type EtherscanLogsEnvelope = {
  status: string;
  message: string;
  result: EtherscanLogRow[];
};

export function enrichRegistryLogsEnvelope(
  envelope: unknown,
  explorerBase?: string
): { raw: unknown; decoded: DecodedRegistryLogLink[] } {
  const base = explorerBase ?? chain138ExplorerBase();
  if (!envelope || typeof envelope !== 'object') {
    return { raw: envelope, decoded: [] };
  }
  const e = envelope as EtherscanLogsEnvelope;
  if (e.status !== '1' || !Array.isArray(e.result)) {
    return { raw: envelope, decoded: [] };
  }
  const decoded: DecodedRegistryLogLink[] = [];
  for (const log of e.result) {
    const chain138TxHash = chain138TxHashFromLogTopic(log.topics?.[1]);
    if (!chain138TxHash || !log.transactionHash) continue;
    decoded.push({
      chain138TxHash,
      chain138ExplorerUrl: chain138ExplorerTxUrl(chain138TxHash, base),
      mainnetTxHash: log.transactionHash,
      mainnetExplorerUrl: `https://etherscan.io/tx/${log.transactionHash}`,
      blockNumber: String(log.blockNumber ?? ''),
      logIndex: String(log.logIndex ?? ''),
    });
  }
  return { raw: envelope, decoded };
}
