import { ethers } from 'ethers';
import { chain138ExplorerTxUrl, chain138TxHashFromLogTopic } from './chain138Explorer';

export type DecodedSurfaceNotificationLog = {
  participant: string;
  chain138TxHash: string;
  chain138ExplorerUrl: string;
  instructionId: string;
  direction: number;
  mainnetTxHash: string;
  mainnetExplorerUrl: string;
  blockNumber: string;
  logIndex: string;
};

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

/** topic0 = Chain138ActivityNotified(address,bytes32,bytes32,uint8,uint64,uint256,uint64,bool) */
export const CHAIN138_ACTIVITY_NOTIFIED_TOPIC0 =
  '0x8dfc8206f97c75e58117c233ab5193e49d50c17bd4d035cdafebcf6794168ffe';

export function decodeChain138ActivityNotifiedLogs(
  envelope: { status: string; result: EtherscanLogRow[] },
  explorerBase?: string
): DecodedSurfaceNotificationLog[] {
  if (envelope.status !== '1' || !Array.isArray(envelope.result)) return [];
  const out: DecodedSurfaceNotificationLog[] = [];
  for (const log of envelope.result) {
    const t = log.topics ?? [];
    if (t.length < 4 || !log.transactionHash) continue;
    const participant = t[1] ? ethers.getAddress('0x' + t[1].slice(-40)) : '';
    const chain138TxHash = chain138TxHashFromLogTopic(t[2]);
    if (!chain138TxHash) continue;
    const instructionId = t[3] ?? '';
    let direction = 0;
    if (log.data && log.data.length >= 66) {
      try {
        const decoded = ethers.AbiCoder.defaultAbiCoder().decode(
          ['uint8', 'uint64', 'uint256', 'uint64', 'bool'],
          log.data
        );
        direction = Number(decoded[0]);
      } catch {
        /* non-fatal */
      }
    }
    out.push({
      participant,
      chain138TxHash,
      chain138ExplorerUrl: chain138ExplorerTxUrl(chain138TxHash, explorerBase),
      instructionId,
      direction,
      mainnetTxHash: log.transactionHash,
      mainnetExplorerUrl: `https://etherscan.io/tx/${log.transactionHash}`,
      blockNumber: String(log.blockNumber ?? ''),
      logIndex: String(log.logIndex ?? ''),
    });
  }
  return out;
}
