import axios from 'axios';
import { Injectable } from '@nestjs/common';
import * as moment from 'jalali-moment';
import { ConfigurationService } from '../../config/configuration.service';
import { meliBankEncrypt } from '../../utils';

@Injectable()
export class BankMeliService {
  private axios;
  private redirectUrl;

  constructor(private config: ConfigurationService) {
    this.axios = axios.create({
      baseURL: 'https://sadad.shaparak.ir/api/v0',
    });

    this.redirectUrl = (token) =>
      `https://sadad.shaparak.ir/Purchase?token=${token}`;
  }

  /**
   * @param amount Amount based on Rial
   */
  async paymentRequest(
    amount: number,
    callbackURL: string,
    orderId: number,
    mobile: string,
    applicationName: string,
  ) {
    const signData = meliBankEncrypt(
      `${this.config.gateway.bankMeliTerminalId};${orderId};${amount}`,
      this.config.gateway.bankMeliTerminalKey,
    );

    const { data } = await this.axios.post('/Request/PaymentRequest', {
      MerchantId: this.config.gateway.bankMeliMerchantId,
      TerminalId: this.config.gateway.bankMeliTerminalId,
      Amount: amount, // Rial
      SignData: signData,
      ReturnUrl: callbackURL,
      LocalDateTime: moment().format('M/D/Y h:m:s a'),
      OrderId: orderId,
      UserId: +mobile,
      ApplicationName: applicationName,
    });

    if (+data.ResCode !== 0) {
      throw new Error('اتصال به درگاه برقرار نشد، لطفا مجدد تلاش کنید');
    }

    return {
      code: data.ResCode,
      message: data?.Description || '',
      authority: data.Token,
      url: this.redirectUrl(data.Token),
    };
  }

  /**
   * **********************************
   */
  async paymentVerification(authority) {
    const signData = meliBankEncrypt(
      authority,
      this.config.gateway.bankMeliTerminalKey,
    );

    const { data } = await this.axios.post('/Advice/Verify', {
      Token: authority,
      SignData: signData,
    });

    if (+data.ResCode !== 0) {
      throw 'خطایی رخ داده است، با پشتیبانی 09391857423 تماس حاصل فرمایید';
    }

    return {
      code: data.ResCode,
      amount: data.Amount,
      message: data?.Description || '',
      referenceNumber: data.RetrivalRefNo,
      tranceNumber: data.SystemTraceNo,
    };
  }
}
