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 { ErrorResponse } from '../ResponseDTOs/ErrorResponse';
import { PayInCreateOrderResponse } from '../ResponseDTOs/PayInCreateOrderResponse';
import { createSign } from '../Utils/Util';
import { TransactionResultsResponse } from '../ResponseDTOs/TransactionResultsResponse';
import {  createHeader, removeUndefinedValues, transformUndefinedToNull } from '../Utils/Util'; 
import { PayInCreateOrderResponseData } from '../ResponseDTOs/PayInCreateOrderResponseData';
import { API_ENDPOINTS_LIVE, API_ENDPOINTS_SANDBOX  } from '../EndpointsConstant'; 


export class PayWithWalletService {

 

  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: CreateOrderRequestBuilder): 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: QueryOrderResultBuilder): Promise<PayInCreateOrderResponse<TransactionResultsResponse>> {
      const orderStatusRequest = builder.build();
      console.log(`Order Request: ${orderStatusRequest.toJSON}`)
      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, orderStatusRequest.toJSON(), { headers: header });
        return response.data;
      } catch (error) {
        if (axios.isAxiosError(error)) {
          throw new Error(`Error message: ${error.message}`);
        } else {
          throw new Error('Unexpected error');
        }
      }
    }

  
}
