import { Chance } from 'chance';
import {
  AsyncJob,
  GetAsyncJobResponse,
  Status,
} from '@wix/bex-utils/@wix/ambassador-infra-asyncjobs-v1-async-job/types';
import { getAsyncJob } from '@wix/bex-utils/@wix/ambassador-infra-asyncjobs-v1-async-job/http';

const chance = new Chance();

export const anAsyncJob = (overrides: Partial<AsyncJob> = {}): AsyncJob => ({
  id: `${chance.word()}_${chance.integer({ min: 0, max: 1000 })}`,
  status: 'FINISHED' as Status,
  ...overrides,
});

export const resolveAsyncJob = ({
  whenRequest,
  job,
  spy,
  persist = true,
}: {
  whenRequest: typeof import('@wix/http-client-testkit/client').whenRequest;
  job: AsyncJob;
  spy?: jest.Mock;
  persist?: boolean;
}) => {
  const request = whenRequest(getAsyncJob).reply(200, async () => {
    if (spy) {
      spy();
    }

    const data = {
      job,
    };

    return data;
  });

  if (persist) {
    return request.persist();
  }

  return request;
};

export const rejectAsyncJob = ({
  whenRequest,
  persist = true,
}: {
  whenRequest: typeof import('@wix/http-client-testkit/client').whenRequest;
  persist?: boolean;
}) => {
  const request = whenRequest(getAsyncJob).reply(400, async () => {
    return new Promise((_, reject) =>
      window.setTimeout(() => {
        return reject(new Error('Async job failed'));
      }, 0),
    );
  });

  if (persist) {
    return request.persist();
  }

  return request;
};

export function asyncJobMocks(
  whenRequest: typeof import('@wix/http-client-testkit/client').whenRequest,
) {
  return {
    mocks: [
      whenRequest(getAsyncJob)
        .reply(200, async () => {
          const res: GetAsyncJobResponse = {
            job: anAsyncJob(),
          };

          return res;
        })
        .persist(),
    ] as import('@wix/http-client-testkit').AnyScenario[],
  };
}
