import { Claim, ClaimKey, constructRead, extractRead } from '@coinweb/contract-kit';

import { TypedClaim } from '../../../types';
import { context } from '../../context';
import { opMarker } from '../../globals/promise';
import { pushAwaitedTask, shiftResolvedOp } from '../../runtime';
import { isResolvedReadOp, isResolvedSlotOp } from '../../utils';

export const readOp = <TClaim extends Claim = TypedClaim>(key: ClaimKey) => {
  let opMarkerValue = false;

  const result = new Promise<TClaim | null>((resolve, reject) => {
    try {
      const { op, isOp } = shiftResolvedOp();

      if (!isOp) {
        pushAwaitedTask(constructRead(context.issuer, key));
        opMarkerValue = true;
      } else {
        if (isResolvedSlotOp(op)) {
          return;
        }

        if (!isResolvedReadOp(op)) {
          console.log(JSON.stringify(op));

          throw new Error('Read operation not found');
        }

        const claim = (extractRead(op)?.[0]?.content ?? null) as TClaim | null;

        console.log('ResolveRead claim: ', claim);
        resolve(claim);
      }
    } catch (error) {
      reject(error);
    }
  });

  (result as Promise<TClaim | null> & { [opMarker]: boolean })[opMarker] = opMarkerValue;

  return result;
};
