import faker from 'faker';

import { mockGQL, mockGQL404 } from 'mtest/fetchMocks/mockGQL';
import { CHANNEL, makeFakeChannelGQL } from 'mtest/fetchMocks/channel';
import { GAME_1 } from 'mtest/fetchMocks/games';
import { VOD, VOD_JSON, VOD_DETAILS } from 'mtest/fetchMocks/vods';

import { FetchEventGQL, EventDataPayload } from 'mweb/common/fetch/events';
import {
  ChannelOnlineStatus,
  ChannelSubscribableStatus,
  ChannelDetails,
} from 'mweb/common/reducers/data/channels';
import {
  EventModel,
  PremiereEventModel,
  EventType,
  PremiereStatus,
} from 'mweb/common/reducers/data/events';

const endTime = faker.date.future();

export const EVENT_ID = faker.random.number().toString();
export const NOT_EVENT_ID = 'cheeseburger';
export const PREMIERE_ID = faker.random.number().toString();

const CHANNEL_GQL = makeFakeChannelGQL(CHANNEL);

const EVENT_GQL_NO_DATA: FetchEventGQL = {
  data: {
    event: null,
  },
};

export const EVENT_GQL_WITHOUT_GAME: FetchEventGQL = {
  data: {
    event: {
      __typename: 'SingleEvent',
      id: EVENT_ID,
      startAt: faker.date.between(new Date(), endTime).toISOString(),
      endAt: endTime.toISOString(),
      title: faker.hacker.phrase(),
      description: faker.lorem.paragraphs(1),
      imageURL: faker.image.imageUrl(),
      channel: CHANNEL_GQL,
      game: undefined,
      premiere: undefined,
    },
  },
};

export const EVENT_GQL: FetchEventGQL = {
  data: {
    event: {
      ...EVENT_GQL_WITHOUT_GAME.data.event!,
      game: GAME_1,
    },
  },
};

export const EVENT_GQL_UNSUPPORTED: FetchEventGQL = {
  data: {
    event: {
      ...EVENT_GQL.data.event!,
      __typename: 'NOT_A_REAL_TYPE',
    },
  },
};

export function createPremiereEventGQL(
  status: PremiereStatus = PremiereStatus.Success,
): FetchEventGQL {
  return {
    data: {
      event: {
        ...EVENT_GQL.data.event!,
        __typename: 'PremiereEvent',
        premiere: {
          id: PREMIERE_ID,
          status,
          pastPremiere:
            status === PremiereStatus.Success ? VOD_JSON.data.video : undefined,
        },
      },
    },
  };
}

const EVENT = EVENT_GQL.data.event!;
const USER = EVENT.channel;
const PREMIERE_EVENT = createPremiereEventGQL().data.event;

export const EVENT_MODEL_WITHOUT_GAME: EventModel = {
  id: EVENT.id,
  type: EventType.SingleEvent,
  startTime: new Date(EVENT.startAt).valueOf(),
  endTime: new Date(EVENT.endAt).valueOf(),
  coverImageTemplateURL: EVENT.imageURL,
  description: EVENT.description,
  title: EVENT.title,
  channel: EVENT.channel.login!,
  game: undefined,
};

export const EVENT_MODEL: EventModel = {
  ...EVENT_MODEL_WITHOUT_GAME,
  game: GAME_1.name,
};

export const PREMIERE_EVENT_MODEL: PremiereEventModel = {
  ...EVENT_MODEL,
  type: EventType.PremiereEvent,
  premiere: {
    id: PREMIERE_EVENT!.premiere!.id,
    status: PREMIERE_EVENT!.premiere!.status,
    vodID: VOD,
  },
};

export const CHANNEL_DETAILS: ChannelDetails = {
  game: USER.stream!.game!.name,
  displayName: USER.displayName!,
  hostedChannel: undefined,
  id: USER.id!,
  logoURL: USER.profileImageURL!,
  name: USER.login!,
  onlineStatus: ChannelOnlineStatus.Online,
  preview: USER.stream!.previewImageURL!,
  status: USER.stream!.title!,
  viewerCount: USER.stream!.viewersCount!,
  subscribableStatus: ChannelSubscribableStatus.Unknown,
  description: USER.description!,
  bannerImageURL: USER.bannerImageURL!,
  followerCount: USER.followers!.totalCount,
  lifetimeViewerCount: USER.profileViewCount!,
};

export const EVENT_PAYLOAD: EventDataPayload = {
  event: EVENT_MODEL,
  channel: CHANNEL_DETAILS,
  game: GAME_1,
  vod: undefined,
};

export const EVENT_PAYLOAD_WITHOUT_GAME: EventDataPayload = {
  event: EVENT_MODEL_WITHOUT_GAME,
  channel: CHANNEL_DETAILS,
  game: undefined,
  vod: undefined,
};

export const PREMIERE_EVENT_PAYLOAD: EventDataPayload = {
  event: PREMIERE_EVENT_MODEL,
  channel: CHANNEL_DETAILS,
  game: GAME_1,
  vod: VOD_DETAILS,
};

export function mockEvent(): void {
  mockGQL(EVENT_GQL);
}

export function mockEventWithoutGame(): void {
  mockGQL(EVENT_GQL_WITHOUT_GAME);
}

export function mockEventUnsupportedType(): void {
  mockGQL(EVENT_GQL_UNSUPPORTED);
}

export function mockEventNotFound(): void {
  mockGQL(EVENT_GQL_NO_DATA);
}

export function mockPremiereEvent(status?: PremiereStatus): void {
  mockGQL(createPremiereEventGQL(status));
}

export function mockEvent404(): void {
  mockGQL404();
}
