import { Inject, Logger, Provide } from '@midwayjs/decorator';
import { BaseService, CoolCommException } from '@cool-midway/core';
import { InjectEntityModel } from '@midwayjs/typeorm';
import { Repository } from 'typeorm';
import * as _ from 'lodash';
import { KycEntity } from '../entity/kyc';
import { SunPayService } from './channels/sunpay';
import { ILogger } from '@midwayjs/logger';
import { PayService } from './pay';
import * as moment from 'moment';
import * as md5 from 'md5';

@Provide()
export class KycOpenService extends BaseService {
  @InjectEntityModel(KycEntity)
  kycEntity: Repository<KycEntity>;

  @Inject()
  sunPayService: SunPayService

  @Inject()
  payService: PayService

  @Logger()
  logger: ILogger;

  async validGetCustomer(payload) {
    if (_.isEmpty(payload.mchId)) {
      throw new Error('商户编号【mchId】不能为空');
    }
    if (_.isEmpty(payload.userId)) {
      throw new Error('商户平台用户ID【userId】不能为空');
    }
  }

  async getCustomer(payload) {
    try {
      this.logger.info('获取客户信息', JSON.stringify(payload));
      await this.validGetCustomer(payload);
      const merchant = await this.payService.validMerchant(payload.mchId);
      await this.payService.validSign(payload, merchant);
      let kyc = await this.kycEntity.findOneBy({
        mchId: payload.mchId,
        userId: payload.userId,
        code: 'SUN_CARD',
      })
      if (kyc && kyc.customerId) {
        return {
          mchId: kyc.mchId,
          userId: kyc.mchId,
          kycUserId: kyc.userId,
          country: kyc.country,
          level: kyc.level,
          email: kyc.email
        }
      }
      const outUserId = md5(payload.mchId + '_' + payload.userId + 'v2');
      const data = await this.sunPayService.queryKyc(outUserId);
      const newKyc = {
        userId: payload.userId,
        mchId: payload.mchId,
        code: 'SUN_CARD',
        kycUserId: data.kycUserId,
        customerId: data.customerId,
        level: '1',
        country: data.countryCode,
        email: data.customerEmail
      }
      await this.kycEntity.insert(kyc)
      return {
        mchId: newKyc.mchId,
        userId: newKyc.mchId,
        kycUserId: newKyc.userId,
        country: newKyc.country,
        email: newKyc.email,
        level: newKyc.level
      }
    } catch (err) {
      this.logger.error('获取客户信息', JSON.stringify(payload), err.message);
      throw new CoolCommException(err.message);
    }
  }

  async validPremiumParam(payload, files) {
    if (_.isEmpty(payload.mchId)) {
      throw new Error('商户编号【mchId】不能为空');
    }
    if (_.isEmpty(payload.kycUserId)) {
      throw new Error('KYC用户ID【kycUserId】不能为空');
    }
    if (!files.residentialAddress) {
      throw new Error('居住地址证明文件【residentialAddress】不能为空');
    }
    if (!files.income) {
      throw new Error('收入证明文件【income】不能为空');
    }
    if (_.isEmpty(payload.sign)) {
      throw new Error('签名【sign】不能为空');
    }
  }

  async createOpenPremium(payload, files) {
    try {
      this.logger.info('KYC高级认证', JSON.stringify(payload));
      if (!files) {
        throw new Error('参数错误，请提交正确参数');
      }
      const fileObj = {};
      files.forEach(item => {
        fileObj[item.fieldName] = item
      })
      await this.validPremiumParam(payload, fileObj);
      const merchant = await this.payService.validMerchant(payload.mchId);
      await this.payService.validSign(payload, merchant);
      const kyc = await this.kycEntity.findOneBy({ kycUserId: payload.kycUserId });
      if (!kyc || !kyc.customerId) {
        throw new CoolCommException('KYC用户不存在');
      }
      const data = await this.sunPayService.createPremium({
        customerId: kyc.customerId,
      }, fileObj);
      await this.kycEntity.update(kyc.id, { level: '3' });
      return { kycUserId: payload.kycUserId }
    } catch (err) {
      this.logger.error('KYC高级认证提交失败', JSON.stringify(payload), err.message);
      throw new CoolCommException(err.message);
    }
  }

  async validAdvanced(payload, files) {
    if (_.isEmpty(payload.mchId)) {
      throw new Error('商户编号【mchId】不能为空');
    }
    if (_.isEmpty(payload.kycUserId)) {
      throw new Error('KYC用户ID【kycUserId】不能为空');
    }
    if (_.isEmpty(payload.documentType)) {
      throw new Error('证件类型【documentType】不能为空');
    }
    if (+payload.documentType < 0 || +payload.documentType > 2) {
      throw new Error('证件类型【documentType】取值错误');
    }
    if (_.isEmpty(payload.documentNumber)) {
      throw new Error('证件号码【documentNumber】不能为空');
    }
    if (!files.frontSideDocument) {
      throw new Error('证件正面图片【frontSideDocument】不能为空');
    }
    if (!files.backSideDocument) {
      throw new Error('证件背面图片【backSideDocument】不能为空');
    }
    if (!files.customerPhoto) {
      throw new Error('客户人像图片【customerPhoto】不能为空');
    }
    if (_.isEmpty(payload.sign)) {
      throw new Error('签名【sign】不能为空');
    }
  }

  async createOpenAdvanced(payload, files) {
    try {
      this.logger.info('KYC进阶认证', JSON.stringify(payload));
      if (!files) {
        throw new Error('参数错误，请提交正确参数');
      }
      const fileObj = {};
      files.forEach(item => {
        fileObj[item.fieldName] = item
      })
      await this.validAdvanced(payload, fileObj);
      const merchant = await this.payService.validMerchant(payload.mchId);
      await this.payService.validSign(payload, merchant);

      const kyc = await this.kycEntity.findOneBy({ kycUserId: payload.kycUserId });
      if (!kyc || !kyc.customerId) {
        throw new CoolCommException('KYC用户不存在');
      }
      const data = await this.sunPayService.createAdvanced({
        customerId: kyc.customerId,
        documentType: payload.documentType,
        documentNumber: payload.documentNumber
      }, fileObj);
      await this.kycEntity.update(kyc.id, { level: '2' });
      return { kycUserId: payload.kycUserId }
    } catch (err) {
      this.logger.error('KYC进阶认证提交失败', JSON.stringify(payload), err.message);
      throw new CoolCommException(err.message);
    }
  }

  async validBasicParam(payload) {
    if (_.isEmpty(payload.mchId)) {
      throw new Error('商户编号【mchId】不能为空');
    }
    if (_.isEmpty(payload.userId)) {
      throw new Error('商户平台用户ID【userId】不能为空');
    }
    if (_.isEmpty(payload.customerName)) {
      throw new Error('客户姓名【customerName】不能为空');
    }
    if (_.isEmpty(payload.customerEmail)) {
      throw new Error('客户邮箱地址【customerEmail】不能为空');
    }
    if (_.isEmpty(payload.countryCode)) {
      throw new Error('国家编码【countryCode】不能为空');
    }
    if (_.isEmpty(payload.residenceCountry)) {
      throw new Error('国家编码【residenceCountry】不能为空');
    }
    if (_.isEmpty(payload.birthDate)) {
      throw new Error('出生日期【birthDate】不能为空');
    }
    if (!moment(payload.birthDate).isValid()) {
      throw new Error('出生日期【birthDate】非正确日期格式');
    }
    if (_.isEmpty(payload.sign)) {
      throw new Error('签名【sign】不能为空');
    }
  }

  async createOpenBasic(payload) {
    try {
      this.logger.info('KYC基础认证', JSON.stringify(payload));
      await this.validBasicParam(payload);
      const merchant = await this.payService.validMerchant(payload.mchId);
      await this.payService.validSign(payload, merchant);
      const kyc = await this.kycEntity.findOneBy({
        mchId: payload.mchId,
        userId: payload.userId,
        code: 'SUN_CARD',
      })
      if (kyc) {
        throw new Error('当前客户ID已存在，请勿重复提交');
      }
      const emailKyc = await this.kycEntity.findOneBy({ email: payload.customerEmail });
      if (emailKyc) {
        throw new CoolCommException('邮箱已被使用');
      }
      const outUserId = md5(payload.mchId + '_' + payload.userId + 'v2');
      const { customerId } = await this.sunPayService.createBasic({
        outUserId,
        customerName: payload.customerName,
        customerEmail: payload.customerEmail,
        countryCode: payload.countryCode,
        residenceCountry: payload.residenceCountry,
        birthDate: payload.birthDate,
      });
      if (customerId) {
        await this.kycEntity.insert({
          userId: payload.userId,
          mchId: payload.mchId,
          code: 'SUN_CARD',
          kycUserId: outUserId,
          customerId: customerId,
          email: payload.customerEmail,
          level: '1',
          country: payload.countryCode
        })
        return { kycUserId: outUserId }
      } else {
        throw new CoolCommException('Network exception, please try again later');
      }

    } catch (err) {
      this.logger.error('KYC基础认证提交失败', JSON.stringify(payload), err.message);
      throw new CoolCommException(err.message);
    }
  }
}
