package com.kmall.api.service.wxGlobal;

import com.kmall.common.constant.Dict;
import com.kmall.api.dao.*;
import com.kmall.api.entity.*;
import com.kmall.api.service.ApiOrderService;
import com.kmall.api.service.PayerChildOrderRealService;
import com.kmall.api.service.pay.wxpay.WxPayPropertiesBuilder;
import com.kmall.common.entity.FormIdsEntity;
import com.kmall.common.service.FormIdsService;
import com.kmall.common.service.pay.global.CommonWxGlobalPayPropertiesBuilder;
import com.kmall.common.utils.Constant;
import com.kmall.common.utils.DateUtils;
import com.kmall.common.utils.wechat.wxglobal.SignUtil;
import com.kmall.common.utils.wechat.wxglobal.WechatGlobalUtil;
import com.kmall.common.utils.wechat.wxglobal.dto.WechatGlobalQueryApiResult;
import com.kmall.common.utils.wechat.wxglobal.dto.WechatGlobalUniformNotifyResult;
import com.kmall.common.utils.wechat.wxglobal.dto.WechatRefundAsynApiResult;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.*;

/**
 * 小程序form_id收集Service实现类
 *
 * @author Scott
 * @email
 * @date 2017-12-16 15:32:50
 */
@Service
public class ApiWxGlobalPayService {
    private static Logger logger = Logger.getLogger(ApiWxGlobalPayService.class);
    @Autowired
    private ApiOrderService orderService;
    @Autowired
    private FormIdsService formIdsService;
    @Autowired
    private PayerChildOrderRealService payerChildOrderRealService;
    @Autowired
    private ApiOrderExceptionRecordMapper mallOrderExceptionRecordMapper;
    @Autowired
    private ApiOrderProcessRecordMapper orderProcessRecordMapper;
    @Autowired
    private ApiOrderRefundMapper mallOrderRefundMapper;


    @Transactional
    public void payPrepay(Map<Object, Object> resultObj, WechatGlobalQueryApiResult queryApiResult, String nonceStr, List<OrderVo> orderVoList) {
        logger.info("payPrepay》》》》更新订单状态");
        String prepay_id = queryApiResult.getPrepay_id();
        String timeStamp = String.valueOf(System.currentTimeMillis() / 1000L);
        String appId = CommonWxGlobalPayPropertiesBuilder.instance().getAppId();
        String packageStr = "prepay_id=" + prepay_id;
        resultObj.put("appId", appId);
        resultObj.put("timeStamp", timeStamp);
        resultObj.put("nonceStr", nonceStr);
        resultObj.put("package", packageStr);
        //组装调起支付待签名串
        String signStr = toSignStr(appId,timeStamp,nonceStr,packageStr);
        //计算签名值
        String paySign = SignUtil.signData(signStr,CommonWxGlobalPayPropertiesBuilder.instance().getCertName(),CommonWxGlobalPayPropertiesBuilder.instance().getMchId());
        resultObj.put("paySign", paySign);

        for (OrderVo orderInfo: orderVoList) {
            orderInfo.setPay_id(prepay_id);
            orderInfo.setPayFlag(Dict.payFlag.item_wxglobalpay.getItem());
            orderInfo.setOrder_status(Integer.parseInt(Dict.orderStatus.item_100.getItem()));
            orderInfo.setPay_status(Integer.parseInt(Dict.payStatus.item_1.getItem())); // 付款中
            orderService.update(orderInfo);

            Map map = new HashMap();
            map.put("orderSn", orderInfo.getOrder_sn());
            List<PayerChildOrderRealEntity> list = payerChildOrderRealService.queryList(map);
            PayerChildOrderRealEntity entity = new PayerChildOrderRealEntity();
            entity.setGoodsBizType(orderInfo.getOrderBizType());
            entity.setOrderSn(orderInfo.getOrder_sn());
            entity.setMerchSn(orderInfo.getMerchSn());
            entity.setMerchOrderSn(orderInfo.getMerchOrderSn());
            entity.setPayNo(orderInfo.getPay_id());
            entity.setPayPrice(orderInfo.getActual_price());
            entity.setCreateTime(new Date());
            entity.setModTime(new Date());
            entity.setUserId(Integer.parseInt(orderInfo.getUser_id() + ""));
            if(list.size() > 0) {
                for (PayerChildOrderRealEntity payerChildOrderRealEntity:list) {
                    entity.setId(payerChildOrderRealEntity.getId());
                    payerChildOrderRealService.update(entity);
                }
            }else{
                payerChildOrderRealService.save(entity);//记录微信返回的支付单与子订单信息
            }
            FormIdsEntity formIdsEntity = formIdsService.getFormIdsByMerchOrderSn(orderInfo.getMerchOrderSn());
            if(formIdsEntity != null){
                FormIdsEntity formIds = new FormIdsEntity();
                formIds.setMerchOrderSn(orderInfo.getMerchOrderSn());
                formIds.setFormId(prepay_id);
                formIds.setValidNum(formIdsEntity.getValidNum()+1);
                formIds.setId(formIdsEntity.getId());
                formIdsService.releaseFormIds(formIds);
            }else{
                formIdsService.save(orderInfo.getUser_id(), prepay_id, 1, orderInfo.getMerchOrderSn());// 保存form_id
            }
        }
    }

    /**
     * 组装调起支付待签名串
     * @param appId appid
     * @param timeStamp 时间戳
     * @param nonceStr 随机串
     * @param packageStr 预支付编号
     * @return
     */
    private String toSignStr(String appId,String timeStamp,String nonceStr,String packageStr){
        logger.debug("******组装待签名串开始*****timestamp："+timeStamp+"；nonce_str："+nonceStr+"；appId："+appId+"；package："+packageStr);
        String signStr = appId+"\n"+timeStamp+"\n"+nonceStr+"\n"+packageStr+"\n";
        logger.debug("******组装待签名串结束*****signStr："+signStr);
        return signStr;
    }

    @Transactional
    public void notify(WechatGlobalUniformNotifyResult result) {
        String time_end = result.getSuccess_time();
        String out_trade_no = result.getOut_trade_no();//商户订单号
        String transaction_id = result.getId();//微信支付订单号
        Integer total_fee = result.getAmount().getTotal();//订单金额
        // 支付成功业务处理
        List<OrderVo> orderVoList = orderService.queryObjectByMerchOrderSn(out_trade_no);
        List<OrderProcessRecordEntity> processRecordEntityList = new ArrayList<>();
        Date timeEnd = DateUtils.convertStringToDate(time_end, DateUtils.DATE_TIME_PATTERN_YYYY_T);
        BigDecimal total = new BigDecimal(0);
        for(OrderVo orderInfo:orderVoList) {
            total = orderInfo.getActual_price().add(total);
        }
        total = total.multiply(Constant.ONE_HUNDRED);
        if(orderVoList != null && orderVoList.size()>0) {
            for(OrderVo orderInfo:orderVoList) {
                if(total.compareTo(new BigDecimal(total_fee)) == 0){//校验返回的订单金额是否与商户侧的订单金额一致
                    if (Dict.orderStatus.item_100.getItem().equalsIgnoreCase(orderInfo.getOrder_status() + "")
                            && Dict.payStatus.item_1.getItem().equalsIgnoreCase(orderInfo.getPay_status() + "")) {
                        OrderProcessRecordEntity processRecordEntity = orderProcessRecordMapper.queryObjectByOrderSn(orderInfo.getOrder_sn());
                        if (processRecordEntity != null) {
                            OrderProcessRecordEntity entity = new OrderProcessRecordEntity();
                            entity.setOrderSn(orderInfo.getOrder_sn());
                            entity.setUserId(Integer.valueOf(orderInfo.getUser_id() + ""));
                            entity.setPaySuccTime(timeEnd);//微信下单完成时间
                            entity.setId(processRecordEntity.getId());
                            processRecordEntityList.add(entity);
                        }
                        orderInfo.setPayTransactionId(transaction_id);
                        orderInfo.setPay_status(Integer.parseInt(Dict.payStatus.item_2.getItem()));
                        orderInfo.setPay_time(timeEnd);//微信下单完成时间
                        if (orderInfo.getOrder_status() == Integer.parseInt(Dict.orderStatus.item_100.getItem())) {
                            orderInfo.setOrder_status(Integer.parseInt(Dict.orderStatus.item_201.getItem()));
                        }
                        if(result.getAmount() != null){
                            BigDecimal totalFee = BigDecimal.valueOf(Long.valueOf(result.getAmount().getTotal()))
                                    .divide(Constant.ONE_HUNDRED);
                            orderInfo.setTotalFee(totalFee);//订单标价金额
                            orderInfo.setFeeType(result.getAmount().getCurrency());//订单标价币种
                            BigDecimal cashFee = BigDecimal.valueOf(Long.valueOf(result.getAmount().getPayer_total()))
                                    .divide(Constant.ONE_HUNDRED);
                            orderInfo.setCashFee(cashFee);//用户支付金额
                            orderInfo.setCashFeeType(result.getAmount().getPayer_currency());//用户支付金额币种
                            if(result.getAmount().getExchange_rate() != null) {
                                Integer rate = result.getAmount().getExchange_rate().getRate();
                                if (rate != null) {
                                    BigDecimal rateValue = new BigDecimal(rate).divide(new BigDecimal(100000000));
                                    orderInfo.setRate(rateValue.toString());//汇率
                                }
                            }
                            // TODO: 2018/12/29  根据汇率计算每笔订单的用户支付人民币金额
                        }
                        orderService.update(orderInfo);
                        orderProcessRecordMapper.updateBatch(processRecordEntityList);//更新订单流转信息

                        // 微信支付成功通知
                        orderService.notifyPaySuccess(orderInfo);
                    }
                }else{
                    //不一致
                    MallOrderExceptionRecord mallOrderExceptionRecord = new MallOrderExceptionRecord();
                    mallOrderExceptionRecord.setUserId(Integer.parseInt(orderInfo.getUser_id() + ""));
                    mallOrderExceptionRecord.setOrderSn(orderInfo.getOrder_sn());
                    mallOrderExceptionRecord.setExceptionStatus(Dict.exceptionStatus.item_04.getItem());
                    mallOrderExceptionRecord.setCreateTime(new Date());
                    mallOrderExceptionRecord.setExceptionContent("微信支付回调返回的订单金额与商户订单金额不一致");
                    mallOrderExceptionRecordMapper.save(mallOrderExceptionRecord);//支付订单异常记录
                }
            }
        }
    }


    @Transactional
    public void refundNotify(WechatRefundAsynApiResult refundApiResult) {
        String success_time = refundApiResult.getSuccess_time();
        String out_trade_no = refundApiResult.getOut_trade_no();//商户订单号
        // 业务处理
        List<OrderVo> orderVoList = orderService.queryOrderByMerchOrderSnAndRefundStatus(out_trade_no);
        Date successTime = DateUtils.convertStringToDate(success_time, DateUtils.DATE_TIME_PATTERN_YYYY_T);
        if(orderVoList != null && orderVoList.size()>0) {
            for(OrderVo orderInfo:orderVoList) {
                if(orderInfo.getOrder_status() == Integer.parseInt(Dict.orderStatus.item_201.getItem())
                        || orderInfo.getOrder_status() == Integer.parseInt(Dict.orderStatus.item_401.getItem())){
                    MallOrderRefund mallOrderRefund = mallOrderRefundMapper.queryObjectByOrderId(orderInfo.getId()+"");
                    MallOrderRefund orderRefund = new MallOrderRefund();
                    OrderVo orderVo = new OrderVo();
                    if(mallOrderRefund != null) {
                        if (mallOrderRefund.getOutRefundNo() != null) {
                            if (mallOrderRefund.getOutRefundNo().equalsIgnoreCase(refundApiResult.getOut_refund_no())) {
                                orderRefund.setOutRefundNo(refundApiResult.getOut_refund_no());
                                orderRefund.setRefundTime(successTime);//退款成功时间
                                orderRefund.setRefundId(refundApiResult.getRefund_id());
                                orderRefund.setRefundMoney(BigDecimal.valueOf(Long.valueOf(refundApiResult.getAmount().getRefund())).divide(Constant.ONE_HUNDRED));
                                if (refundApiResult.getRefund_status().equalsIgnoreCase(WechatGlobalUtil.WXTradeState.SUCCESS.getCode())) {
                                    orderRefund.setRefundStatus(Integer.parseInt(Dict.RefundStatus.item_2.getItem()));
                                    orderRefund.setWechatRefundStatusDes("退款成功");
                                    orderVo.setPay_status(Integer.parseInt(Dict.payStatus.item_4.getItem()));
                                } else if (refundApiResult.getRefund_status().equalsIgnoreCase("PROCESSING")) {
                                    orderRefund.setRefundStatus(Integer.parseInt(Dict.RefundStatus.item_5.getItem()));
                                    orderRefund.setWechatRefundStatusDes("退款处理中");
                                    orderVo.setPay_status(Integer.parseInt(Dict.payStatus.item_3.getItem()));
                                } else if (refundApiResult.getRefund_status().equalsIgnoreCase("CLOSED")) {
                                    orderRefund.setRefundStatus(Integer.parseInt(Dict.RefundStatus.item_4.getItem()));
                                    orderRefund.setWechatRefundStatusDes("退款关闭");
                                    orderVo.setPay_status(Integer.parseInt(Dict.payStatus.item_5.getItem()));
                                } else if (refundApiResult.getRefund_status().equalsIgnoreCase("CHANGE")) {
                                    orderRefund.setRefundStatus(Integer.parseInt(Dict.RefundStatus.item_4.getItem()));
                                    orderRefund.setWechatRefundStatusDes("退款异常");
                                    orderVo.setPay_status(Integer.parseInt(Dict.payStatus.item_6.getItem()));
                                }
                                BigDecimal cashFee = BigDecimal.valueOf(Long.valueOf(refundApiResult.getAmount().getPayer_total())).divide(Constant.ONE_HUNDRED);
                                orderRefund.setCashFee(cashFee);
                                orderRefund.setCashFeeType(refundApiResult.getAmount().getPayer_currency());

                                orderRefund.setRefundFeeType(refundApiResult.getAmount().getCurrency());
                                BigDecimal totalFee = BigDecimal.valueOf(Long.valueOf(refundApiResult.getAmount().getRefund())).divide(Constant.ONE_HUNDRED);
                                orderRefund.setTotalFee(totalFee);
                                orderRefund.setFeeType(refundApiResult.getAmount().getCurrency());
                                BigDecimal cashRefundFee = BigDecimal.valueOf(Long.valueOf(refundApiResult.getAmount().getPayer_refund())).divide(Constant.ONE_HUNDRED);
                                orderRefund.setCashRefundFee(cashRefundFee);
                                orderRefund.setCashRefundFeeType(refundApiResult.getAmount().getPayer_currency());

                                if (refundApiResult.getAmount().getExchange_rate() != null) {
                                    Integer rate = refundApiResult.getAmount().getExchange_rate().getRate();
                                    if (rate != null) {
                                        BigDecimal rateValue = new BigDecimal(rate).divide(new BigDecimal(100000000));
                                        orderRefund.setRate(rateValue.toString());
                                    }
                                }
                                orderRefund.setRefundRecvAccout(refundApiResult.getRecv_accout());
                                orderRefund.setId(mallOrderRefund.getId());
                                mallOrderRefundMapper.update(orderRefund);//更新订单退款信息

                                orderVo.setOrder_status(Integer.parseInt(Dict.orderStatus.item_401.getItem()));
                                orderVo.setId(orderInfo.getId());
                                orderService.update(orderVo);
                            }
                        }
                    }
                }
            }
        }
    }

}
