import { Inject, Logger, Provide } from '@midwayjs/decorator';
import { BaseService } from '@cool-midway/core';
import * as _ from 'lodash';
import * as moment from 'moment';
import { Utils } from '../../../../comm/utils';
import { HttpService } from '@midwayjs/axios';
import { ILogger } from '@midwayjs/logger';
import * as forge from 'node-forge';

const HOST = "https://payment.alchemytech.cc";
const MCH_ID = 'AC202299319';
const KEY = 'r1t8hnmj86i1zt7ywbin';
const PRIVATE_KEY = "-----BEGIN RSA PRIVATE KEY-----\n" + "MIICdwIBADANBgkqhkiG9w0BAQEFAASCAmEwggJdAgEAAoGBAK/q2uuuf+s4pd2gkVAyhHkpog1o4RL5+Dm2ZOe5i7O/ELKJvj/9JIrNO1abNNuG8g2nvBnOeJ5uii1q83Qy9C4aaey1UjqYd3iVupuO8Xfmr/3sHTec6R8X0HZnuQ/fsU8uREYEQFUfBFcZtiNz2TqXfjJXMXAeTpXc6CbKOLe3AgMBAAECgYAYDVvWSnsJ7apb9Ya4uNd8+3DBNZxEbHIAbgw41Jkhv9doGcYt2I4k/i+FRV5CP56buFnTC3RZcRKqaAuWURsqcnDG8ufFIhoSEiD11FcFrXanFdixfj9gijuPiTE4w9f07eDVEfdQjFMSO8tYDbsMUoaMPUTOoreqyy86uW0G0QJBAN5zaUsxjgtJhqO3OsoHXpu+67bsM2ounuoHWq7KehiVeb9ykrS6quZ1+r5+0SIMEFkKZKbpwfIG+Hi9NII85/ECQQDKctaP1WQzuLQvm97lfQEfgY/JWL9RZuWriGd7fDT7Nrl0FTK5O9q22HvJdwIQktaTOQca28KzHucIxa7ouYInAkB1KehteF5OR52ooRtPyW3lLjvMjr/Nz1xX+yOiKHcCd8g2M8xdcGwPEljM+NKB0kTSAQ1edIR4S3+XaGA9sIKhAkEAsfVaqJry9wgw0/zXZbGJsDFKvLpXiu3BjBReqszXIdDMGr+bk/qKWtpXjhQf64O4PTgPB8wQDTZn7m0fQJH5VwJBAIDnGXiaoMRammmmOl6sYwar8APUMhRkCNqxzwiEokmwRsrR0GKuKtLKpRg/jNAAQbj2ajVihhgR7F3/04kc/jE=\n" + "-----END RSA PRIVATE KEY-----\n"
const PUBLIC_KEY = "-----BEGIN PUBLIC KEY-----\n" + "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCv6trrrn/rOKXdoJFQMoR5KaINaOES+fg5tmTnuYuzvxCyib4//SSKzTtWmzTbhvINp7wZzniebootavN0MvQuGmnstVI6mHd4lbqbjvF35q/97B03nOkfF9B2Z7kP37FPLkRGBEBVHwRXGbYjc9k6l34yVzFwHk6V3Ogmyji3twIDAQAB" + "\n-----END PUBLIC KEY-----";
const PAY_URL = '/nh-gateway/card/payment';
const QUERY_URL = '/nh-gateway/card/query'
// const BALANCE_URL = '/api/v3/bra/query/balance'
// const BANK_URL = '/api/v3/bra/query/bank';
// const WITHDRAW_URL = '/api/v3/bra/createTransferOrder';
// const QUERY_WITHDRAW_URL = '/api/v3/bra/query/transferOrder'

const NOTIFY_HOST = `http://157.175.73.225/api/admin/dj/open/ach/notifyOrder`;
// const WITHDRAW_NOTIFY_HOST = `http://157.175.73.225/api/admin/dj/open/ach/notifyWithdraw`;

const PAY_TYPE = {
  "INR": 'INDIA_PAY',
  "BRL": "BRAZIL_PAY",
  "MXN": "MEXICO_PAY",
  "JPY": "JAPAN_PAY",
  "VND": "VIETNAM_PAY",
  "PHP": "PHILIPPINES_PAY",
  "IDR": "INDONESIA_PAY"
}

const PAY_MODEL = {
  "BANK": 'BankTransfer',
  "PIX": "Pix",
  "UPI": "UPI",
  "MOMO": "MOMO_PAY",
  "COINS": "Coins",
  "BPI": "BPI",
  "PAYMAYA": "Paymaya",
  "QRIS": "QRIS",
  "VA": "DIRECT"

}
@Provide()
export class AchService extends BaseService {
  @Inject()
  utils: Utils;
  @Inject()
  httpService: HttpService;
  @Logger()
  logger: ILogger;

  validOrderParam(payload) {
    switch (payload.payType) {
      case "PIX": {
        if (_.isEmpty(payload.idendifyType)) {
          throw new Error('身份类型【idendifyType】不能为空');
        }
        if (_.isEmpty(payload.idendifyNumber)) {
          throw new Error('用户的真实CPF号码【idendifyNumber】不能为空');
        }
        if (_.isEmpty(payload.firstName)) {
          throw new Error('【firstName】不能为空');
        }
        if (_.isEmpty(payload.lastName)) {
          throw new Error('【lastName】不能为空');
        }
        break;
      }
      case "UPI": {
        if (_.isEmpty(payload.phone)) {
          throw new Error('用户手机号【phone】不能为空');
        }
        if (_.isEmpty(payload.email)) {
          throw new Error('用户邮箱【email】不能为空');
        }
        break;
      }
      case "QRIS": {
        if (_.isEmpty(payload.firstName)) {
          throw new Error('【firstName】不能为空');
        }
        if (_.isEmpty(payload.lastName)) {
          throw new Error('【lastName】不能为空');
        }
        break;
      }
    }
  }

  async order(payload, extra) {
    const param: any = {
      merchantNo: MCH_ID,
      timeStamp: +moment(),
      merchantOrderNo: payload.orderNo,
      payType: PAY_TYPE[payload.currency],
      payModel: PAY_MODEL[payload.payType],
      orderAmount: (+payload.amount * 100).toFixed(0),
      productDetail: "good",
      callbackUrl: NOTIFY_HOST,
    };
    if (extra.firstName) {
      param.firstName = extra.firstName;
    }
    if (extra.lastName) {
      param.lastName = extra.lastName;
    }
    if (extra.phone) {
      param.phone = extra.phone;
    }
    if (extra.email) {
      param.email = extra.email;
    }
    if (extra.payBankCode && payload.currency === 'VND' && payload.payType === 'BANK') {
      param.payBankCode = extra.payBankCode;
    }
    const signStr = this.utils.signSort(param);
    param.sign = this.sign(PRIVATE_KEY, signStr);
    if (extra.idendifyType) {
      param.idendifyType = extra.idendifyType;
    }
    if (extra.idendifyNumber) {
      param.idendifyNumber = extra.idendifyNumber;
    }
    if (extra.userIp) {
      param.userIp = extra.userIp;
    }
    param.language = "en";
    param.noticeUrl = payload.returnUrl;
    const res = await this.httpService.postForm(HOST + PAY_URL, param);
    this.logger.info('下单接口返回', param, JSON.stringify(res.data));
    const { meta = {}, data = {} } = res.data;
    const { success, code, message } = meta
    if (success && code === '0000') {
      return {
        payUrl: data.webUrl,
        traceNo: data?.orderNo
      };
    } else {
      throw new Error(message);
    }
  }

  sign(privateKey: string, text: string): string {
    const privateKeyPem = `-----BEGIN RSA PRIVATE KEY-----\n${privateKey.match(/.{1,64}/g).join('\n')}\n-----END RSA PRIVATE KEY-----\n`;
    const privateKeyObj = forge.pki.privateKeyFromPem(privateKeyPem);
    const md = forge.md.md5.create();
    md.update(text, 'utf8');
    const signature = privateKeyObj.sign(md);
    return forge.util.encode64(signature);
  }

  async query(payload) {
    const param: any = {
      merchantNo: MCH_ID,
      timeStamp: +moment(),
      merchantOrderNo: payload.orderNo,
    };
    const signStr = this.utils.signSort(param);
    param.sign = this.utils.signByMD5WithRSA(signStr, PRIVATE_KEY);
    const res = await this.httpService.postForm(HOST + QUERY_URL, param);
    this.logger.info('查询接口返回', param, JSON.stringify(res.data));
    const { meta = {}, data = {} } = res.data;
    const { success, code, message } = meta
    if (success && code === '0000') {
      if (data.orderStatus === 'SUCCESS') {
        return {
          status: 1,
          traceNo: data.orderNo,
          date: new Date()
        };
      } else {
        return {
          status: 0
        };
      }
    } else {
      throw new Error(message);
    }
  }

  async handleOrderNotify(payload, headers) {
    const { data = "" } = payload;
    const jsonData = JSON.parse(data);
    const signData = {
      merchantNo: jsonData.merchantNo,
      merchantOrderNo: jsonData.merchantOrderNo,
      orderNo: jsonData.orderNo,
      currency: jsonData.currency,
      orderAmount: jsonData.orderAmount,
      orderFee: jsonData.orderFee,
      payType: jsonData.payType,
      payModel: jsonData.payModel,
      orderStatus: jsonData.orderStatus,
    }
    const signStr = this.utils.signSort(signData);
    console.log(this.utils.decryptByMD5WithRSA(jsonData.sign, PRIVATE_KEY))
    const valid = this.utils.verifyByMD5WithRSA(signStr, jsonData.sign, PUBLIC_KEY);
    if (!valid) {
      throw new Error('sign error');
    }
    if (payload.orderStatus !== 'SUCCESS' && payload.orderStatus !== 'FAIL' && payload.orderStatus !== 'CANCEL') {
      throw new Error('order no result');
    }
    return {
      date: new Date(),
      orderNo: payload.merchantOrderNo,
      traceNo: payload.orderNo,
      status: payload.orderStatus === 'SUCCESS' ? 1 : 3,
    };
  }

  // async queryBalance() {
  //   const param = {};
  //   const timestamp = +moment();
  //   const nonce = uuidv4();
  //   const signStr = this.utils.signSort({
  //     timestamp,
  //     nonce,
  //     access_key: ACCESS_KEY,
  //     ...param
  //   });
  //   const sign = this.utils.signByHmacSha1(signStr, SECRET_KEY);
  //   const res = await this.httpService.get(HOST + BALANCE_URL, {
  //     headers: {
  //       'access_key': ACCESS_KEY,
  //       'timestamp': timestamp,
  //       'nonce': nonce,
  //       'sign': sign
  //     }
  //   });
  //   this.logger.info('查询余额接口返回', param, JSON.stringify(res.data));
  //   const { success, msg, data } = res.data;
  //   if (success && data[0]) {
  //     return {
  //       balance: data[0].accountBalance,
  //       freeze: data[0].accountFreezeAmount
  //     }
  //   } else {
  //     throw new Error(msg);
  //   }
  // }

  // async queryBanks(payload) {
  //   const param = {
  //     currencyType: 'BRL',
  //   };
  //   const timestamp = +moment();
  //   const nonce = uuidv4();
  //   const signStr = this.utils.signSort({
  //     timestamp,
  //     nonce,
  //     access_key: ACCESS_KEY,
  //     ...param
  //   });
  //   const sign = this.utils.signByHmacSha1(signStr, SECRET_KEY);
  //   const res = await this.httpService.post(HOST + BANK_URL, param, {
  //     headers: {
  //       'access_key': ACCESS_KEY,
  //       'timestamp': timestamp,
  //       'nonce': nonce,
  //       'sign': sign
  //     }
  //   });
  //   this.logger.info('查询银行接口返回', param, JSON.stringify(res.data));
  //   const { success, msg, data } = res.data;
  //   if (success) {
  //     return data.map(item => {
  //       return {
  //         bankName: item.bankNames,
  //         bankCode: ''
  //       }
  //     })
  //   } else {
  //     throw new Error(msg);
  //   }
  // }

  // async withdraw(payload) {
  //   const param = {
  //     currencyAmount: (+payload.amount).toFixed(2),
  //     channelType: CHANNEL_TYPE,
  //     externalOrderId: payload.orderNo,
  //     personIdType: payload.personIdType,
  //     personId: payload.personId,
  //     personName: payload.personName,
  //     accountType: payload.bankCode,
  //     accountId: payload.accountNo,
  //     notifyUrl: WITHDRAW_NOTIFY_HOST
  //   };
  //   const timestamp = +moment();
  //   const nonce = uuidv4();
  //   const signStr = this.utils.signSort({
  //     timestamp,
  //     nonce,
  //     access_key: ACCESS_KEY,
  //     ...param
  //   });
  //   const sign = this.utils.signByHmacSha1(signStr, SECRET_KEY);
  //   const res = await this.httpService.post(HOST + WITHDRAW_URL, param, {
  //     headers: {
  //       'access_key': ACCESS_KEY,
  //       'timestamp': timestamp,
  //       'nonce': nonce,
  //       'sign': sign
  //     }
  //   });
  //   this.logger.info('代付接口返回', param, JSON.stringify(res.data));
  //   const { success, msg, desc, data } = res.data;
  //   if (success && data.orderId) {
  //     return {
  //       status: 2,
  //       traceNo: data.orderId
  //     };
  //   } else {
  //     return {
  //       status: 3,
  //       message: desc || msg
  //     }
  //   }
  // }

  // async handleWithdrawNotify(payload, headers) {
  //   const sign = headers['sign'];
  //   const timestamp = headers['timestamp'];
  //   const nonce = headers['nonce'];
  //   const signStr = this.utils.signSort({
  //     timestamp,
  //     nonce,
  //     access_key: ACCESS_KEY,
  //     ...payload
  //   });
  //   const validSign = this.utils.signByHmacSha1(signStr, SECRET_KEY);
  //   if (sign !== validSign) {
  //     throw new Error('sign error');
  //   }
  //   if (+payload.orderStatusCode !== 8 && +payload.orderStatusCode !== 4 && +payload.orderStatusCode !== 16) {
  //     throw new Error('order no result');
  //   }
  //   let status = 2;
  //   if (+payload.orderStatusCode === 8) {
  //     status = 8;
  //   } else if (+payload.orderStatusCode === 4 || +payload.orderStatusCode === 16) {
  //     status = 3;
  //   }
  //   return {
  //     date: new Date(),
  //     status: status,
  //     message: payload.errorMsg,
  //     orderNo: payload.externalOrderId
  //   };
  // }

  // async queryWithdraw(payload) {
  //   const param = {
  //     externalOrderId: payload.orderNo
  //   };
  //   const timestamp = +moment();
  //   const nonce = uuidv4();
  //   const signStr = this.utils.signSort({
  //     timestamp,
  //     nonce,
  //     access_key: ACCESS_KEY,
  //     ...param
  //   });
  //   const sign = this.utils.signByHmacSha1(signStr, SECRET_KEY);
  //   const res = await this.httpService.post(HOST + QUERY_WITHDRAW_URL, param, {
  //     headers: {
  //       'access_key': ACCESS_KEY,
  //       'timestamp': timestamp,
  //       'nonce': nonce,
  //       'sign': sign
  //     }
  //   });
  //   this.logger.info('查询代付接口返回', JSON.stringify(res.data));
  //   const { success, msg, data = [] } = res.data;
  //   const orderData = data.find(item => item.externalOrderId === payload.orderNo)
  //   if (success && orderData) {
  //     if (+orderData.orderStatus === 4 || +orderData.orderStatus === 16) {
  //       return {
  //         date: new Date(),
  //         status: 3,
  //         message: orderData.errorMsg,
  //         orderNo: orderData.externalOrderId
  //       };
  //     } else if (+orderData.orderStatus === 8) {
  //       return {
  //         date: new Date(),
  //         status: 8,
  //         message: orderData.errorMsg,
  //         orderNo: orderData.externalOrderId
  //       };
  //     }
  //     return {
  //       status: 1,
  //       traceNo: orderData.orderId,
  //       date: new Date()
  //     };
  //   } else {
  //     return {
  //       status: 3,
  //       message: '渠道订单不存在'
  //     };
  //   }
  // }
}
