package com.gree.mall.miniapp.logic.user;

import cn.hutool.core.convert.Convert;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import cn.hutool.json.JSONUtil;
import com.gree.mall.miniapp.commonmapper.SoldNumMapper;
import com.gree.mall.miniapp.enums.*;
import com.gree.mall.miniapp.enums.es.ESGoodsStatusEnum;
import com.gree.mall.miniapp.enums.material.WebsitGoodsTypeEnum;
import com.gree.mall.miniapp.enums.material.WebsitSalesTypeEnum;
import com.gree.mall.miniapp.enums.workorder.OrderFlagEnum;
import com.gree.mall.miniapp.logic.acitivy.PromotionLuckDrawLogic;
import com.gree.mall.miniapp.logic.common.WxPubNoticeLogic;
import com.gree.mall.miniapp.logic.common.outside.WechatLogic;
import com.gree.mall.miniapp.logic.engin.WebsitGoodsMangerLogic;
import com.gree.mall.miniapp.logic.order.LeaseOrderLogic;
import com.gree.mall.miniapp.plus.entity.*;
import com.gree.mall.miniapp.plus.service.*;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.jdom.JDOMException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

//import com.gree.mall.miniapp.logic.common.FucaiLogic;

@Slf4j
@Service
public class PayLogic {

    @Autowired
    WechatLogic wechatLogic;
//    @Autowired
//    OrderTaxLogic orderTaxLogic;
//    @Autowired
//    FucaiLogic fucaiLogic;
    @Autowired
    PromotionLuckDrawLogic promotionLuckDrawLogic;
    @Autowired
    UserService userService;
    @Autowired
    OrderInfoService orderInfoService;
    @Autowired
    OrderDetailService orderDetailService;
    @Autowired
    OrderShareService orderShareService;
    @Autowired
    UserCouponService userCouponService;

    @Autowired
    CouponGoodsService couponGoodsService;
    @Autowired
    private GoodsService goodsService;
    @Autowired
    private SoldNumMapper soldNumMapper;
    @Autowired
    private GoodsSpecService goodsSpecService;
    @Autowired
    PromotionGroupSpecService promotionGroupSpecService;
    @Autowired
    GiftExchangeCodeService giftExchangeCodeService;
    @Resource
    WebsitSalesService websitSalesService;
    @Resource
    BuyServiceRecordService buyServiceRecordService;
    @Resource
    BuyNormConfigService buyNormConfigService;
    @Resource
    AdminCompanyWechatService adminCompanyWechatService;
    @Autowired
    WxPubNoticeLogic wxPubNoticeLogic;

    @Autowired
    PgIncreOrderService pgIncreOrderService;

    @Autowired
    AdminUserService adminUserService;

    @Autowired
    AdminUserWebsitRelaService adminUserWebsitRelaService;
    @Resource
    WebsitGoodsMangerLogic websitGoodsMangerLogic;
    @Resource
    LeaseOrderService leaseOrderService;
    @Resource
    LeaseOrderItemService leaseOrderItemService;
    @Resource
    LeaseOrderPayRecordService leaseOrderPayRecordService;
    @Resource
    LeaseOrderLogic leaseOrderLogic;
    @Resource
    EsOrderInfoService esOrderInfoService;

    @Autowired
    EsGoodsService esGoodsService;

    @Autowired
    CarouselMapService carouselMapService;

    public void payCall(String id,String transactionId,BigDecimal totalFee) throws JDOMException, IOException {

        OrderInfo orderInfo = orderInfoService.getById(id);
        if (!orderInfo.getOrderStatus().equals(OrderStatusEnum.NOPAY.toString())) {
            log.info("请勿重复支付,orderId:{}", id);
            return;
        }
        if(StringUtils.equals(orderInfo.getPayTypeId(),PayTypeEnum.WECHAT.getKey())) {
            orderInfo.setOrderStatus(OrderStatusEnum.DFH.toString());
        }else{
            orderInfo.setOrderStatus(OrderStatusEnum.DQR.toString());
        }
        orderInfo.setPayTime(new Date());
        orderInfo.setTransactionId(transactionId);
        orderInfo.setDiscountAmount(orderInfo.getTotalAmount().subtract(orderInfo.getPayAmount()));
        if(orderInfo.getYjhxDkFlag() != null && orderInfo.getYjhxDkFlag() == 1){
            orderInfo.setDiscountAmount(orderInfo.getDiscountAmount().subtract(orderInfo.getYjhxDiscountAmount()));
        }

        //计算各订单详情的优惠金额以及实际支付金额
        BigDecimal lastDiscountAmount = new BigDecimal(0);
        //实际支付金额
        BigDecimal payAmount = orderInfo.getPayAmount();

        //判断金额是否支付正确
        if(totalFee.doubleValue() != payAmount.doubleValue()){
            log.error("【支付回调严重bug】......orderId:{},微信回调金额:{},订单实际支付金额:{}",id,totalFee,payAmount);
            return;
        }
        List<OrderDetail> orderDetails = orderDetailService.lambdaQuery()
                .eq(OrderDetail::getOrderId, orderInfo.getOrderId())
                .orderByAsc(OrderDetail::getPrice)
                .list();
        //商品实付总金额(不包含运费)
        BigDecimal totalProductPayAmount = orderDetails.stream().map(OrderDetail::getPayAmount).reduce(BigDecimal::add).orElse(BigDecimal.valueOf(0));
        //优惠券优惠金额
        BigDecimal couponDiscAmount = orderInfo.getCouponValue();
        //使用优惠券的处理
        if(couponDiscAmount != null && couponDiscAmount.doubleValue() > 0) {
            //公共的处理(可能涉及到修改了支付金额的)
            for (int i = 0; i < orderDetails.size(); i++) {
                OrderDetail orderDetail = orderDetails.get(i);
                //实付金额在总实付金额的占比
                BigDecimal orderDiscountPercent = orderDetail.getPayAmount().divide(totalProductPayAmount, 4, BigDecimal.ROUND_DOWN);
                updateSaleNum(orderDetail);
                if (i == orderDetails.size() - 1) {
                    //最后一个，直接拿总的减
                    BigDecimal subtract = couponDiscAmount.subtract(lastDiscountAmount);
                    orderDetail.setDiscountAmount(orderDetail.getDiscountAmount().add(subtract));
                    orderDetail.setPayAmount(orderDetail.getTotalPrice().subtract(orderDetail.getDiscountAmount()));
                    if(orderInfo.getYjhxDkFlag() != null && orderInfo.getYjhxDkFlag() == 1){
                        orderDetail.setPayAmount(orderDetail.getPayAmount().subtract(orderDetail.getYjhxDiscountAmount()));
                    }
                    orderDetail.setPayAmount(orderDetail.getPayAmount().doubleValue() < 0 ? BigDecimal.valueOf(0) : orderDetail.getPayAmount());
                    continue;
                }
                BigDecimal discount = orderDiscountPercent.multiply(couponDiscAmount).setScale(2, BigDecimal.ROUND_DOWN);

                //优惠后的实际支付金额
                orderDetail.setDiscountAmount(orderDetail.getDiscountAmount().add(discount));
                orderDetail.setPayAmount(orderDetail.getTotalPrice().subtract(orderDetail.getDiscountAmount()));
                orderDetail.setPayAmount(orderDetail.getPayAmount().doubleValue() < 0 ? BigDecimal.valueOf(0) : orderDetail.getPayAmount());
                lastDiscountAmount = lastDiscountAmount.add(discount);
            }
        }

        //计算满件打折商品 或 认筹活动的佣金
        for(OrderDetail orderDetail : orderDetails){
            if(com.aliyuncs.utils.StringUtils.isNotEmpty(orderDetail.getPromotionFullPieceId())) {

                orderDetail.setShareAmount(orderDetail.getPayAmount().multiply(orderDetail.getPromotionFullPieceShareRate()));
                log.info("【满减打折佣金计算】实付金额:"+orderDetail.getPayAmount()+",佣金比例:"+orderDetail.getPromotionFullPieceShareRate()
                        + com.aliyuncs.utils.StringUtils.isNotEmpty(orderDetail.getPromotionFullPieceId())+",佣金："+orderDetail.getShareAmount());
            }
            orderDetail.setProfitAmount(orderDetail.getPayAmount().subtract(orderDetail.getShareAmount()));
        }
        orderDetailService.updateBatchById(orderDetails);

//        List<OrderDetail> promotionOrderDetails = orderDetails.stream().filter(v -> StringUtils.isNotBlank(v.getPromotionGroupId())).collect(Collectors.toList());
        List<OrderDetail> commonlyOrderDetails = orderDetails.stream().filter(v -> StringUtils.isBlank(v.getPromotionGroupId())).collect(Collectors.toList());
        //团购商品分佣金(暂没团购)
//        if(promotionOrderDetails.size() > 0)
//            this.addOrderShare(orderInfo, promotionOrderDetails,2);
        //普通商品分佣金
        if(commonlyOrderDetails.size() > 0)
            this.addOrderShare(orderInfo, commonlyOrderDetails,1);

        //对接金蝶系统
//        Boolean aBoolean = fucaiLogic.sendSaleOrder(orderDetails,orderInfo,orderInfo.getWebsitNumber());
//        orderInfo.setJindSaleStatus(aBoolean);


        //如果是线下单需要将审批状态变更为已通过
        if(orderInfo.getSaleType() != null && orderInfo.getSaleType() == 2){
            orderInfo.setExamineStatus(ExamineStatusEnum.OK.getKey());
            orderInfo.setExamineTime(new Date());
        }

        orderInfo.updateById();

        //提醒发货通知
        if(!orderInfo.getIsAllVr()){
            wxPubNoticeLogic.addDeliver(orderInfo.getCompanyWechatId(),orderInfo.getOrderId(),orderInfo.getOrderTitle(),
                    orderInfo.getPayAmount(),orderInfo.getReceUserName(),orderInfo.getReceAddress());
            this.sendMaterialExamine(orderInfo.getOrderId());
        }
        //订单支付成功的公众号通知
        wxPubNoticeLogic.addPaid(orderInfo.getPhone(),orderInfo.getCompanyWechatId(),orderInfo.getOrderId(),orderInfo.getOrderTitle(),
                orderInfo.getPayAmount(),orderInfo.getReceUserName(),orderInfo.getPayTime(),1);

        this.sendMaterialExamineOrder(orderInfo.getOrderId());
        //回写抽奖活动
        //promotionLuckDrawLogic.updatePromotionLuckDrawCode(orderInfo);
        log.info("===============支付回调结束:{}==============", id);
    }

    public void sendMaterialExamineOrder(String orderId) {

        OrderInfo orderInfo = orderInfoService.getById(orderId);



        List<AdminUserWebsitRela> adminUserWebsitRelas = adminUserWebsitRelaService.lambdaQuery()
                .eq(AdminUserWebsitRela::getAdminWebsitId, orderInfo.getWebsitId()).list();

        for (AdminUserWebsitRela adminUserWebsitRela : adminUserWebsitRelas) {
            AdminUser one = adminUserService.getById(adminUserWebsitRela.getAdminUserId());
            NoticeRecord noticeRecord = new NoticeRecord();
            noticeRecord.setNoticeId(orderInfo.getOrderId());
            String format = DateUtil.format(new Date(), "yyyy-MM-dd");
            noticeRecord.setTitle(orderInfo.getOrderTitle()+"创建时间"+format+",已支付成功");
            noticeRecord.setContent(orderInfo.getOrderTitle()+"创建时间"+format+",已支付成功");
            noticeRecord.setType(NoticeEnum.B.getKey());
            noticeRecord.setNoticeType(NoticeTypeEnum.SYSTEM.getKey());
            noticeRecord.setIsNotice(IsYesNoEnum.YES.getKey());
            noticeRecord.setReadFlag(IsYesNoEnum.NO.getKey());
            noticeRecord.setAdminUserId(adminUserWebsitRela.getAdminUserId());
            noticeRecord.setAdminNickName(one.getNickName());
            noticeRecord.setIssueTime(new Date());
            noticeRecord.setAdminCompanyId(adminUserWebsitRela.getCompanyWechatId());
            noticeRecord.setAdminCompanyName(orderInfo.getCompanyWechatName());
            noticeRecord.setAdminNoticeType(AdminNoticTypeEnum.CR_SALES.getKey());
            noticeRecord.setOrderId(orderInfo.getOrderId());
            noticeRecord.setPaidType(PaidTypeEnum.MALL.getKey());
            noticeRecord.insert();
        }

        AdminUser one = adminUserService.lambdaQuery().eq(AdminUser::getCompanyWechatId, orderInfo.getCompanyWechatId())
                .eq(AdminUser::getType, 1).last("limit 1").one();

        NoticeRecord noticeRecordCom = new NoticeRecord();
        noticeRecordCom.setNoticeId(orderInfo.getOrderId());
        String format = DateUtil.format(new Date(), "yyyy-MM-dd");
        noticeRecordCom.setTitle(orderInfo.getOrderTitle()+"创建时间"+format+",已支付成功");
        noticeRecordCom.setContent(orderInfo.getOrderTitle()+"创建时间"+format+",已支付成功");
        noticeRecordCom.setType(NoticeEnum.B.getKey());
        noticeRecordCom.setNoticeType(NoticeTypeEnum.SYSTEM.getKey());
        noticeRecordCom.setIsNotice(IsYesNoEnum.YES.getKey());
        noticeRecordCom.setReadFlag(IsYesNoEnum.NO.getKey());
        noticeRecordCom.setAdminUserId(one.getAdminUserId());
        noticeRecordCom.setAdminNickName(one.getNickName());
        noticeRecordCom.setIssueTime(new Date());
        noticeRecordCom.setAdminCompanyId(one.getCompanyWechatId());
        noticeRecordCom.setAdminCompanyName(one.getCompanyName());
        noticeRecordCom.setAdminNoticeType(AdminNoticTypeEnum.CR_SALES.getKey());
        noticeRecordCom.setOrderId(orderInfo.getOrderId());
        noticeRecordCom.setPaidType(PaidTypeEnum.MALL.getKey());
        noticeRecordCom.insert();

    }


    private void sendMaterialExamine(String orderId) {

        OrderInfo orderInfo = orderInfoService.getById(orderId);


        List<AdminUserWebsitRela> adminUserWebsitRelas = adminUserWebsitRelaService.lambdaQuery()
                .eq(AdminUserWebsitRela::getAdminWebsitId, orderInfo.getWebsitId()).list();

        for (AdminUserWebsitRela adminUserWebsitRela : adminUserWebsitRelas) {
            AdminUser one = adminUserService.getById(adminUserWebsitRela.getAdminUserId());
            NoticeRecord noticeRecord = new NoticeRecord();
            noticeRecord.setNoticeId(orderInfo.getOrderId());
            String format = DateUtil.format(new Date(), "yyyy-MM-dd");
            noticeRecord.setTitle(orderInfo.getOrderTitle()+"创建时间"+format+",请及时安排发货");
            noticeRecord.setContent(orderInfo.getOrderTitle()+"创建时间"+format+",请及时安排发货");
            noticeRecord.setType(NoticeEnum.B.getKey());
            noticeRecord.setNoticeType(NoticeTypeEnum.SYSTEM.getKey());
            noticeRecord.setIsNotice(IsYesNoEnum.YES.getKey());
            noticeRecord.setReadFlag(IsYesNoEnum.NO.getKey());
            noticeRecord.setAdminUserId(adminUserWebsitRela.getAdminUserId());
            noticeRecord.setAdminNickName(one.getNickName());
            noticeRecord.setIssueTime(new Date());
            noticeRecord.setAdminCompanyId(adminUserWebsitRela.getCompanyWechatId());
            noticeRecord.setAdminCompanyName(orderInfo.getCompanyWechatName());
            noticeRecord.setAdminNoticeType(AdminNoticTypeEnum.SEND_MALL.getKey());
            noticeRecord.setOrderId(orderInfo.getOrderId());
            noticeRecord.insert();
        }

        AdminUser one = adminUserService.lambdaQuery().eq(AdminUser::getCompanyWechatId, orderInfo.getCompanyWechatId())
                .eq(AdminUser::getType, 1).last("limit 1").one();

        NoticeRecord noticeRecordCom = new NoticeRecord();
        noticeRecordCom.setNoticeId(orderInfo.getOrderId());
        String format = DateUtil.format(new Date(), "yyyy-MM-dd");
        noticeRecordCom.setTitle(orderInfo.getOrderTitle()+"创建时间"+format+",请及时安排发货");
        noticeRecordCom.setContent(orderInfo.getOrderTitle()+"创建时间"+format+",请及时安排发货");
        noticeRecordCom.setType(NoticeEnum.B.getKey());
        noticeRecordCom.setNoticeType(NoticeTypeEnum.SYSTEM.getKey());
        noticeRecordCom.setIsNotice(IsYesNoEnum.YES.getKey());
        noticeRecordCom.setReadFlag(IsYesNoEnum.NO.getKey());
        noticeRecordCom.setAdminUserId(one.getAdminUserId());
        noticeRecordCom.setAdminNickName(one.getNickName());
        noticeRecordCom.setIssueTime(new Date());
        noticeRecordCom.setAdminCompanyId(one.getCompanyWechatId());
        noticeRecordCom.setAdminCompanyName(one.getCompanyName());
        noticeRecordCom.setAdminNoticeType(AdminNoticTypeEnum.SEND_MALL.getKey());
        noticeRecordCom.setOrderId(orderInfo.getOrderId());
        noticeRecordCom.insert();

    }


    /**
     * 修改销量
     */
    private void updateSaleNum(OrderDetail orderDetail) {
        try {
            //秒杀销售数量

            //团购活动销售数量
            List<PromotionGroupSpec> list = promotionGroupSpecService.lambdaQuery().eq(PromotionGroupSpec::getGoodsSpecId, orderDetail.getGoodsSpecId()).list();
            for(PromotionGroupSpec promotionGroupSpec : list){
                promotionGroupSpec.setSalesNum(promotionGroupSpec.getSalesNum() + orderDetail.getNum());
                promotionGroupSpec.updateById();
            }

            soldNumMapper.updateGoodsSpec(orderDetail);
            soldNumMapper.updateGoods(orderDetail);
        } catch (Exception e) {

        }
    }


//    public String refundCall(String body) throws Exception {
//
//        log.info("【微信退款回调开始】{}", body);
//        Map<String, String> params = wechatLogic.doXMLParse(body);
//        if (params.get("return_code").equals("SUCCESS")) {
//            String reqInfo = params.get("req_info");
//            Map map = wechatLogic.refundAESStr(reqInfo);
//            String orderId = (String) map.get("out_trade_no");
//            List<OrderDetail> list = orderDetailService.lambdaQuery()
//                    .eq(OrderDetail::getOrderId, orderId)
//                    .eq(OrderDetail::getRefund, true).list();
//            BigDecimal totalShareAmount = new BigDecimal(0);
//            for (OrderDetail orderDetail : list) {
//                totalShareAmount = totalShareAmount.add(orderDetail.getShareAmount());
//            }
//            OrderShare orderShare = orderShareService.lambdaQuery().eq(OrderShare::getOrderId, orderId).one();
//            if (orderShare != null) {
//                orderShare.setAmount(orderShare.getAmount().subtract(totalShareAmount));
//                orderShare.updateById();
//            }
//        }
//        log.info("【微信退款回调结束】{}", body);
//        return body;
//    }



    /**
     * 新增结算记录
     * @param orderInfo
     * @param list
     * @param flag  1=分销员带货  2=团购佣金
     */
    public void addOrderShare(OrderInfo orderInfo, List<OrderDetail> list,int flag){
        AdminCompanyWechat adminCompanyWechat = adminCompanyWechatService.getById(orderInfo.getCompanyWechatId());
        try {
            BigDecimal shareAmount = list.stream().map(OrderDetail::getShareAmount).reduce(BigDecimal::add).orElse(BigDecimal.valueOf(0));
            if (shareAmount.doubleValue() < 0) {
                return;
            }

            String remark = "分销员带货";
            OrderShare orderShare = new OrderShare();
            orderShare.setFlag(flag);
            //分账
            String workUserId = orderInfo.getWorkerId();
            if(StringUtils.isBlank(workUserId)){
                return;
            }
            List<User> workUserList = userService.lambdaQuery()
                    .eq(User::getUserId, workUserId)
                    .eq(User::getCompanyWechatId,orderInfo.getCompanyWechatId())
                    .list();
            if(workUserList.size() == 0){
                log.info("【结算团购】未找到分销员,分销员id:{}",workUserId);
                return;
            }
            User workUser = workUserList.get(0);
            orderShare.setWorkUserId(workUserId);
            if(StringUtils.equals(orderInfo.getSource(),OrderInfoSourceEnum.A.getRemark())) {
                orderShare.setOpenId(workUser.getMiniOpenId());
            }else{
                orderShare.setOpenId(workUser.getOpenId());
            }
            orderShare.setWorkUserName(orderInfo.getWorkerName());
            orderShare.setWorkUserPhone(orderInfo.getWorkerPhone());
            orderShare.setWebsitName(orderInfo.getWebsitName());
            orderShare.setWebsitNumber(orderInfo.getWebsitNumber());


            BigDecimal totalShareAmount = list.stream().map(OrderDetail::getShareAmount)
                    .reduce(BigDecimal::add).orElse(new BigDecimal(0));
            //新增待分账记录
            orderShare.setOrderId(orderInfo.getOrderId());
            orderShare.setStatus(OrderShareStatusEnum.ING.toString());
            orderShare.setAmount(totalShareAmount);
            orderShare.setTotalAmount(totalShareAmount);
            //扣除千分之六的手续费
            if(adminCompanyWechat.getIsShareTax()) {
                BigDecimal shareTax = totalShareAmount.multiply(BigDecimal.valueOf(0.006));
                if(shareTax.doubleValue() < 0.01 && shareTax.doubleValue() > 0){
                    shareTax = BigDecimal.valueOf(0.01);
                }
                orderShare.setHandleFees(shareTax);
                orderShare.setAmount(totalShareAmount.subtract(shareTax));
            }
            orderShare.setUserId(orderInfo.getUserId());
            orderShare.setUserName(orderInfo.getUserName());
            orderShare.setPhone(orderInfo.getPhone());
            orderShare.setPayment(orderInfo.getPayAmount());
            orderShare.setOrderStatus(orderInfo.getOrderStatus());
            orderShare.setTransactionId(orderInfo.getTransactionId());
            orderShare.setPosition(orderInfo.getPosition());
            orderShare.setPayTime(orderInfo.getPayTime());
            StringBuffer address = new StringBuffer();
            address.append(orderInfo.getProvince())
                    .append(orderInfo.getCity())
                    .append(orderInfo.getArea())
                    .append(orderInfo.getStreet())
                    .append(orderInfo.getReceAddress()).append(orderInfo.getHouseNo());
            orderShare.setAddress(address.toString());
            orderShare.setRemark(remark);

            orderShare.setCreateTime(new Date());
            orderShare.setCompanyWechatId(orderInfo.getCompanyWechatId());
            orderShare.setCompanyWechatName(orderInfo.getCompanyWechatName());
            orderShare.insert();

            log.info("新增结算记录成功{}",orderInfo.getOrderId());
        }catch(Exception e){
            log.error("结算添加失败", e);
        }
    }

    public void payCall2(String id, String transactionId, BigDecimal totalFee, Map<String, String> params) {
        String timeEnd = params.get("time_end");// 支付时间
        String openid = params.get("sub_openid");// opendid
        String mchId = params.get("mch_id");// 商户号
        String subMchId = params.get("sub_mch_id");// 子商户号
        String attach = params.get("attach");// 订单单号

        WebsitSales sales = websitSalesService.getById(attach);
        if (!sales.getPayFlag().equals("NO")) {
            log.info("请勿重复支付,orderId:{}", attach);
            return;
        }
        sales.setPayFlag("YES");
        sales.setFlag("PAY_NOT_TAKE");
        sales.setPayTime(DateUtil.parse(timeEnd, "yyyyMMddHHmmss"));
        sales.setPayNo(transactionId);

        //实际支付金额
        BigDecimal payAmount = sales.getTotalAmount();

        //判断金额是否支付正确
        if(totalFee.compareTo(payAmount) != 0){
            log.error("【支付回调严重bug】......orderId:{},微信回调金额:{},订单实际支付金额:{}", attach, totalFee, payAmount);
            return;
        }

        websitSalesService.lambdaUpdate()
                .set(WebsitSales::getPayFlag, sales.getPayFlag())
                .set(WebsitSales::getFlag, sales.getFlag())
                .set(WebsitSales::getPayTime, sales.getPayTime())
                .set(WebsitSales::getPayNo, sales.getPayNo())
                .eq(WebsitSales::getSalesId, attach)
                .update();

        // 生成现金支付记录
        WebsitSalesPayOrder order = new WebsitSalesPayOrder();
        order.setCompanyWechatId(sales.getCompanyWechatId());
        order.setCompanyWechatName(sales.getCompanyWechatName());
        order.setGoodsType(sales.getGoodsType());
        order.setWebsitId(sales.getWebsitId());
        order.setWebsitName(sales.getWebsitName());
        order.setOrderId(sales.getSalesId());
        order.setPayType("WECHAT");
        order.setPayFlag(sales.getPayFlag());
        order.setPayTime(sales.getPayTime());
        order.setPayValue(sales.getTotalAmount());
        order.setOrderType("S");
        order.setMchNo(mchId);
        order.setSubMchNo(subMchId);
        order.setOpenid(openid);
        order.setSource(sales.getSource());
        order.setOrderSource(sales.getGoodsType().equals(WebsitGoodsTypeEnum.M.toString()) ? "M_SALES" : "P_SALES");
        order.setTransactionId(transactionId);
        order.insert();

        if (sales.getSalesType().equals(WebsitSalesTypeEnum.ENGIN.getName())) {
            websitGoodsMangerLogic.givePrice(sales.getTotalAmount(), sales.getOrderEnginBaseId(), null, null, sales.getSalesId(), sales.getGoodsType());
            websitGoodsMangerLogic.upManage(sales.getOrderEnginBaseId(), sales.getGoodsType());
        }

        log.info("===============支付回调结束:{}==============", attach);
        //发货对接微信
        //wechatLogic.deliver(order.getCompanyWechatId(),transactionId,openid);
        sendMaterialExamineCall2(sales.getSalesId());
    }


    public void sendMaterialExamineCall2(String salesId) {

        WebsitSales sales = websitSalesService.getById(salesId);


        List<AdminUserWebsitRela> adminUserWebsitRelas = adminUserWebsitRelaService.lambdaQuery()
                .eq(AdminUserWebsitRela::getAdminWebsitId, sales.getWebsitId()).list();

        for (AdminUserWebsitRela adminUserWebsitRela : adminUserWebsitRelas) {
            AdminUser one = adminUserService.getById(adminUserWebsitRela.getAdminUserId());
            NoticeRecord noticeRecord = new NoticeRecord();
            noticeRecord.setNoticeId(sales.getSalesId());
            String format = DateUtil.format(new Date(), "yyyy-MM-dd");
            noticeRecord.setTitle("辅材购买成功"+"创建时间"+format+",已支付成功");
            noticeRecord.setContent("辅材购买成功"+"创建时间"+format+",已支付成功");
            noticeRecord.setType(NoticeEnum.B.getKey());
            noticeRecord.setNoticeType(NoticeTypeEnum.SYSTEM.getKey());
            noticeRecord.setIsNotice(IsYesNoEnum.YES.getKey());
            noticeRecord.setReadFlag(IsYesNoEnum.NO.getKey());
            noticeRecord.setAdminUserId(adminUserWebsitRela.getAdminUserId());
            noticeRecord.setAdminNickName(one.getNickName());
            noticeRecord.setIssueTime(new Date());
            noticeRecord.setAdminCompanyId(adminUserWebsitRela.getCompanyWechatId());
            noticeRecord.setAdminCompanyName(sales.getCompanyWechatName());
            noticeRecord.setAdminNoticeType(AdminNoticTypeEnum.CR_SALES.getKey());
            noticeRecord.setOrderId(sales.getSalesId());
            noticeRecord.setPaidType(sales.getGoodsType());
            noticeRecord.insert();
        }

        AdminUser one = adminUserService.lambdaQuery().eq(AdminUser::getCompanyWechatId, sales.getCompanyWechatId())
                .eq(AdminUser::getType, 1).last("limit 1").one();

        NoticeRecord noticeRecordCom = new NoticeRecord();
        noticeRecordCom.setNoticeId(sales.getSalesId());
        String format = DateUtil.format(new Date(), "yyyy-MM-dd");
        noticeRecordCom.setTitle("辅材购买成功"+"创建时间"+format+",已支付成功");
        noticeRecordCom.setContent("辅材购买成功"+"创建时间"+format+",已支付成功");
        noticeRecordCom.setType(NoticeEnum.B.getKey());
        noticeRecordCom.setNoticeType(NoticeTypeEnum.SYSTEM.getKey());
        noticeRecordCom.setIsNotice(IsYesNoEnum.YES.getKey());
        noticeRecordCom.setReadFlag(IsYesNoEnum.NO.getKey());
        noticeRecordCom.setAdminUserId(one.getAdminUserId());
        noticeRecordCom.setAdminNickName(one.getNickName());
        noticeRecordCom.setIssueTime(new Date());
        noticeRecordCom.setAdminCompanyId(one.getCompanyWechatId());
        noticeRecordCom.setAdminCompanyName(one.getCompanyName());
        noticeRecordCom.setAdminNoticeType(AdminNoticTypeEnum.CR_SALES.getKey());
        noticeRecordCom.setOrderId(sales.getSalesId());
        noticeRecordCom.setPaidType(sales.getGoodsType());
        noticeRecordCom.insert();

    }

    public void payCall3(String id, String transactionId, BigDecimal totalFee, Map<String, String> params) {
        String timeEnd = params.get("time_end");// 支付时间
        String openid = params.get("sub_openid");// opendid
        String mchId = params.get("mch_id");// 商户号
        String subMchId = params.get("sub_mch_id");// 子商户号
        String attach = params.get("attach");// 订单单号

        BuyServiceRecord record = buyServiceRecordService.getById(attach);
        if (record.getIsPay()) {
            log.info("请勿重复支付,id:{}", attach);
            return;
        }

        //实际支付金额
        BigDecimal payAmount = record.getPayAmount();

        //判断金额是否支付正确
        if(totalFee.compareTo(payAmount) != 0){
            log.error("【支付回调严重bug】......orderId:{},微信回调金额:{},订单实际支付金额:{}", attach, totalFee, payAmount);
            return;
        }

        BuyNormConfig config = buyNormConfigService.getById(record.getNormId());

        // 续费记录增加过期日期处理
//        if (record.getBuyMode().equals("续费")) {
            AdminCompanyWechat adminCompanyWechat = adminCompanyWechatService.lambdaQuery()
                    .eq(AdminCompanyWechat::getCompanyName, record.getCompanyName())
                    .one();

            if (Objects.nonNull(adminCompanyWechat)) {
                Date expireTime = adminCompanyWechat.getExpireTime();
                if (Objects.nonNull(expireTime)) {
                    DateTime offsetMonth = DateUtil.offsetMonth(expireTime, config.getMonth());
                    adminCompanyWechat.setExpireTime(offsetMonth)
                            .updateById();

                    record.setOpenTime(adminCompanyWechat.getCreateTime())
                            .setExpireTime(offsetMonth);
                }
            }
//        }

        record.setIsPay(true)
                .setPayTime(DateUtil.parse(timeEnd, "yyyyMMddHHmmss"))
                .setTransactionId(transactionId)
                .updateById();

        log.info("===============支付回调结束:{}==============", attach);
    }


    public void payCall4(String id, String transactionId, BigDecimal totalFee, Map<String, String> params) {
        String timeEnd = params.get("time_end");// 支付时间
        String openid = params.get("sub_openid");// opendid
        String mchId = params.get("mch_id");// 商户号
        String subMchId = params.get("sub_mch_id");// 子商户号
        String attach = params.get("attach");// 订单单号

        PgIncreOrder pgIncreOrder = pgIncreOrderService.getById(attach);
        if (pgIncreOrder.getPayStatus().equals(PayStatusEnum.PAID.getKey())) {
            log.info("请勿重复支付,id:{}", attach);
            return;
        }

        //实际支付金额
        BigDecimal payAmount = pgIncreOrder.getAmount();

        //判断金额是否支付正确
        if(totalFee.compareTo(payAmount) != 0){
            log.error("【支付回调严重bug】......orderId:{},微信回调金额:{},订单实际支付金额:{}", attach, totalFee, payAmount);
            return;
        }
        pgIncreOrder.setPayTime(new Date());
        pgIncreOrder.setPayStatus(PayStatusEnum.PAID.getKey());
        pgIncreOrder.setSettleStatus(OrderShareStatusEnum.ING.toString());
        if (pgIncreOrder.getOrderChannel().equals("SELF")) {
            BigDecimal websitProceAmount = pgIncreOrder.getAmount().multiply(Convert.toBigDecimal("0.006"));
            if (websitProceAmount.doubleValue() > 0.01) {
                websitProceAmount = websitProceAmount.setScale(2, BigDecimal.ROUND_HALF_UP);
            }else {
                websitProceAmount = Convert.toBigDecimal("0.01");
            }
            pgIncreOrder.setWebsitAmount(pgIncreOrder.getAmount().subtract(websitProceAmount));
            pgIncreOrder.setPayType(1);
            pgIncreOrder.setCommissionAmount(websitProceAmount);
            pgIncreOrder.setSettleStatus(OrderShareStatusEnum.OVER.toString());

        }else {
            pgIncreOrder.setPayType(2);
        }
        if (pgIncreOrder.getIncreType().equals(1)){
            pgIncreOrder.setServiceEndTime(DateUtil.offsetMonth(pgIncreOrder.getInsureTime(),pgIncreOrder.getLimitNum()*12));
        }
        pgIncreOrder.setWorkerOpenId(openid);
        pgIncreOrder.setPayNo(id);
        pgIncreOrder.setTranscationId(transactionId);

        pgIncreOrder.updateById();

        //自动发货对接微信(立即发货，腾讯那边会有延迟问题找不到订单，所以交给定时器处理)
        //wechatLogic.deliver(pgIncreOrder.getCompanyWechatId(),pgIncreOrder.getTranscationId(),pgIncreOrder.getWorkerOpenId());

        //订单支付成功的公众号通知
        wxPubNoticeLogic.addPaid(pgIncreOrder.getUserMobile(),pgIncreOrder.getCompanyWechatId(),pgIncreOrder.getId(),
                pgIncreOrder.getMainName()+pgIncreOrder.getIncreContent(), pgIncreOrder.getAmount(),
                pgIncreOrder.getUserName(),pgIncreOrder.getPayTime(),2);

        sendMaterialExamineIncre(pgIncreOrder.getId());
        log.info("===============支付回调结束:{}==============", attach);
    }


    public void sendMaterialExamineIncre(String orderId) {

        PgIncreOrder pgIncreOrder = pgIncreOrderService.getById(orderId);


        List<AdminUserWebsitRela> adminUserWebsitRelas = adminUserWebsitRelaService.lambdaQuery()
                .eq(AdminUserWebsitRela::getAdminWebsitId, pgIncreOrder.getWebsitId()).list();

        for (AdminUserWebsitRela adminUserWebsitRela : adminUserWebsitRelas) {
            AdminUser one = adminUserService.getById(adminUserWebsitRela.getAdminUserId());
            NoticeRecord noticeRecord = new NoticeRecord();
            noticeRecord.setNoticeId(pgIncreOrder.getId());
            String format = DateUtil.format(new Date(), "yyyy-MM-dd");
            noticeRecord.setTitle(pgIncreOrder.getIncreContent()+"创建时间"+format+",已支付成功");
            noticeRecord.setContent(pgIncreOrder.getIncreContent()+"创建时间"+format+",已支付成功");
            noticeRecord.setType(NoticeEnum.B.getKey());
            noticeRecord.setIsNotice(IsYesNoEnum.YES.getKey());
            noticeRecord.setReadFlag(IsYesNoEnum.NO.getKey());
            noticeRecord.setAdminUserId(adminUserWebsitRela.getAdminUserId());
            noticeRecord.setAdminNickName(one.getNickName());
            noticeRecord.setIssueTime(new Date());
            noticeRecord.setAdminCompanyId(adminUserWebsitRela.getCompanyWechatId());
            noticeRecord.setAdminCompanyName(pgIncreOrder.getCompanyWechatName());
            noticeRecord.setAdminNoticeType(AdminNoticTypeEnum.CR_SALES.getKey());
            noticeRecord.setOrderId(pgIncreOrder.getId());
            noticeRecord.setPaidType(OrderFlagEnum.YB.getKey());
            noticeRecord.insert();
        }

        AdminUser one = adminUserService.lambdaQuery().eq(AdminUser::getCompanyWechatId, pgIncreOrder.getCompanyWechatId())
                .eq(AdminUser::getType, 1).last("limit 1").one();

        NoticeRecord noticeRecordCom = new NoticeRecord();
        noticeRecordCom.setNoticeId(pgIncreOrder.getId());
        String format = DateUtil.format(new Date(), "yyyy-MM-dd");
        noticeRecordCom.setTitle(pgIncreOrder.getIncreContent()+"创建时间"+format+",已支付成功");
        noticeRecordCom.setContent(pgIncreOrder.getIncreContent()+"创建时间"+format+",已支付成功");
        noticeRecordCom.setType("B");
        noticeRecordCom.setIsNotice("YES");
        noticeRecordCom.setReadFlag("NO");
        noticeRecordCom.setAdminUserId(one.getAdminUserId());
        noticeRecordCom.setAdminNickName(one.getNickName());
        noticeRecordCom.setIssueTime(new Date());
        noticeRecordCom.setAdminCompanyId(one.getCompanyWechatId());
        noticeRecordCom.setAdminCompanyName(one.getCompanyName());
        noticeRecordCom.setAdminNoticeType(AdminNoticTypeEnum.CR_SALES.getKey());
        noticeRecordCom.setOrderId(pgIncreOrder.getId());
        noticeRecordCom.setPaidType(OrderFlagEnum.YB.getKey());
        noticeRecordCom.insert();

    }

    public void payCall5(String id, String transactionId, BigDecimal totalFee, Map<String, String> params) {
        String timeEnd = params.get("time_end");// 支付时间
        String openid = params.get("sub_openid");// opendid
        String attach = params.get("attach");// 订单单号

        final String[] splitOrderStr = attach.split("-");

        LeaseOrder order = leaseOrderService.getById(splitOrderStr[0]);
        if (order.getStatus().equals("WAIT") && order.getPayStatus()) {
            log.info("请勿重复支付,orderId:{}", attach);
            return;
        }
        LeaseOrderItem item = leaseOrderItemService.lambdaQuery()
                .eq(LeaseOrderItem::getLeaseOrderId, order.getId())
                .one();

        if (order.getStatus().equals("WAIT") && !order.getPayStatus()) {
            order.setPayStatus(true);
            LeaseOrderPayRecord record = leaseOrderPayRecordService.lambdaQuery()
                    .eq(LeaseOrderPayRecord::getLeaseOrderId, order.getId())
                    .eq(LeaseOrderPayRecord::getOrderType, "FIRST")
                    .eq(LeaseOrderPayRecord::getSort, splitOrderStr[1])
                    .one();

            //判断金额是否支付正确
            if(totalFee.compareTo(record.getPayValue()) != 0){
                log.error("【支付回调严重bug】......orderId:{},微信回调金额:{},订单实际支付金额:{}", attach, totalFee, record.getPayValue());
                return;
            }

            record.setPayStatus(true)
                    .setPayTime(DateUtil.parse(timeEnd, "yyyyMMddHHmmss"))
                    .setOpenid(openid)
                    .setTransactionId(transactionId)
                    .setStartDate(item.getStartDate())
                    .setEndDate(item.getEndDate())
                    .updateById();
        } else if ((order.getStatus().equals("LEASE") || order.getStatus().equals("OVER")) && order.getPayStatus()) {
            LeaseOrderPayRecord record = leaseOrderPayRecordService.lambdaQuery()
                    .eq(LeaseOrderPayRecord::getLeaseOrderId, order.getId())
                    .eq(LeaseOrderPayRecord::getOrderType, "RENEWAL")
                    .eq(LeaseOrderPayRecord::getSort, splitOrderStr[1])
                    .one();
            //判断金额是否支付正确
            if(totalFee.compareTo(record.getPayValue()) != 0){
                log.error("【支付回调严重bug】......orderId:{},微信回调金额:{},订单实际支付金额:{}", attach, totalFee, record.getPayValue());
                return;
            }

            record.setPayStatus(true)
                    .setPayTime(DateUtil.parse(timeEnd, "yyyyMMddHHmmss"))
                    .setOpenid(openid)
                    .setTransactionId(transactionId)
                    .updateById();

            long leaseRenewalDay = DateUtil.betweenDay(record.getStartDate(), record.getEndDate(), true) + 1;
            order.setTotalAmount(order.getTotalAmount().add(record.getPayValue()));
            item.setRealEndDate(record.getEndDate())
                    .setLeaseDay(Math.toIntExact(item.getLeaseDay() + leaseRenewalDay));
        } else {
            log.info("租赁商品支付场景未定义,orderId:{}", attach);
            return;
        }

        order.updateById();

        log.info("===============支付回调结束:{}==============", attach);
    }

    public void payCall6(String id, String transactionId, BigDecimal totalFee, Map<String, String> params) {

        String timeEnd = params.get("time_end");// 支付时间
        String openid = params.get("sub_openid");// opendid
        String mchId = params.get("mch_id");// 商户号
        String subMchId = params.get("sub_mch_id");// 子商户号
        String attach = params.get("attach");// 订单单号

        EsOrderInfo esOrderInfo = esOrderInfoService.getById(attach);
        if (esOrderInfo.getStatus().equals(PayStatusEnum.PAID.getKey())) {
            log.info("请勿重复支付,id:{}", attach);
            return;
        }

        //实际支付金额
        BigDecimal payAmount = esOrderInfo.getTotalAmount();

        //判断金额是否支付正确
        if(totalFee.compareTo(payAmount) != 0){
            log.error("【支付回调严重bug】......orderId:{},微信回调金额:{},订单实际支付金额:{}", attach, totalFee, payAmount);
            return;
        }
        esOrderInfo.setPayTime(new Date());
        esOrderInfo.setTransactionId(transactionId);
        esOrderInfo.setStatus(PayStatusEnum.PAID.getKey());
        esOrderInfo.setPayStatus(PayStatusEnum.PAID.getKey());

        EsGoods esGoods = esGoodsService.getById(esOrderInfo.getEsGoodsId());

        esGoods.setStatus(ESGoodsStatusEnum.SALE.getKey());

        esGoods.updateById();


        carouselMapService.lambdaUpdate().eq(CarouselMap::getGoodsId,esGoods.getId())
                .set(CarouselMap::getState,0).update();


        esOrderInfo.updateById();

        //自动发货对接微信(立即发货，腾讯那边会有延迟问题找不到订单，所以交给定时器处理)
        //wechatLogic.deliver(pgIncreOrder.getCompanyWechatId(),pgIncreOrder.getTranscationId(),pgIncreOrder.getWorkerOpenId());


        sendMaterialExamineEsOrder(esOrderInfo.getEsOrderId());

        //对接微信自动发货
        if(StringUtils.equals(esOrderInfo.getSource(),"小程序")) {
            addWechatAutoDeliver(esOrderInfo.getEsOrderId(), esOrderInfo.getCompanyWechatId(), esOrderInfo.getCompanyName(), esOrderInfo.getTransactionId(), openid);
        }

        log.info("===============支付回调结束:{}==============", attach);
    }



    public void sendMaterialExamineEsOrder(String orderId) {

        EsOrderInfo esOrderInfo = esOrderInfoService.getById(orderId);


        AdminUser one = adminUserService.lambdaQuery().eq(AdminUser::getCompanyWechatId, esOrderInfo.getCompanyWechatId())
                .eq(AdminUser::getType, 1).last("limit 1").one();

        NoticeRecord noticeRecordCom = new NoticeRecord();
        noticeRecordCom.setNoticeId(esOrderInfo.getEsOrderId());
        String format = DateUtil.format(new Date(), "yyyy-MM-dd");
        noticeRecordCom.setTitle(esOrderInfo.getEsGoodsName()+"创建时间"+format+",已支付成功");
        noticeRecordCom.setContent(esOrderInfo.getEsGoodsName()+"创建时间"+format+",已支付成功");
        noticeRecordCom.setType("B");
        noticeRecordCom.setIsNotice("YES");
        noticeRecordCom.setReadFlag("NO");
        noticeRecordCom.setAdminUserId(one.getAdminUserId());
        noticeRecordCom.setAdminNickName(one.getNickName());
        noticeRecordCom.setIssueTime(new Date());
        noticeRecordCom.setAdminCompanyId(one.getCompanyWechatId());
        noticeRecordCom.setAdminCompanyName(one.getCompanyName());
        noticeRecordCom.setAdminNoticeType(AdminNoticTypeEnum.CR_ES_SALES.getKey());
        noticeRecordCom.setOrderId(esOrderInfo.getEsOrderId());
        noticeRecordCom.setPaidType("ES");
        noticeRecordCom.insert();

    }


    /**
     * 新增对接微信待发货
     * @param orderId
     * @param companyWechatId
     * @param companyWechatName
     * @param transactionId
     * @param openId
     */
    public void addWechatAutoDeliver(String orderId,String companyWechatId,String companyWechatName,String transactionId,String openId){
        WechatAutoDeliver wechatAutoDeliver = new WechatAutoDeliver();
        wechatAutoDeliver.setOrderId(orderId);
        wechatAutoDeliver.setCompanyWechatId(companyWechatId);
        wechatAutoDeliver.setCompanyWechatName(companyWechatName);
        wechatAutoDeliver.setTransactionId(transactionId);
        wechatAutoDeliver.setOpenId(openId);
        wechatAutoDeliver.insert();
    }


    public void allinpayCallback(HttpServletRequest request) throws UnsupportedEncodingException {
        TreeMap<String, String> params = getParams(request);//动态遍历获取所有收到的参数,此步非常关键,因为收银宝以后可能会加字段,动态获取可以兼容
        log.info("通联回调: {} {}", params.get("trxid"), JSONUtil.toJsonStr(params));
    }

    /**
     * 动态遍历获取所有收到的参数,此步非常关键,因为收银宝以后可能会加字段,动态获取可以兼容由于收银宝加字段而引起的签名异常
     * @param request
     * @return
     */
    private TreeMap<String, String> getParams(HttpServletRequest request) throws UnsupportedEncodingException {
        request.setCharacterEncoding("UTF-8");//通知传输的编码为GBK
        TreeMap<String, String> map = new TreeMap<String, String>();
        Map reqMap = request.getParameterMap();
        for(Object key:reqMap.keySet()){
            String value = ((String[])reqMap.get(key))[0];
            map.put(key.toString(),value);
        }
        return map;
    }
}
