import { HttpRequest, HttpStatusCodes } from '../base';
import { AUTH_TOKEN } from '../commands';
import {
  generateEventData,
  generateEventEditData,
  generateEventItemDataWithCarsTrains
} from './factory';
import { TeamEventParamsStringInvitees } from '@group-events-lib/interface';

Cypress.Commands.add(
  'createTeamEventViaApi',
  (teamEventParams: TeamEventParamsStringInvitees) => {
    if (!AUTH_TOKEN) {
      throw new Error('Please login before calling api endpoints');
    }

    const eventDataBody = generateEventData(teamEventParams);

    const eventEditBody = generateEventEditData(teamEventParams.eventName);

    createTeamEvent(eventDataBody).then((body) => {
      sendTeamInvitation(body.uuid, eventEditBody);

      getEventItem(body).then((item) => {
        cy.log('ITEMS: ' + JSON.stringify(item));
        const eventItemBody = generateEventItemDataWithCarsTrains(item);

        editEventItem(body.uuid, eventItemBody);
      });
    });
  }
);

function createTeamEvent(body: any): Cypress.Chainable<any> {
  return cy
    .request({
      method: HttpRequest.Post,
      url: '/api/user/teamEvents?sendInvite=false',
      headers: {
        Authorization: AUTH_TOKEN
      },
      body,
      retryOnStatusCodeFailure: true
    })
    .then(({ status, body }) => {
      expect(status, 'Team event created').to.equal(HttpStatusCodes.Ok);

      return body;
    });
}

function sendTeamInvitation(invitationId: string, body: any) {
  cy.request({
    method: HttpRequest.Patch,
    url: `/api/user/teamEvents/${invitationId}/edit`,
    headers: {
      Authorization: AUTH_TOKEN
    },
    body,
    failOnStatusCode: true
  });
  cy.request({
    method: HttpRequest.Post,
    url: `/api/user/teamEvents/${invitationId}/sendInvite`,
    headers: {
      Authorization: AUTH_TOKEN
    },
    retryOnStatusCodeFailure: true
  }).then(({ status }) => {
    expect(status, 'Team event invitation send').to.equal(HttpStatusCodes.Ok);
  });
}

function getEventItem(body: any): Cypress.Chainable<any> {
  cy.allure().logStep('retrieve event item');
  return cy
    .request({
      method: HttpRequest.Get,
      url: `/api/user/teamEvents/${body.uuid}`,
      headers: {
        Authorization: AUTH_TOKEN
      },
      retryOnStatusCodeFailure: true
    })
    .then(({ body, status }) => {
      expect(status, 'Event item data received').to.equal(HttpStatusCodes.Ok);
      return body.items[0];
    });
}

function editEventItem(uuid: string, body: any) {
  console.log('TRYING HERE: ' + JSON.stringify(body));
  return cy
    .request({
      method: HttpRequest.Put,
      url: `/api/user/teamEvents/${uuid}/items/${body.uuid}`,
      headers: {
        Authorization: AUTH_TOKEN
      },
      body,
      retryOnStatusCodeFailure: true
    })
    .then(({ status }) => {
      expect(status, 'Team event created').to.equal(HttpStatusCodes.Ok);
    });
}
