package org.springblade.modules.api.service.impl;

import cn.hutool.core.util.NumberUtil;
import com.alibaba.fastjson.JSONObject;
import com.alipay.api.AlipayApiException;
import com.alipay.api.AlipayClient;
import com.alipay.api.AlipayConfig;
import com.alipay.api.DefaultAlipayClient;
import com.alipay.api.domain.AlipayFundTransUniTransferModel;
import com.alipay.api.domain.Participant;
import com.alipay.api.request.AlipayFundAuthOrderUnfreezeRequest;
import com.alipay.api.request.AlipayFundTransUniTransferRequest;
import com.alipay.api.response.AlipayFundAuthOrderUnfreezeResponse;
import com.alipay.api.response.AlipayFundTransUniTransferResponse;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import io.swagger.annotations.ApiParam;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springblade.common.utils.CommonUtil;
import org.springblade.core.log.logger.BladeLogger;
import org.springblade.core.tool.api.R;
import org.springblade.core.tool.utils.DateUtil;
import org.springblade.core.tool.utils.StringUtil;
import org.springblade.modules.api.controller.AliPay01Controller;
import org.springblade.modules.api.service.ITradeService;
import org.springblade.modules.finance.entity.OrderConsign;
import org.springblade.modules.finance.entity.OrderGrant;
import org.springblade.modules.finance.entity.PlatformAuthorization;
import org.springblade.modules.finance.pay.entity.AlipayProperties;
import org.springblade.modules.finance.service.IOrderConsignService;
import org.springblade.modules.finance.service.IOrderGrantService;
import org.springblade.modules.finance.service.IOrderService;
import org.springblade.modules.finance.service.IPlatformAuthorizationService;
import org.springblade.modules.shopping.entity.Consign;
import org.springblade.modules.shopping.service.IConsignService;
import org.springblade.modules.system.entity.User;
import org.springblade.modules.system.entity.UserApp;
import org.springblade.modules.system.service.IUserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.bind.annotation.RequestParam;

import java.util.ArrayList;
import java.util.List;

@Service
public class TradeServiceImpl implements ITradeService {

	private static final Logger log = LoggerFactory.getLogger(AliPay01Controller.class);

	@Autowired
	private IOrderService orderService;

	@Autowired
	private IConsignService consignService;

	@Autowired
	private IOrderConsignService orderConsignService;

	@Autowired
	private IOrderGrantService orderGrantService;

	@Autowired
	private IPlatformAuthorizationService platformAuthorizationService;

	@Autowired
	private IUserService userService;

	@Autowired
	private BladeLogger logger;

	@Autowired
	private AlipayClient client;//支付宝请求sdk客户端

	@Autowired
	private AlipayProperties properties;//支付宝sdk配置

	@Override
	public void transfer(Consign consign){
		String msg = "【平台打款】";
		if (consign != null){
			User user = userService.getById(consign.getConsignUserId());
			if (user != null){
				UserApp userApp = new UserApp();
				UserApp query = userApp.selectOne(Wrappers.<UserApp>lambdaQuery().eq(UserApp::getUserId,user.getId()));
				if (query != null){
					String transAmount = Double.toString(consign.getConsignPrice());
					String outTradeNo = CommonUtil.genTimeID();
					OrderConsign orderConsign = new OrderConsign();
					orderConsign.setOutTradeNo(outTradeNo);
					orderConsign.setConfirmTime(DateUtil.now());
					orderConsign.setConsignPrice(Double.valueOf(transAmount));
					orderConsign.setConsignDays(0);
					orderConsign.setConsignId(consign.getId());
					orderConsign.setGoodsId(consign.getGoodsId());
					orderConsign.setTotalPrice(consign.getConsignPrice());
					orderConsign.setPayUserId(0L);//支付人为系统
					orderConsign.setConsignUserId(consign.getConsignUserId());
					if (StringUtil.isEmpty(user.getRealName())){
						orderConsign.setIsConfirm(3);//异常
						orderConsign.setBody("该用户无法获取真实名字");
						orderConsignService.save(orderConsign);
						return;
					}
					String identity = userApp.getAlipayUserId();
					String name = user.getRealName();
					try {
						String privateKey = properties.getPrivateKey();
						String alipayPublicKey = properties.getAlipayPublicKey();
						AlipayConfig alipayConfig = new AlipayConfig();
						alipayConfig.setServerUrl("https://openapi.alipay.com/gateway.do");
						alipayConfig.setAppId(properties.getAppId());
						alipayConfig.setPrivateKey(privateKey);
						alipayConfig.setFormat("json" );
						alipayConfig.setAlipayPublicKey(alipayPublicKey);
						alipayConfig.setCharset("UTF8");
						alipayConfig.setSignType(properties.getSignType());
						//设置应用公钥证书路径//appCertPublicKey_2021003125657245
						alipayConfig.setAppCertPath(properties.getAppCertPath());
						//设置支付宝公钥证书路径//alipayCertPublicKey_RSA2
						alipayConfig.setAlipayPublicCertPath(properties.getAliPayCertPath());
						//设置支付宝根证书路径
						alipayConfig.setRootCertPath(properties.getAliPayRootCertPath());
						AlipayClient alipayClient = new DefaultAlipayClient(alipayConfig);
						AlipayFundTransUniTransferModel model = new AlipayFundTransUniTransferModel();
						model.setOutBizNo(CommonUtil.genTimeID());
						model.setRemark("贵州中宏科技有限公司进货仓单收款");
						model.setBusinessParams("{\"payer_show_name_use_alias\":\"true\"}");
						model.setBizScene("DIRECT_TRANSFER");
						Participant payeeInfo = new Participant();
						payeeInfo.setIdentity(identity);
						payeeInfo.setIdentityType("ALIPAY_USER_ID");
						payeeInfo.setName(name);
						model.setPayeeInfo(payeeInfo);
						model.setTransAmount(transAmount);
						model.setProductCode("TRANS_ACCOUNT_NO_PWD");
						model.setOrderTitle("进货仓单收款");
						AlipayFundTransUniTransferRequest request = new AlipayFundTransUniTransferRequest();
						request.setBizModel(model);
						AlipayFundTransUniTransferResponse response = alipayClient.certificateExecute(request);
						if (!response.isSuccess()){
							log.info("向用户【" + name +" 】打款失败，打款账号："  + identity);
							logger.info("打款失败", ",打款人：" + name + "支付宝账号：" + identity);
							orderConsign.setBody("向用户【" + name +" 】打款失败，打款账号："  + identity);
							orderConsign.setIsConfirm(3);//异常
						}else{
							log.info("向用户【" + name +" 】打款成功，打款账号："  + identity);
							logger.info("打款成功", ",打款人：" + name + "支付宝账号：" + identity);
							orderConsign.setBody("向用户【" + name +" 】打款成功，打款账号："  + identity);
							orderConsign.setIsConfirm(2);//确认
						}
						orderConsignService.save(orderConsign);
					} catch (AlipayApiException e) {
						e.printStackTrace();
						logger.info("打款失败", ",打款人：" + name + "支付宝账号：" + identity);
						orderConsign.setIsConfirm(3);//异常
						orderConsign.setBody(e.getMessage());
						orderConsignService.save(orderConsign);
					}
				}else{
					logger.info(msg, "无该用户userApp信息！");
				}
			}else {
				logger.info(msg, "无该用户user信息！");
			}
		}else{
			logger.info("系统打款失败", DateUtil.today());
		}
	}

	@Override
	public boolean platformReceipt(Long consignId) {
		//查询未抢的单
		List<Consign> list = consignService.list(Wrappers.<Consign>lambdaQuery()
			.eq(Consign::getConsignConfigId, consignId)
			.eq(Consign::getConsignType,2) //寄售
			.eq(Consign::getIsDelivery,1)  //未交割
			.eq(Consign::getConsignFor,2)  //订单
		);
		list.forEach(item -> {
			item.setConsignState(2);//待付款
		});
		//更新为待付款， 变为已寄售（后台打钱）
		return consignService.updateBatchById(list);
	}

	@Override
	public void orderGrant(List<OrderGrant> list) {
		for (OrderGrant orderGrant: list) {
			OrderGrant param = new OrderGrant();
			try {
				param.setId(orderGrant.getId());
				String authNo = orderGrant.getAuthNo();
				logger.info("解冻资金：", authNo);
				String amount = NumberUtil.mul(orderGrant.getNowNum(), orderGrant.getPrice()).toString();
				AlipayFundAuthOrderUnfreezeRequest request = new AlipayFundAuthOrderUnfreezeRequest();
				JSONObject bizContent = new JSONObject();
				bizContent.put("auth_no", authNo);
				bizContent.put("out_request_no","outRequestNo123");
				bizContent.put("amount", amount);
				bizContent.put("remark","解冻资金");
				JSONObject extraParam = new JSONObject();
				JSONObject unfreezeBizInfo = new JSONObject();
				unfreezeBizInfo.put("bizComplete",true);
				extraParam.put("unfreezeBizInfo",unfreezeBizInfo);
				bizContent.put("extra_param",extraParam);
				// 设置整体请求参数
				request.setBizContent(bizContent.toString());
				// 使用execute方法发起请求
				AlipayFundAuthOrderUnfreezeResponse response = client.certificateExecute(request);;
				if(response.isSuccess()){
					param.setStatus(2);//解冻
					logger.info("解冻资金成功", response.getBody());
				}else{
					param.setStatus(3);//解冻失败
					logger.info("解冻资金失败：", authNo);
				}
				param.setUnfreezeTime(DateUtil.now());
				orderGrantService.updateById(param);
			} catch (AlipayApiException e) {
				e.printStackTrace();
			}
		}
	}

	@Override
	public void platFormUnfreeze(List<PlatformAuthorization> list) {
		for (PlatformAuthorization platformAuthorization: list) {
			PlatformAuthorization param = new PlatformAuthorization();
			try {
				param.setId(platformAuthorization.getId());
				String authNo = platformAuthorization.getAuthNo();
				logger.info("解冻资金：", authNo);
				String amount = NumberUtil.mul(platformAuthorization.getTotalNum(), platformAuthorization.getAuthPrice()).toString();
				AlipayFundAuthOrderUnfreezeRequest request = new AlipayFundAuthOrderUnfreezeRequest();
				JSONObject bizContent = new JSONObject();
				bizContent.put("auth_no", authNo);
				bizContent.put("out_request_no","outRequestNo123");
				bizContent.put("amount", amount);
				bizContent.put("remark","解冻资金");
				JSONObject extraParam = new JSONObject();
				JSONObject unfreezeBizInfo = new JSONObject();
				unfreezeBizInfo.put("bizComplete",true);
				extraParam.put("unfreezeBizInfo",unfreezeBizInfo);
				bizContent.put("extra_param",extraParam);
				// 设置整体请求参数
				request.setBizContent(bizContent.toString());
				// 使用execute方法发起请求
				AlipayFundAuthOrderUnfreezeResponse response = client.certificateExecute(request);;
				if(response.isSuccess()){
					param.setState(2);//解冻
					logger.info("解冻资金成功", response.getBody());
				}else{
					param.setState(3);//解冻失败
					logger.info("解冻资金失败：", authNo);
				}
				param.setEndTime(DateUtil.now());
				platformAuthorizationService.updateById(param);
			} catch (AlipayApiException e) {
				e.printStackTrace();
			}
		}
	}

	public boolean payUnfreeze(String authNo, Double amount){
		try{
			AlipayFundAuthOrderUnfreezeRequest request = new AlipayFundAuthOrderUnfreezeRequest();
			JSONObject bizContent = new JSONObject();
			String out_request_no = CommonUtil.genTimeID();
			bizContent.put("auth_no", authNo);
			bizContent.put("out_request_no",out_request_no);
			bizContent.put("amount", amount);
			bizContent.put("remark","解冻资金");
			JSONObject extraParam = new JSONObject();
			JSONObject unfreezeBizInfo = new JSONObject();
			unfreezeBizInfo.put("bizComplete",true);
			extraParam.put("unfreezeBizInfo",unfreezeBizInfo);
			bizContent.put("extra_param",extraParam);
			// 设置整体请求参数
			request.setBizContent(bizContent.toString());
			// 使用execute方法发起请求
			AlipayFundAuthOrderUnfreezeResponse response = client.certificateExecute(request);
			if(response.isSuccess()){
				logger.info("解冻资金成功", response.getBody());
				OrderGrant orderGrant = new OrderGrant();
				orderGrant.setStatus(2);
				orderGrant.setUnfreezeTime(DateUtil.now());
				orderGrantService.update(orderGrant, Wrappers.<OrderGrant>lambdaQuery().eq(OrderGrant::getAuthNo,authNo));
				return true;
			}
			logger.info("解冻资金失败", response.getBody());
		} catch (AlipayApiException e) {
			e.printStackTrace();
		}
		return false;
	}

}
