import { extractContractArgs } from '@coinweb/contract-kit';

import { ResolvedOp, TypedClaim } from '../../types';
import { resultKey } from '../claims/result';
import { isResolvedBlockOp, isResolvedReadOp, isResolvedTakeOp } from '../utils';

import { getRawContext } from './context';

export const extractOps = () => {
  const contractArgs = extractContractArgs(getRawContext().tx);

  if (!contractArgs.length) {
    return {
      extractedOps: [],
      fundsOps: [],
    };
  }

  const [fundsOp, ...resolvedOps] = contractArgs;

  if (!isResolvedReadOp(fundsOp)) {
    throw new Error('Wrong funds claims');
  }

  const extractedOps: ResolvedOp[] = [];

  let i = 0;

  while (i < resolvedOps.length) {
    const op = resolvedOps[i];

    if (isResolvedBlockOp(op)) {
      const { first } = op.BlockOp.blocks_on[0][0];

      //Maybe it is needed to check more conditions here
      if (Array.isArray(first) && first[0] === resultKey) {
        const nextAfterBlock = resolvedOps[i + 1];

        if (!isResolvedTakeOp(nextAfterBlock)) {
          throw new Error('Wrong subcall result');
        }

        extractedOps.push({ ChildOp: 0 }, ...(nextAfterBlock.TakeOp.result as TypedClaim<ResolvedOp[]>).body);

        i += 2;
        continue;
      }
    }

    extractedOps.push(op);
    i++;
  }

  return {
    fundsOp,
    extractedOps,
  };
};
