import * as O from 'fp-ts/Option';
import { delay } from 'rxjs/operators';
import { getOrDefault, getOrError } from '../../../utils';
import carsCalculatorApi from '../api/cars-calculator.api';
import sessionQuery from './session.query';
import sessionStore from './session.store';
export class CarsCalculatorService {
  constructor() {
    sessionQuery
      .select(['user', 'vehicle'])
      .pipe(delay(0))
      .subscribe((state) => this.attemptQuoteCalculationAsync(state.user, state.vehicle));
  }
  selectVariant(variant) {
    sessionStore.update((state) => ({
      vehicle: Object.assign(Object.assign({}, state.vehicle), { selectedVariant: variant })
    }));
  }
  generateCarsEnquiryRequest() {
    const vehicle = sessionQuery.vehicle;
    const variant = getOrError(vehicle.selectedVariant);
    const result = sessionQuery.result;
    const details = sessionQuery.userDetails;
    const user = sessionQuery.user;
    return {
      chosenVariant: {
        variant_id: variant.variantId,
        short_description: variant.description,
        build_year: variant.buildYear,
        model_month: variant.modelMonth,
        list_price_gross: variant.listPriceGross,
        engine_litres: variant.engineLitres,
        fuel_type_translation_id: variant.fuelTypeId,
        transmission: variant.transmission
      },
      quoteRequest: {
        variantId: variant.variantId,
        isUsedCarRequested: getOrError(vehicle.isUsedCarRequested),
        approximatePrice: getOrDefault(vehicle.approximatePrice, variant.listPriceGross),
        annualSalaryGross: getOrError(user.annualSalary),
        payPeriod: getOrError(user.paymentPeriod),
        annualKm: getOrError(user.annualKms),
        state: getOrError(user.state),
        leaseTermInYears: getOrError(user.term),
        employmentType: getOrError(user.employmentType)
      },
      websiteQuote: {
        afterTaxEffectPerPayCycle: getOrError(result.afterTaxEffectPerPayCycle),
        totalTaxSavings: getOrError(result.taxSaving),
        residualValueGross: getOrError(result.residualValue),
        financedAmount: getOrError(result.financedAmount),
        fuel: getOrError(result.fuel),
        serviceAndMaintenance: getOrError(result.serviceAndMaintenance),
        registrationAndCtp: getOrError(result.registrationAndCtp),
        comprehensiveInsurance: getOrError(result.comprehensiveInsurance),
        managementFee: getOrError(result.managementFee)
      },
      contactDetails: {
        firstName: getOrError(details.userFirstName),
        lastName: getOrError(details.userLastName),
        email: getOrError(details.emailAddress),
        mobileNumber: getOrError(details.contactNumber),
        employerName: getOrError(details.employerName)
      }
    };
  }
  async attemptQuoteCalculationAsync(user, vehicle) {
    const isAllInformationAvailable = O.isSome(user.annualKms) &&
      O.isSome(user.annualSalary) &&
      O.isSome(user.paymentPeriod) &&
      O.isSome(user.state) &&
      O.isSome(user.term) &&
      O.isSome(user.employmentType) &&
      O.isSome(vehicle.selectedVariant);
    if (!isAllInformationAvailable) {
      return;
    }
    sessionStore.updateQuote({
      afterTaxEffectPerPayCycle: O.none,
      taxSaving: O.none,
      residualValue: O.none,
      financedAmount: O.none,
      fuel: O.none,
      serviceAndMaintenance: O.none,
      registrationAndCtp: O.none,
      comprehensiveInsurance: O.none,
      managementFee: O.none,
      quoteState: 'Calculation pending'
    });
    const variant = getOrError(vehicle.selectedVariant);
    const isUsedCarRequested = getOrError(vehicle.isUsedCarRequested);
    const price = isUsedCarRequested
      ? getOrDefault(vehicle.approximatePrice, variant.listPriceGross)
      : variant.listPriceGross;
    const req = {
      variantId: variant.variantId,
      isUsedCarRequested: getOrError(vehicle.isUsedCarRequested),
      approximatePrice: price,
      annualSalaryGross: getOrError(user.annualSalary),
      payPeriod: getOrError(user.paymentPeriod),
      annualKm: getOrError(user.annualKms),
      state: getOrError(user.state),
      leaseTermInYears: getOrError(user.term),
      employmentType: getOrError(user.employmentType)
    };
    const response = await carsCalculatorApi.postCarsQuoteResult(req);
    const quoteResult = {
      afterTaxEffectPerPayCycle: O.some(response.afterTaxEffectPerPayCycle),
      taxSaving: O.some(response.totalTaxSavings),
      residualValue: O.some(response.residualValueGross),
      financedAmount: O.some(response.financedAmount),
      fuel: O.some(response.fuel),
      serviceAndMaintenance: O.some(response.serviceAndMaintenance),
      registrationAndCtp: O.some(response.registrationAndCtp),
      comprehensiveInsurance: O.some(response.comprehensiveInsurance),
      managementFee: O.some(response.managementFee),
      quoteState: 'Calculated'
    };
    sessionStore.updateQuote(quoteResult);
  }
}
export default new CarsCalculatorService();
