import { Claim, ClaimKey, constructRangeRead, extractRead, isResolvedRead } from '@coinweb/contract-kit';
import { ClaimRange } from '@coinweb/contract-kit/dist/types/operations/read';

import { TypedClaim } from '../../../types';
import { context } from '../../context';
import { pushAwaitedOp } from '../awaited';
import { shiftResolvedOp } from '../resolved';

export const rangeReadOp = <TClaims extends Claim[] = TypedClaim[]>(
  firstPart: ClaimKey['first_part'],
  range: ClaimRange,
  maxCount: number
) => {
  return new Promise<TClaims | null>((resolve, reject) => {
    try {
      const { op, isOp } = shiftResolvedOp();

      if (!isOp) {
        pushAwaitedOp(constructRangeRead(context.issuer, firstPart, range, maxCount));
      } else {
        if (op && !isResolvedRead(op)) {
          throw new Error('Read operation not found');
        }

        const claim = op && ((extractRead(op)?.map((result) => result.content) ?? null) as TClaims | null);
        resolve(claim);
      }
    } catch (error) {
      reject(error);
    }
  });
};
