package com.hfkj.channel.weixin;

import com.hfkj.channel.weixin.entity.OrderRefundModel;
import com.hfkj.channel.weixin.entity.WeChatPayReqInfo;
import com.hfkj.channel.weixin.utils.SignatureUtil;
import com.hfkj.channel.weixin.utils.WechatPayUtil;
import com.hfkj.channel.weixin.utils.WxOrderConfig;
import com.hfkj.channel.weixin.utils.XmlUtil;
import com.hfkj.common.exception.ErrorCode;
import com.hfkj.common.exception.ErrorHelp;
import com.hfkj.common.exception.SysCode;
import com.hfkj.config.CommonSysConst;
import com.hfkj.entity.*;
import com.hfkj.service.BsMerPlatformNoService;
import com.hfkj.service.BsMerService;
import com.hfkj.service.BsTradeOrderRefundService;
import com.hfkj.service.BsTradeOrderService;
import com.hfkj.sysenum.PlatformTypeEnum;
import com.hfkj.sysenum.TradeOrderMsgTypeEnum;
import com.hfkj.sysenum.TradeOrderRefundStatusEnum;
import com.hfkj.sysenum.TradeOrderStatusEnum;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.SortedMap;
import java.util.concurrent.ThreadLocalRandom;

/**
 * @className: WeiXinPayService
 * @author: HuRui
 * @date: 2022/11/21
 **/
@Service("weiXinPayService")
public class WeiXinPayService {

    @Resource
    private BsTradeOrderService tradeOrderService;

    @Resource
    private BsTradeOrderRefundService tradeOrderRefundService;

    @Resource
    private BsMerPlatformNoService merPlatformNoService;

    @Resource
    private BsMerService merService;

    @Resource
    private WechatPayUtil wechatPayUtil;

    /**
     * 交易【主扫】
     * @param tradeNo 订单号
     */
    public Map<String, Object> preorder(String tradeNo) throws Exception {
        // 查询交易订单
        BsTradeOrder order = tradeOrderService.getOrderByOutTradeNo(tradeNo);
        if (order == null) {
            throw ErrorHelp.genException(SysCode.System, ErrorCode.COMMON_ERROR, "未找到交易订单");
        }
        if (!order.getStatus().equals(TradeOrderStatusEnum.status1.getNumber())) {
            throw ErrorHelp.genException(SysCode.System, ErrorCode.COMMON_ERROR, "订单不处于待支付状态");
        }
        // 查询商户号
        BsMerPlatformNo platformNo = merPlatformNoService.getPlatformNo(order.getMerId(), PlatformTypeEnum.type4);
        if (platformNo == null) {
            throw ErrorHelp.genException(SysCode.System, ErrorCode.COMMON_ERROR, "未找到商户号");
        }
        // 查询商户
        BsMer mer = merService.getMer(order.getMerId());
        if (mer == null) {
            throw ErrorHelp.genException(SysCode.System, ErrorCode.COMMON_ERROR, "未知的商户信息");
        }
        String subAppid = "wxa075e8509802f826";
        // 微信支付
        WeChatPayReqInfo weChatPayReqInfo = new WeChatPayReqInfo();
        weChatPayReqInfo.setAppid("wx637bd6f7314daa46");                                // 服务商appid
        weChatPayReqInfo.setMch_id("1289663601");                                       // 服务商商户号
        weChatPayReqInfo.setSub_appid(subAppid);                                        // 公众号
        weChatPayReqInfo.setSub_mch_id(platformNo.getPlatformNo());

        // weChatPayReqInfo.setOpenid(openId);
        weChatPayReqInfo.setSub_openid(order.getPayUserId());
        weChatPayReqInfo.setNonce_str(SignatureUtil.createNonceStr());                                             // 随机字符串
        weChatPayReqInfo.setBody(order.getStoreName());                                       // 商品描述
        weChatPayReqInfo.setOut_trade_no(order.getOutTradeNo());                			  // 商户订单号
        weChatPayReqInfo.setTotal_fee(order.getTradeActualAmount().multiply(new BigDecimal("100")).intValue());                                             // 总金额
        weChatPayReqInfo.setSpbill_create_ip("122.9.135.148");                                // 终端ip
        weChatPayReqInfo.setNotify_url(CommonSysConst.getSysConfig().getWechat_pay_notify_url());                                                   // 通知url
        weChatPayReqInfo.setTrade_type("JSAPI");                                              // 交易类型
        weChatPayReqInfo.setProfit_sharing(order.getProfitSharingStatus().equals(true)?"Y":"N");

        //附加数据，区分订单类型
        Map<String,String> payMap = new HashMap<>();
        payMap.put("app_id", weChatPayReqInfo.getSub_appid());
        payMap.put("api_key", "Skufk5oi85wDFGl888i6wsRSTkdd5df5");
        payMap.put("unified_order_url", "https://api.mch.weixin.qq.com/pay/unifiedorder");
        SortedMap<Object, Object> sortedMap = wechatPayUtil.goWechatPay(weChatPayReqInfo,payMap);

        order.setPlatformAppid(subAppid);
        tradeOrderService.editOrder(order);

        Map<String, Object> returnMap = new HashMap<>();
        returnMap.put("order", order);
        returnMap.put("payMode", order.getPayMode());
        returnMap.put("payParam", sortedMap);
        return returnMap;
    }

    /**
     * 交易订单
     * @param refundNo    退款订单号
     * @param refundMoney 退款金额
     * @return
     * @throws Exception
     */
    public Map<String, Object> refund(String refundNo, BigDecimal refundMoney) throws Exception {
        // 查询交易订单
        BsTradeOrderRefund orderRefund = tradeOrderRefundService.getRefundByRefundNo(refundNo);
        if (orderRefund == null) {
            throw ErrorHelp.genException(SysCode.System, ErrorCode.COMMON_ERROR, "未找到订单");
        }
        if (!orderRefund.getStatus().equals(TradeOrderRefundStatusEnum.status1.getNumber())) {
            throw ErrorHelp.genException(SysCode.System, ErrorCode.COMMON_ERROR, "订单不处于退款中状态");
        }

        // 查询交易订单
        BsTradeOrder order = tradeOrderService.getOrderByOutTradeNo(orderRefund.getOutTradeNo());
        if (order == null) {
            throw ErrorHelp.genException(SysCode.System, ErrorCode.COMMON_ERROR, "未找到交易订单");
        }

        OrderRefundModel refundModel = WxOrderConfig.orderToRefund(
                order.getPlatformTradeNo(),
                orderRefund.getRefundNo(),
                order.getPlatformMerNo(),
                order.getTradeActualAmount(),
                orderRefund.getRefundAmount()
        );

        if("SUCCESS".equals(refundModel.getReturn_code()) && "SUCCESS".equals(refundModel.getResult_code())) {
            order.setStatus(TradeOrderStatusEnum.status6.getNumber());
            tradeOrderService.editOrder(order);

            Map<String, Object> returnMap = new HashMap<>();
            returnMap.put("order", order);
            returnMap.put("orderRefund", orderRefund);
            return returnMap;
        }

        throw ErrorHelp.genException(SysCode.System, ErrorCode.COMMON_ERROR, refundModel.getErr_code_des());
    }

}
