import {
  Claim,
  ClaimKey,
  CwebStore,
  GStore,
  OrdJson,
  PreparedOperation,
  ResolvedOperation,
  User,
} from '@coinweb/contract-kit';

import { LockedKey } from './onchain/mutex';

export type HexBigInt = `0x${string}`;

export type TypedClaim<TBody extends OrdJson = OrdJson, TKey extends ClaimKey = ClaimKey> = Claim & {
  body: TBody;
  fees_stored: HexBigInt;
  key: TKey;
};

export type ResolvedSlotOp = {
  SlotOp:
    | {
        ok: false;
        error: string;
      }
    | {
        ok: true;
      };
};

export type ResolvedExecOp = {
  ExecOp: {
    id: string;
  };
};

export type ResolvedChildOp = {
  ChildOp: 0;
};

export type ResolvedLockOp = {
  LockOp: {
    lockId: string;
    timestamp: number;
  };
};

export type ResolvedUnlockOp = {
  UnlockOp: 0;
};

export type ResolvedOp =
  | ResolvedOperation
  | ResolvedSlotOp
  | ResolvedExecOp
  | ResolvedChildOp
  | ResolvedLockOp
  | ResolvedUnlockOp;

export type PreparedExecOp = {
  ExecOp: {
    id: string;
  };
};

export type PreparedLockOp = {
  LockOp: {
    lockId: string;
    keys: LockedKey[];
    timestamp: number;
  };
};

export type PreparedUnlockOp = {
  UnlockOp: {
    lockId: string;
    timestamp: number;
  };
};

export type PreparedExtendedStoreOp = GStore<CwebStore> & { providedCweb?: bigint };

export type PreparedOp =
  | PreparedOperation
  | PreparedExecOp
  | PreparedLockOp
  | PreparedUnlockOp
  | PreparedExtendedStoreOp;

export type Task = {
  op: PreparedOp;
  batchId: number;
};

export type ExecutorMethodArgs = [
  initialArgs?: unknown[],
  resolvedOps?: ResolvedOp[],
  caller?: User,
  thisId?: string,
  parentId?: string,
  saveResult?: boolean,
  takenFundsIds?: string[],
  execOpsIndexes?: number[],
];
