import {
  CwebStore,
  isResolvedBlock,
  isResolvedRead,
  isResolvedStore,
  isResolvedTake,
  ResolvedOperation,
  ResolvedRead,
  ResolvedTake,
} from '@coinweb/contract-kit';
import { CwebBlock } from '@coinweb/contract-kit/dist/esm/operations/block';
import { CwebCallRefResolved, isResolvedCall } from '@coinweb/contract-kit/dist/esm/operations/call';
import { ResolvedBlock } from '@coinweb/contract-kit/dist/types/operations/block';
import { GBlock, GCall, GRead, GStore, GTake } from '@coinweb/contract-kit/dist/types/operations/generics';

import { PreparedExecOp, PreparedOp, ResolvedChildOp, ResolvedExecOp, ResolvedOp, ResolvedSlotOp } from '../../types';

export const isResolvedSlotOp = (op?: ResolvedOp | null): op is ResolvedSlotOp => {
  if (op && 'SlotOp' in op) {
    console.log('isResolvedSlotOp >>> ', JSON.stringify(op));
  }

  return !!(op && 'SlotOp' in op);
};

export const isResolvedExecOp = (op?: ResolvedOp | null): op is ResolvedExecOp => {
  if (op && 'ExecOp' in op) {
    console.log('isResolvedExecOp >>> ', JSON.stringify(op));
  }

  return !!(op && 'ExecOp' in op);
};

export const isResolvedChildOp = (op?: ResolvedOp | null): op is ResolvedChildOp => {
  if (op && 'ChildOp' in op) {
    console.log('isResolvedChildOp >>> ', JSON.stringify(op));
  }

  return !!(op && 'ChildOp' in op);
};

export const isResolvedBlockOp = (op?: ResolvedOp | null): op is GBlock<ResolvedBlock> => {
  if (op && 'BlockOp' in op) {
    console.log('isResolvedBlockOp >>> ', JSON.stringify(op));
  }

  return isResolvedBlock(op as ResolvedOperation); //TODO: Fix contract-kit types
};

export const isResolvedStoreOp = (op?: ResolvedOp | null): op is GStore<CwebStore> => {
  if (op && 'StoreOp' in op) {
    console.log('isResolvedStoreOp >>> ', JSON.stringify(op));
  }

  return isResolvedStore(op as ResolvedOperation); //TODO: Fix contract-kit types
};

export const isResolvedCallOp = (op?: ResolvedOp | null): op is GCall<CwebCallRefResolved> => {
  if (op && 'CallOp' in op) {
    console.log('isResolvedCallOp >>> ', JSON.stringify(op));
  }

  return isResolvedCall(op as ResolvedOperation); //TODO: Fix contract-kit types
};

export const isResolvedTakeOp = (op?: ResolvedOp | null): op is GTake<ResolvedTake> => {
  if (op && 'TakeOp' in op) {
    console.log('isResolvedTakeOp >>> ', JSON.stringify(op));
  }

  return isResolvedTake(op as ResolvedOperation); //TODO: Fix contract-kit types
};

export const isResolvedReadOp = (op?: ResolvedOp | null): op is GRead<ResolvedRead> => {
  if (op && 'ReadOp' in op) {
    console.log('isResolvedReadOp >>> ', JSON.stringify(op));
  }

  return isResolvedRead(op as ResolvedOperation); //TODO: Fix contract-kit types
};

export const isPreparedExecOp = (op?: PreparedOp | null): op is PreparedExecOp => {
  if (op && 'ExecOp' in op) {
    console.log('isPreparedExecOp >>> ', JSON.stringify(op));
  }

  return !!(op && 'ExecOp' in op);
};

export const isPreparedBlockOp = (op?: PreparedOp | null): op is GBlock<CwebBlock> => {
  if (op && 'BlockOp' in op) {
    console.log('isPreparedBlockOp >>> ', JSON.stringify(op));
  }

  return !!(op && 'BlockOp' in op);
};
