import { HttpRequest, HttpStatusCodes } from '../base';
import { AUTH_TOKEN } from '../commands';
import { getTravelSetting, updateDefaultRule } from './factory/trip_proposal';
import {
  generateBlackCarPolicyData,
  generateFlightPolicyData,
  generateHotelPolicyData,
  generateRentalCarPolicyData,
  generateRentalCarClassPolicyData
} from './index';

export type PolicyVertical = 'flight' | 'flight-invites' | 'hotel' | 'car' | 'black car';
type ruleType = 'costs' | 'approval' | 'enabled' | 'allowedCarTypes';

Cypress.Commands.add('createFlightPolicy', (policyVertical: PolicyVertical = 'flight') => {
  getPolicyIds(policyVertical, ['costs'])
    .then((policyId) => generateFlightPolicyData(policyVertical, policyId))
    .then((body) => updateTravelPolicy(body));
});

Cypress.Commands.add('createHotelPolicy', (policyName) => {
  getPolicyIds('hotel', ['costs', 'approval'])
    .then((policyIds) => generateHotelPolicyData(policyIds, 1, policyName))
    .then((body) => updateTravelPolicy(body));
});

Cypress.Commands.add('createRentalCarPolicyWithHardApproval', (maxPrice) => {
  getPolicyIds('car', ['costs', 'approval'])
    .then((policyIds) => generateRentalCarPolicyData(policyIds, maxPrice))
    .then((body) => updateTravelPolicy(body));
});

Cypress.Commands.add('createRentalCarClassPolicyWithHardApproval', () => {
  getPolicyIds('car', ['allowedCarTypes', 'approval'])
    .then((policyIds) => generateRentalCarClassPolicyData(policyIds))
    .then((body) => updateTravelPolicy(body));
});

Cypress.Commands.add('enableBlackCarPolicy', () => {
  getPolicyIds('black car', ['enabled'])
    .then((policyIds) => generateBlackCarPolicyData(policyIds))
    .then((body) => updateTravelPolicy(body));
});

function getPolicyIds(module: PolicyVertical, list: ruleType[]) {
  if (AUTH_TOKEN) {
    return cy
      .request({
        method: HttpRequest.Get,
        url: `/api/adminpolicyengine/v1/rules/${module}`,
        headers: {
          Authorization: AUTH_TOKEN
        },
        retryOnStatusCodeFailure: true
      })
      .then(({ body, status }) => {
        console.log(`here is the body: ${body}`);
        expect(status, `Retrieve ${module} policy ids`).to.equal(HttpStatusCodes.Ok);
        return body.filter((data: any) => list.includes(data.name)).map((result: any) => result.defaultRule.uuid);
      });
  } else {
    throw new Error('Please login before calling api endpoints');
  }
}

Cypress.Commands.add('enableTripProposal', () => {
  return getTravelSetting().then((defaultRule) => {
    return updateDefaultRule(defaultRule);
  });
});

function updateTravelPolicy(body: any) {
  if (AUTH_TOKEN) {
    cy.request({
      method: HttpRequest.Patch,
      url: '/api/adminpolicyengine/v1/rules',
      headers: {
        Authorization: AUTH_TOKEN
      },
      body,
      retryOnStatusCodeFailure: true
    }).then(({ status }) => {
      expect(status, 'Travel policy updated').to.equal(HttpStatusCodes.Ok);
    });
  } else {
    throw new Error('Please login before calling api endpoints');
  }
}
