/*
 *      Copyright (c) 2018-2028, Chill Zhuang All rights reserved.
 *
 *  Redistribution and use in source and binary forms, with or without
 *  modification, are permitted provided that the following conditions are met:
 *
 *  Redistributions of source code must retain the above copyright notice,
 *  this list of conditions and the following disclaimer.
 *  Redistributions in binary form must reproduce the above copyright
 *  notice, this list of conditions and the following disclaimer in the
 *  documentation and/or other materials provided with the distribution.
 *  Neither the name of the dreamlu.net developer nor the names of its
 *  contributors may be used to endorse or promote products derived from
 *  this software without specific prior written permission.
 *  Author: Chill 庄骞 (smallchill@163.com)
 */
package org.springblade.modules.guosen.bussiness.service.impl;

import cn.hutool.core.lang.Assert;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import org.springblade.common.constant.SystemConstant;
import org.springblade.core.tool.api.R;
import org.springblade.modules.guosen.bussiness.dto.BussinessBonusRecordsDTO;
import org.springblade.modules.guosen.bussiness.entity.BussinessBonusAccount;
import org.springblade.modules.guosen.bussiness.entity.BussinessBonusRecords;
import org.springblade.modules.guosen.bussiness.service.IBussinessBonusAccountService;
import org.springblade.modules.guosen.bussiness.vo.BussinessBonusRecordsVO;
import org.springblade.modules.guosen.bussiness.mapper.BussinessBonusRecordsMapper;
import org.springblade.modules.guosen.bussiness.service.IBussinessBonusRecordsService;
import org.springblade.core.mp.base.BaseServiceImpl;
import org.springblade.modules.guosen.bussinessTransferOrder.entity.BussinessTransferOrder;
import org.springblade.modules.guosen.bussinessTransferOrder.service.IBussinessTransferOrderService;
import org.springblade.modules.guosen.bussinessuserinfo.entity.BussinessUserInfo;
import org.springblade.modules.guosen.bussinessuserinfo.service.IBussinessUserInfoService;
import org.springblade.modules.guosen.bussinessuserwithdraw.entity.BussinessUserWithdraw;
import org.springblade.modules.guosen.bussinessuserwithdraw.service.IBussinessUserWithdrawService;
import org.springblade.modules.system.service.IParamService;
import org.springblade.yeePay.service.BussinessPayService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.baomidou.mybatisplus.core.metadata.IPage;

import java.math.BigDecimal;
import java.text.DecimalFormat;
import java.util.Timer;
import java.util.TimerTask;
import java.util.UUID;

/**
 *  服务实现类
 *
 * @author BladeX
 * @since 2021-07-22
 */
@Service
public class BussinessBonusRecordsServiceImpl extends BaseServiceImpl<BussinessBonusRecordsMapper, BussinessBonusRecords> implements IBussinessBonusRecordsService {

	@Autowired
	private IParamService paramService;
	@Autowired
	private IBussinessUserInfoService userInfoService;
	@Autowired
	private IBussinessUserWithdrawService withdrawService;
	@Autowired
	private IBussinessTransferOrderService transferOrderService;
	@Autowired
	private IBussinessBonusAccountService accountService;
	@Autowired
	private BussinessPayService bussinessPayService;

	@Override
	public IPage<BussinessBonusRecordsVO> selectBussinessBonusRecordsPage(IPage<BussinessBonusRecordsVO> page, BussinessBonusRecordsVO bussinessBonusRecords) {
		return page.setRecords(baseMapper.selectBussinessBonusRecordsPage(page, bussinessBonusRecords));
	}

	@Override
	public R payForBonus(BussinessBonusRecordsDTO recordsDTO) {
		return null;
	}

	@Override
	public R withdrawForBonus(BussinessBonusRecordsDTO recordsDTO) {
		BussinessBonusRecords record = this.getById(recordsDTO.getId());
		//分佣
		Assert.isFalse(record.getBonusStatus() == SystemConstant.BussinessBonusStatus.SUCCESS.getValue()
										|| record.getBonusStatus() == SystemConstant.BussinessBonusStatus.BONUSING.getValue(),
						"不能重复分配");
		BigDecimal price = recordsDTO.getPrice();
		if(record.getPrice().compareTo(price) == -1){
			R.fail("分润金额不能高于可分润金额");
		}
		String withdrawRate = paramService.getValue("yee_withdraw_rate");
		String transferRate = paramService.getValue("yee_transfer_rate");
		DecimalFormat decimalFormat = new DecimalFormat("0.00");
		BigDecimal transferFee = new BigDecimal(decimalFormat.format(Double.parseDouble(transferRate)));
		BigDecimal withdrawFee = new BigDecimal(decimalFormat.format(Double.parseDouble(withdrawRate)));
		BigDecimal transferAmount = record.getPrice().add(transferFee).add(withdrawFee);
		if(record.getPrice().compareTo(transferAmount) == -1){
			return R.fail("可分润金额不足以抵扣手续费");
		}
		Long userInfoId = record.getUserInfoId();
		BussinessUserInfo userInfo = this.userInfoService.getById(userInfoId);
		if(!userInfo.isRegisterSuccess()){
			return R.fail("该用户未完成进件");
		}
		BussinessBonusAccount account = this.accountService.getById(record.getBonusAccountId());
		//1、创建转账单
		BussinessTransferOrder transferOrder = new BussinessTransferOrder();
		transferOrder.setTransferStatus(SystemConstant.TransferOrderStatus.WAIT.getValue());
		transferOrder.setTransferScene(SystemConstant.TransferScene.FOR_BONUS_TRANSFER.getValue());
		transferOrder.setFeeChargeSide("feeChargeSide");
		transferOrder.setOrderAmount(transferAmount.toString());
		transferOrder.setTransferUsage("采购");
		transferOrder.setFromMerchantNo(userInfo.getParentMerchantNo());
		transferOrder.setToMerchantNo(userInfo.getMerchantNo());
		transferOrder.setRequestNo(UUID.randomUUID().toString().replaceAll("-", "").toUpperCase());
		boolean transferSave = this.transferOrderService.save(transferOrder);
		if(transferSave){
			//2、创建提现单
			BussinessUserWithdraw withdraw = new BussinessUserWithdraw();
			withdraw.setWithdrawStatus(SystemConstant.WithdrawOrderStatus.WAIT.getValue());
			withdraw.setBussinessId(userInfo.getBussinessId());
			withdraw.setBankCode(account.getReceiverBankCode());
			withdraw.setBankAccountNo(account.getReceiverAccountNo());
			withdraw.setReceiveType("REAL_TIME");
			withdraw.setReceiverAccountName(account.getReceiverAccountName());
			withdraw.setMerchantNo(userInfo.getMerchantNo());
			withdraw.setUserInfoId(userInfoId);
			withdraw.setOrderAmount(record.getPrice());
			withdraw.setRequestNo(UUID.randomUUID().toString().replaceAll("-", "").toUpperCase());
			withdraw.setSecondTransferOrderId(transferOrder.getId());
			withdraw.setBussinessId(userInfo.getBussinessId());
			this.withdrawService.save(withdraw);
			R secondTransferResult = this.transferOrderService.transferOrder(transferOrder, userInfo.getParentMerchantNo());
			if(secondTransferResult.isSuccess()){
				if(secondTransferResult.getMsg().equals("REQUEST_RECEIVE")){
					this.bussinessPayService.handleSecondTransferScene(transferOrder.getId());
					return R.status(true);
				}else if(secondTransferResult.getMsg().equals("SUCCESS")){
					R withdrawResult = this.bussinessPayService.withdrawOrder(withdraw, userInfo.getParentMerchantNo());
					record.setFailReason(withdrawResult.getMsg());
					record.setThirdPayLog(withdraw.getThirdLog());
					if(withdrawResult.isSuccess()){
						record.setThirdOrderNo(withdraw.getThirdOrderNo());
						record.setBonusStatus(SystemConstant.BussinessBonusStatus.BONUSING.getValue());
					}else{
						record.setBonusStatus(SystemConstant.BussinessBonusStatus.FAIL.getValue());
					}
					this.withdrawService.updateById(withdraw);
					return R.status(true);
				}else{
					return R.status(true);
				}
			}else{
				withdraw.setFailReason("分润失败");
				withdraw.setReturnMsg(secondTransferResult.getMsg());
				withdraw.setWithdrawStatus(SystemConstant.WithdrawOrderStatus.FAIL.getValue());
				this.withdrawService.updateById(withdraw);
				record.setBonusStatus(SystemConstant.BussinessBonusStatus.FAIL.getValue());
				return R.fail("分润失败");
			}
		}else{
			return R.fail("保存数据失败");
		}
	}

	@Override
	public BussinessBonusRecords getByTransferOrderId(Long transferOrderId) {
		LambdaQueryWrapper<BussinessBonusRecords> lambda = new LambdaQueryWrapper<>();
		lambda.eq(BussinessBonusRecords::getTransferOrderId, transferOrderId);
		return baseMapper.selectOne(lambda);
	}

}
