/*
 *      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.bussinessTransferOrder.service.impl;

import cn.hutool.json.JSON;
import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import org.springblade.common.constant.SystemConstant;
import org.springblade.core.tool.api.R;
import org.springblade.core.tool.utils.StringUtil;
import org.springblade.modules.guosen.bussinessInfo.entity.BussinessInfo;
import org.springblade.modules.guosen.bussinessInfo.service.IBussinessInfoService;
import org.springblade.modules.guosen.bussinessTransferOrder.entity.BussinessTransferOrder;
import org.springblade.modules.guosen.bussinessTransferOrder.vo.BussinessTransferOrderVO;
import org.springblade.modules.guosen.bussinessTransferOrder.mapper.BussinessTransferOrderMapper;
import org.springblade.modules.guosen.bussinessTransferOrder.service.IBussinessTransferOrderService;
import org.springblade.core.mp.base.BaseServiceImpl;
import org.springblade.yeePay.entity.TransferOrderDto;
import org.springblade.yeePay.entity.TransferQueryDto;
import org.springblade.yeePay.service.YeePayService;
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.util.UUID;

/**
 *  服务实现类
 *
 * @author BladeX
 * @since 2021-09-27
 */
@Service
public class BussinessTransferOrderServiceImpl extends BaseServiceImpl<BussinessTransferOrderMapper, BussinessTransferOrder> implements IBussinessTransferOrderService {

	@Autowired
	private YeePayService yeePayService;
	@Autowired
	private IBussinessInfoService bussinessInfoService;

	@Override
	public IPage<BussinessTransferOrderVO> selectBussinessTransferOrderPage(IPage<BussinessTransferOrderVO> page, BussinessTransferOrderVO bussinessTransferOrder) {
		return page.setRecords(baseMapper.selectBussinessTransferOrderPage(page, bussinessTransferOrder));
	}

	@Override
	public R transferOrder(BussinessTransferOrder bussinessTransferOrder, String parentMerchantNo) {
		TransferOrderDto transferOrderDto = TransferOrderDto.builder()
				.usage(StringUtil.isBlank(bussinessTransferOrder.getTransferUsage()) ? "采购" : bussinessTransferOrder.getTransferUsage())
				.fromMerchantNo(bussinessTransferOrder.getFromMerchantNo())
				.toMerchantNo(bussinessTransferOrder.getToMerchantNo())
				.requestNo(bussinessTransferOrder.getRequestNo())
				.orderAmount(bussinessTransferOrder.getOrderAmount())
				.feeChargeSide(bussinessTransferOrder.getFeeChargeSide())
				.build();
		R transferResult = yeePayService.transferOrder(transferOrderDto, parentMerchantNo);
		JSONObject data = JSONUtil.parseObj(transferResult.getData());
		String requestNo = data.getStr("requestNo");
		String fromMerchantNo = data.getStr("fromMerchantNo");
		BussinessTransferOrder dbTransferOrder = this.getByRequestNo(requestNo, fromMerchantNo);
		if(dbTransferOrder == null){
			log.error("=================充值服务费转账请求响应，转账订单不存在====================");
			log.error("转账请求号：" + requestNo + ", 转出商户号：" + fromMerchantNo);
			return R.fail("TF订单查询失败");
		}
		String returnCode = data.getStr("returnCode");
		String transferStatus = data.getStr("transferStatus");
		if(returnCode.equals("UA00000")){ //转账成功
			dbTransferOrder.setFee(data.getStr("fee"));
			dbTransferOrder.setOrderNo(data.getStr("orderNo"));
			dbTransferOrder.setFinishTime(data.getStr("finishTime"));
			dbTransferOrder.setDebitAmount(data.getStr("debitAmount"));
			dbTransferOrder.setFeeMerchantNo(data.getStr("feeMerchantNo"));
			dbTransferOrder.setReceiveAmount(data.getStr("receiveAmount"));
			dbTransferOrder.setThirdLog(JSONUtil.toJsonStr(data));
			if("REQUEST_RECEIVE".equals(transferStatus)){
				dbTransferOrder.setTransferStatus(SystemConstant.TransferOrderStatus.REQUEST_RECEIVE.getValue());
				this.updateById(dbTransferOrder);
				return R.success("REQUEST_RECEIVE");
			}else if("SUCCESS".equals(transferStatus)){
				dbTransferOrder.setTransferStatus(SystemConstant.TransferOrderStatus.SUCCESS.getValue());
				this.updateById(dbTransferOrder);
				return R.success("SUCCESS");
			}else if("FAIL".equals(transferStatus)){
				dbTransferOrder.setTransferStatus(SystemConstant.TransferOrderStatus.FAIL.getValue());
				this.updateById(dbTransferOrder);
				return R.fail(data.getStr("returnMsg"));
			}
			return R.status(true);
		}else{
			log.error("=================充值服务费转账请求响应转账下单失败====================");
			log.error("转账请求号：" + requestNo + ", 转出商户号：" + fromMerchantNo + ", 失败原因：" + data.getStr("returnMsg"));
			dbTransferOrder.setReturnMsg(data.getStr("returnMsg"));
			dbTransferOrder.setTransferStatus(SystemConstant.TransferOrderStatus.FAIL.getValue());
			dbTransferOrder.setThirdLog(JSONUtil.toJsonStr(data));
			this.updateById(dbTransferOrder);
			return R.fail(data.getStr("returnMsg"));
		}
	}

	//调试专用
	@Override
	public R transferOrderDebug(BussinessTransferOrder bussinessTransferOrder, String parentMerchantNo) {
		TransferOrderDto transferOrderDto = TransferOrderDto.builder()
				.usage(StringUtil.isBlank(bussinessTransferOrder.getTransferUsage()) ? "采购" : bussinessTransferOrder.getTransferUsage())
				.fromMerchantNo(bussinessTransferOrder.getFromMerchantNo())
				.toMerchantNo(bussinessTransferOrder.getToMerchantNo())
				.requestNo(bussinessTransferOrder.getRequestNo())
				.orderAmount(bussinessTransferOrder.getOrderAmount())
				.feeChargeSide(bussinessTransferOrder.getFeeChargeSide())
				.build();
		R transferResult = yeePayService.transferOrder(transferOrderDto, parentMerchantNo);
		JSONObject data = JSONUtil.parseObj(transferResult.getData());
		String requestNo = data.getStr("requestNo");
		String fromMerchantNo = data.getStr("fromMerchantNo");
		BussinessTransferOrder dbTransferOrder = this.getByRequestNo(requestNo, fromMerchantNo);
		if(dbTransferOrder == null){
			log.error("=================充值服务费转账请求响应，转账订单不存在====================");
			log.error("转账请求号：" + requestNo + ", 转出商户号：" + fromMerchantNo);
			return R.fail("TF订单查询失败");
		}
		String returnCode = data.getStr("returnCode");
		String transferStatus = data.getStr("transferStatus");
		dbTransferOrder.setThirdLog(JSONUtil.toJsonStr(data));
		if(returnCode.equals("UA00000")){ //转账成功
			dbTransferOrder.setFee(data.getStr("fee"));
			dbTransferOrder.setOrderNo(data.getStr("orderNo"));
			dbTransferOrder.setFinishTime(data.getStr("finishTime"));
			dbTransferOrder.setDebitAmount(data.getStr("debitAmount"));
			dbTransferOrder.setFeeMerchantNo(data.getStr("feeMerchantNo"));
			dbTransferOrder.setReceiveAmount(data.getStr("receiveAmount"));
			if("REQUEST_RECEIVE".equals(transferStatus)){
				dbTransferOrder.setTransferStatus(SystemConstant.TransferOrderStatus.REQUEST_RECEIVE.getValue());
				this.updateById(dbTransferOrder);
				return R.status(true);
			}else if("SUCCESS".equals(transferStatus)){
				return R.status(true);
			}else if("FAIL".equals(transferStatus)){
				dbTransferOrder.setTransferStatus(SystemConstant.TransferOrderStatus.FAIL.getValue());
				this.updateById(dbTransferOrder);
				return R.fail(data.getStr("returnMsg"));
			}
			return R.status(true);
		}else{
			log.error("=================充值服务费转账请求响应转账下单失败====================");
			log.error("转账请求号：" + requestNo + ", 转出商户号：" + fromMerchantNo + ", 失败原因：" + data.getStr("returnMsg"));
			dbTransferOrder.setReturnMsg(data.getStr("returnMsg"));
			dbTransferOrder.setTransferStatus(SystemConstant.TransferOrderStatus.FAIL.getValue());
			this.updateById(dbTransferOrder);
			return R.fail(data.getStr("returnMsg"));
		}
	}

	@Override
	public BussinessTransferOrder getByRequestNo(String requestNo, String fromMerchantNo) {
		LambdaQueryWrapper<BussinessTransferOrder> lambdaQueryWrapper = new LambdaQueryWrapper<>();
		lambdaQueryWrapper.eq(BussinessTransferOrder::getRequestNo, requestNo);
		lambdaQueryWrapper.eq(BussinessTransferOrder::getFromMerchantNo, fromMerchantNo);
		return baseMapper.selectOne(lambdaQueryWrapper);
	}

	@Override
	public R<BussinessTransferOrder> transferOrder(BigDecimal transferAmount, String fromMerchantNo, String toMerchantNo, String usage, String feeChargeSide, Integer transferScene, String parentMerchantNo) {
		String requestNo = UUID.randomUUID().toString().replaceAll("-", "").toUpperCase();
		BussinessTransferOrder transferOrder = new BussinessTransferOrder();
		transferOrder.setOrderAmount(transferAmount.toString());
		transferOrder.setRequestNo(requestNo);
		transferOrder.setFromMerchantNo(fromMerchantNo);
		transferOrder.setToMerchantNo(toMerchantNo);
		transferOrder.setTransferUsage(StringUtil.isBlank(usage) ? "采购" : usage);
		transferOrder.setFeeChargeSide(feeChargeSide);
		transferOrder.setTransferScene(transferScene);
		transferOrder.setTransferStatus(SystemConstant.TransferOrderStatus.WAIT.getValue());
		//保存转账订单
		if(this.save(transferOrder)){
			TransferOrderDto transferOrderDto = TransferOrderDto.builder()
					.usage(StringUtil.isBlank(usage) ? "采购" : usage)
					.fromMerchantNo(fromMerchantNo)
					.toMerchantNo(toMerchantNo)
					.requestNo(requestNo)
					.orderAmount(transferAmount.toString())
					.feeChargeSide(feeChargeSide)
					.build();
			R transferResult = yeePayService.transferOrder(transferOrderDto, parentMerchantNo);
			JSONObject data = JSONUtil.parseObj(transferResult.getData());
			BussinessTransferOrder dbTransferOrder = this.getByRequestNo(data.getStr("requestNo"), data.getStr("fromMerchantNo"));
			if(dbTransferOrder == null){
				log.error("=================转账请求响应，转账订单不存在====================");
				log.error("转账请求号：" + data.getStr("requestNo") + ", 转出商户号：" + data.getStr("fromMerchantNo"));
				return R.fail("TF订单查询失败");
			}
			String returnCode = data.getStr("returnCode");
			String transferStatus = data.getStr("transferStatus");
			dbTransferOrder.setThirdLog(JSONUtil.toJsonStr(data));
			if(returnCode.equals("UA00000")){ //转账成功
				dbTransferOrder.setFee(data.getStr("fee"));
				dbTransferOrder.setOrderNo(data.getStr("orderNo"));
				dbTransferOrder.setFinishTime(data.getStr("finishTime"));
				dbTransferOrder.setDebitAmount(data.getStr("debitAmount"));
				dbTransferOrder.setFeeMerchantNo(data.getStr("feeMerchantNo"));
				dbTransferOrder.setReceiveAmount(data.getStr("receiveAmount"));
				if("REQUEST_RECEIVE".equals(transferStatus)){
					dbTransferOrder.setTransferStatus(SystemConstant.TransferOrderStatus.REQUEST_RECEIVE.getValue());
					this.updateById(dbTransferOrder);
					return R.data(dbTransferOrder);
				}else if("SUCCESS".equals(transferStatus)){
					return R.data(dbTransferOrder);
				}else if("FAIL".equals(transferStatus)){
					dbTransferOrder.setTransferStatus(SystemConstant.TransferOrderStatus.FAIL.getValue());
					this.updateById(dbTransferOrder);
					return R.fail(data.getStr("returnMsg"));
				}
				return R.data(dbTransferOrder);
			}else{
				log.error("=================转账请求响应转账下单失败====================");
				log.error("转账请求号：" + requestNo + ", 转出商户号：" + fromMerchantNo + ", 失败原因：" + data.getStr("returnMsg"));
				dbTransferOrder.setReturnMsg(data.getStr("returnMsg"));
				dbTransferOrder.setTransferStatus(SystemConstant.TransferOrderStatus.FAIL.getValue());
				this.updateById(dbTransferOrder);
				return R.fail(data.getStr("returnMsg"));
			}
		}else{
			return R.fail("TF业务订单保存失败");
		}

	}

	@Override
	public R transferQuery(Long transferOrderId) {
		LambdaQueryWrapper<BussinessTransferOrder> lambda = new LambdaQueryWrapper<>();
		lambda.eq(BussinessTransferOrder::getId, transferOrderId);
		BussinessTransferOrder transferOrder = this.baseMapper.selectOne(lambda);
		TransferQueryDto queryDto = TransferQueryDto.builder()
						.orderNo(transferOrder.getOrderNo())
						.requestNo(transferOrder.getRequestNo())
						.build();
		BussinessInfo bussinessInfo = this.bussinessInfoService.getByMerchantNo(transferOrder.getFromMerchantNo());
		R result = this.yeePayService.transferQuery(queryDto, bussinessInfo.getParentMerchantNo());
		JSONObject data = JSONUtil.parseObj(result.getData());
		String returnCode = data.getStr("returnCode");
		String transferStatus = data.getStr("transferStatus");
		String returnMsg = data.getStr("returnMsg");
		if(returnCode.equals("UA00000")){
			if("REQUEST_RECEIVE".equals(transferStatus)){
				transferOrder.setTransferStatus(SystemConstant.TransferOrderStatus.REQUEST_RECEIVE.getValue());
				this.updateById(transferOrder);
				return R.data("REQUEST_RECEIVE");
			}else if("SUCCESS".equals(transferStatus)){
				transferOrder.setTransferStatus(SystemConstant.TransferOrderStatus.SUCCESS.getValue());
				this.updateById(transferOrder);
				return R.data("SUCCESS");
			}else if("FAIL".equals(transferStatus)){
				transferOrder.setTransferStatus(SystemConstant.TransferOrderStatus.FAIL.getValue());
				transferOrder.setReturnMsg(returnMsg);
				this.updateById(transferOrder);
				return R.fail("FAIL");
			}
			return R.success(transferStatus);
		}else{
			return R.fail(data.getStr("returnMsg"));
		}
	}

}
