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){
			consign.setConsignState(3);
			consignService.updateById(consign);
			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);
						consign.setConsignState(3);
						consignService.updateById(consign);
					} 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());
		}

	}

	/**
	 * 用户仓单收款
	 * 1、向用户打款
	 * 2、修改寄售订单金额
	 * @param user 用户
	 * @param transAmount 金额
	 * @param orderConsignId 寄售（进货）Id
	 */
	@Override
	public void transfer(UserApp user, String transAmount, Long orderConsignId, Consign consign){
		OrderConsign orderConsign = new OrderConsign();
		orderConsign.setId(orderConsignId);
		orderConsign.setConfirmTime(DateUtil.now());
		if (user == null){
			orderConsign.setIsConfirm(3);//异常
			orderConsign.setBody("该用户不存在");
			orderConsignService.updateById(orderConsign);
			return;
		}
		if (StringUtil.isEmpty(user.getAlipayUserId())){
			orderConsign.setIsConfirm(3);//异常
			orderConsign.setBody("用户【" + user.getUserId() +" 】无支付宝账号数据");
			orderConsignService.updateById(orderConsign);
			return;
		}
		User u = userService.getById(user.getUserId());
		if (u == null){
			orderConsign.setIsConfirm(3);//异常
			orderConsign.setBody("该用户不存在,可能被删除或者冻结");
			orderConsignService.updateById(orderConsign);
			return;
		}
		if (StringUtil.isEmpty(u.getRealName())){
			orderConsign.setIsConfirm(3);//异常
			orderConsign.setBody("该用户无法获取真实名字");
			orderConsignService.updateById(orderConsign);
			return;
		}
		String identity = user.getAlipayUserId();
		String name = u.getRealName();
		try {
			String privateKey = "MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQCU4XTbNjnNOmuEnwBEgUBOVLK5CaUiUFKEkVW1/2sTlijARZzLtzwXfbkvzHEhCSu+E+OA1Futbh5HwNAC06bvqYDS+TXrFuZ0LcDaU92lk5Hp/ed8NhRXtm0gss1TS0vebOq+3kejErIvVCg9kNMrYMrmdf8G0+zKlCp3vrfdM37IeLXp3GoOckNzHh/LT7rLd7/9QcdSCPixPSwusrfCusw3H093cuWkV9WX4Go/zHTL9rAEwJPOn36OhyVc1oG113ZJiVg7KgsZGOCJJyh9BvlKq2vuKxnylQwq9Kh5e+BfP2FSWs7a1XMj/79JsZTxztJ9tFqcSXQh99vq1nd1AgMBAAECggEAVglIT5oxoxEcq0J7lBshf2Lg+Z/CR2clmKioYImfZm1DVYGlD/DvECA+kYnS4qV7GthBg+S0qi/V3d9mFgwcD6nj4YfVCets+Dyskz8d+p6iFxf820IhVWL+A4Rwta7wxDQrIGwx9+JJCKLYsmNsNUg1WSNdYqO71oHzXMnhVTmYJ6sKOrrBucyI4Ydu9UbfN+DRRGD9seL+Nxh1V2PPXs4ftk2kRlG18LaTPgFba1g8QBIpGDR9gFqM+DvBHUxAWsPRnL1+q0c6o5Ndk7W5f7Ob1zxF/lgqHudiG38jItkwc7MLMOYjbV5wiJPZc93nsHS1CKPSEX9/snNLnx2LQQKBgQDMyLBVVasfTMQpMjyi+Jof9JLHPiRP3dEHwZECUgfdWhPoidLjK9y1wszmCLrcg01842WufrpbJ1QXs+g8x6+DhLHvcKum1znsvQKWdy/2V6a2eahNHsYi1Qus+N0dFgotfZwfElfkIU/jAwh6OnYPCXQCVmdvoxzmdk81L04d5QKBgQC6HY6EZ8o4mo4CzDss2qxT2oKuiI0clnbDPC9LJzkRBVbHosx6AO+C3RyfREZxMzNhYW3XnozifDyRw6rlvI6toE3l9ku71dJS1aKZwbH/h0rdHXXqDHARYc9rdwCzOM2t2Kve/PgXxCDQdwY/m0deXM22oKdOlb7miz2YTGLaUQKBgEg8qucPNzPtUmztybH7W/LVxUj/RLPfnTLNNyfIY/nTIp6ur3NvL4X2V2z1u2S59IWPeXjaP0aUUvehgNSf4+vSzSmXZxWNamN2MQl+ta6CMM7Bj3rU1jPHTz0O9ICkG6b8Xiwfvl082v9LPJxRLwAS55dDf21D7pflN/+c1kN5AoGARaRHrt3TeojCuONJBUiyERKDseFgxCC9QeLkY3/Cx86yoTMWxlRRSyuHyUTYAwXApSC65GLsntcUJwsLiLmcvfVtEK6vuhKRh/Nuy5ACFfa/Gawrci/DQ43Q+opmFaoctH+OGHuaLfJywO64xNZKx1F8nGjTEgHQlB3oJ3P1zXECgYBW/GRUU+SevGeLjZTZ9WqG+ztseItnmEwmar9tGhR9TNv3vDiL5/fsAfI8ApMiIzDe6+QfS5Lxx5rD6V4Et/zBpsf8JzqP2eDiTe9UiHxDr2v5NIxelf404VZcdRh83u84lCJTa/ZYanFu94UW6h70MHhDWtiWddtFR3EXt5hD9w==";
			String alipayPublicKey = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAhIxPBQL0OKBc6fcU/9PdVTMA7L2s314oU2w1q06ywQSDdhF3RY1Bo0Eqh4Zg8QpPirFeyAc4rhFjyKZRlngQXrybcAhUfswD86QQGodObe3aA9bbWdXiTt10Q5CBk5GImadNiEW6Adh+0bY5ezf1RbxIjbGDfH6x5gatZnpjPswiHMQnskZtg9JSfE2u8WEKuSaH8yhnkllHpIHWnWvFvXwNVNycXdmDrEe7gIB1yCouNK6/DZ7IQH2AajSuvbxmCqO0MzywEfgvLqE0GFVsKKmXvgJebRAnW9RmGhmrxvEIceXCjR3tbxM9gX8lioDlqKnBootTgAbjIJ5VrPvKPwIDAQAB";
			AlipayConfig alipayConfig = new AlipayConfig();
			alipayConfig.setServerUrl("https://openapi.alipay.com/gateway.do");
			alipayConfig.setAppId("2021003125657245");
			alipayConfig.setPrivateKey(privateKey);
			alipayConfig.setFormat("json");
			alipayConfig.setAlipayPublicKey(alipayPublicKey);
			alipayConfig.setCharset("UTF8");
			alipayConfig.setSignType("RSA2");
			//设置应用公钥证书路径//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);//确认
			}
			consign.setConsignState(3);
			consignService.updateById(consign);
			orderConsignService.updateById(orderConsign);
		} catch (AlipayApiException e) {
			e.printStackTrace();
			logger.info("打款失败", ",打款人：" + name + "支付宝账号：" + identity);
			orderConsign.setIsConfirm(3);//异常
			orderConsign.setBody(e.getMessage());
			orderConsignService.updateById(orderConsign);
		}

	}

	@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;
	}

}
