import 'reflect-metadata';
import axios from 'axios';
import { plainToClass } from 'class-transformer';
import { CreateOrderRequest } from '../RequestDTOs/CreateOrderRequest';
import { CreateOrderRequestBuilder } from '../RequestDTOs/CreateOrderRequest';
import { QueryOrderResultBuilder } from '../RequestDTOs/QueryOrderResultRequest';
import { VerifyUtil } from '../Utils/VerifyUtil';
import { verify } from 'crypto';
import { ErrorResponse } from '../ResponseDTOs/ErrorResponse';
import { PayInCreateOrderResponse } from '../ResponseDTOs/PayInCreateOrderResponse';
import { PayInCreateOrderResponseData } from '../ResponseDTOs/PayInCreateOrderResponseData';
import { TransactionResultsResponse } from '../ResponseDTOs/TransactionResultsResponse';


import {  createHeader, removeUndefinedValues, transformUndefinedToNull } from '../Utils/Util'; 
import { BuildPayload } from '../RequestDTOs/PaymentRequest';
import { createSign } from '../Utils/Util';
import { API_ENDPOINTS_LIVE, API_ENDPOINTS_SANDBOX  } from '../EndpointsConstant'; 










export class PayWithMMOService {

 

  constructor(
    private appId: string,
    private countryCode: string,
    private privateKey: string,
    private isTest: boolean
  ) {
    this.appId = appId
    this.countryCode = countryCode;
    this.privateKey = privateKey;
    this.isTest = isTest
  }

  private getCountryCode() {
    return this.countryCode

  }

  private getAppId() {
    return this.appId

  }

  private getPrivateKey() {
    return this.privateKey

  }

  private getIsTest() {
    return this.isTest

  }


   
    
  
    

  async createOrder(builder: BuildPayload): Promise<PayInCreateOrderResponse<PayInCreateOrderResponseData>>{
    const createOrderRequest = builder.build();
    
    try {
      const createOrderEndpoint = this.isTest ? API_ENDPOINTS_SANDBOX.CREATE_ORDER : API_ENDPOINTS_LIVE.CREATE_ORDER;
      const signedRequest = createSign(builder, this.privateKey)
        const header = createHeader(this.countryCode,signedRequest, 'Bearer '.concat(this.appId),'application/json')  
        const response = await axios.post(createOrderEndpoint, createOrderRequest.toJSON(), { headers: header });
        console.log("Order Response Data: ",response.data)
      return response.data;


    } catch (error) {
      if (axios.isAxiosError(error)) {
        throw new Error(`Error message: ${error.message}`);
      } else {
        console.log("Unexpected error", error)
        throw new Error
      }
    }
  }


  async fetchOrderStatus(builder: BuildPayload): Promise<PayInCreateOrderResponse<TransactionResultsResponse>>{
    const fetchOrderStatus = builder.build();
    
    try {
      const orderStatusEndpoint = this.isTest ? API_ENDPOINTS_SANDBOX.ORDER_STATUS : API_ENDPOINTS_LIVE.ORDER_STATUS;
      const signedRequest = createSign(builder, this.privateKey)
        const header = createHeader(this.countryCode,signedRequest, 'Bearer '.concat(this.appId),'application/json')  
        const response = await axios.post(orderStatusEndpoint, fetchOrderStatus.toJSON(), { headers: header });
        console.log("Order Response Data: ",response.data)
      return response.data;


    } catch (error) {
      if (axios.isAxiosError(error)) {
        throw new Error(`Error message: ${error.message}`);
      } else {
        console.log("Unexpected error", error)
        throw new Error
      }
    }
  }

  
}
