package com.hai.order.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.hai.common.exception.ErrorCode;
import com.hai.common.exception.ErrorHelp;
import com.hai.common.exception.SysCode;
import com.hai.config.*;
import com.hai.dao.HighGasOrderPushMapper;
import com.hai.entity.*;
import com.hai.enum_type.*;
import com.hai.goods.service.GoodsOrderExtService;
import com.hai.goods.service.GoodsPresentService;
import com.hai.msg.entity.MsgTopic;
import com.hai.order.service.OrderPaySuccessService;
import com.hai.order.service.OrderService;
import com.hai.order.topic.OrderTopic;
import com.hai.order.type.*;
import com.hai.service.*;
import org.apache.rocketmq.client.producer.SendCallback;
import org.apache.rocketmq.client.producer.SendResult;
import org.apache.rocketmq.spring.core.RocketMQTemplate;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.integration.support.MessageBuilder;
import org.springframework.messaging.Message;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.*;

/**
 * @className: OrderPaySuccessServiceImpl
 * @author: HuRui
 * @date: 2022/8/29
 **/
@Service("orderPaySuccessService")
public class OrderPaySuccessServiceImpl implements OrderPaySuccessService {

    @Resource
    private RedisTemplate redisTemplate;

    @Resource
    private RocketMQTemplate rocketMQTemplate;

    @Resource
    private OrderService orderService;

    @Resource
    private HighOrderPreService orderPreService;

    @Resource
    private HighMerchantStoreService merchantStoreService;

    @Resource
    private HighCouponService couponService;

    @Resource
    private HighCouponCodeService couponCodeService;

    @Resource
    private HighUserService userService;

    @Resource
    private HighGasOrderService gasOrderService;

    @Resource
    private ShellGroupService shellGroupService;

    @Resource
    private JinZhuJiaYouService jinZhuJiaYouService;



    @Resource
    private PayloService payloService;

    @Resource
    private GoodsOrderExtService goodsOrderExtService;

    @Resource
    private HighDiscountPackageDiscountActualService discountPackageDiscountActualService;

    @Resource
    private HighDiscountPackageActualService discountPackageActualService;

    @Resource
    private HighDiscountPackageService discountPackageService;

    @Resource
    private HighDiscountPackageRecordService discountPackageRecordService;

    @Resource
    private HighDiscountUserRelService highDiscountUserRelService;

    @Resource
    private ApiMemberProductService apiMemberProductService;

    @Resource
    private BsMsgService bsMsgService;

    @Resource
    private OutRechargeOrderService outRechargeOrderService;

    @Resource
    private GoodsPresentService presentService;



    @Override
    public HighOrder orderPaySuccessHandle(String orderNo, OrderPayType payType, String paySerialNo, BigDecimal payRealPrice, HighUserCard userCard) {
        HighOrder order = orderService.getOrderDetailByNo(orderNo);
        try {
            if (order != null) {
                order.setPaySerialNo(paySerialNo);
                order.setPayRealPrice(payRealPrice);
                order.setPayTime(new Date());
                order.setPayType(payType != null?payType.getNumber():null);

                if (order.getProductType().equals(OrderProductType.PRODUCT_TYPE6.getNumber())) {
                    order.setOrderStatus(OrderStatusEnum.type3.getType());
                } else {
                    order.setOrderStatus(OrderStatusEnum.type2.getType());
                }

                if (userCard != null) {
                    order.setMemCardId(userCard.getId());
                    order.setMemCardNo(userCard.getCardNo());
                    order.setMemCardType(userCard.getType());
                }
                for (HighChildOrder childOrder : order.getHighChildOrderList()) {
                    childOrder.setPayTime(new Date());
                    childOrder.setChildOrderStatus(OrderChildStatus.STATUS2.getNumber());
                }
                orderService.updateOrderData(order);

                // 分账业务
                if (order.getProfitSharingStatus() == true) {
                    // 延迟3分钟
                    Message<HighOrder> rocketMsg = MessageBuilder.withPayload(order).build();
                    rocketMQTemplate.syncSend(OrderTopic.ORDER_TOPIC_PROFIT_SHARING.getTopic(), rocketMsg, 1000,7);
                }

                // 处理订单产品业务
                orderBusHandle(order);

                // 推送消息
                pushUserMsg(order.getId() , OrderProductType.getDataByType(order.getProductType()).getName() +"下单支付成功");

            }
            return order;

        } catch (Exception e) {
            if (order != null) {
                order.setExceptionStatus(true);
                order.setExceptionContent(e.getMessage());
                orderService.updateOrderData(order);
            }
            return order;
        }
    }

    @Async
    public void pushUserMsg(Long order, String title) throws Exception {
        bsMsgService.pushUserMsg(order , title , 2);
    }

    /**
     * 订单业务处理
     * @param order
     * @throws Exception
     */
    @Transactional(
            propagation= Propagation.REQUIRED,
            isolation = Isolation.READ_COMMITTED,
            timeout = 20,
            rollbackFor = Exception.class)
    public void orderBusHandle(HighOrder order) throws Exception {

        // 子订单存在多个情况下订单处理
        if (order.getProductType().equals(OrderProductType.PRODUCT_TYPE1.getNumber()) || order.getProductType().equals(OrderProductType.PRODUCT_TYPE2.getNumber())) {
            if (order.getHighChildOrderList().get(0).getGoodsType().equals(OrderChildGoodsType.TYPE4.getNumber())) {
                kfcHandle(order.getHighChildOrderList().get(0).getChannelOrderNo());
            } else if (order.getHighChildOrderList().get(0).getGoodsType().equals(OrderChildGoodsType.TYPE9.getNumber())) {
                starbucksOrderHandle(order.getHighChildOrderList().get(0).getChannelOrderNo());
            }
        }

        for (HighChildOrder childOrder : order.getHighChildOrderList()) {
            if (childOrder.getGoodsType().equals(OrderChildGoodsType.TYPE1.getNumber())) {
                childOrder.setChildOrderStatus(OrderChildStatus.STATUS3.getNumber());
                couponHandle(order, childOrder);

            } else if (childOrder.getGoodsType().equals(OrderChildGoodsType.TYPE2.getNumber())) {
                order.setOrderStatus(OrderStatus.STATUS3.getNumber());
                order.setFinishTime(new Date());
                integralHandle(order,childOrder);

                childOrder.setChildOrderStatus(OrderChildStatus.STATUS3.getNumber());
                orderService.updateOrderData(order);

            } else if (childOrder.getGoodsType().equals(OrderChildGoodsType.TYPE3.getNumber())) {
                order.setOrderStatus(OrderStatus.STATUS3.getNumber());
                order.setFinishTime(new Date());
                oilHandle(order,childOrder);

                childOrder.setChildOrderStatus(OrderChildStatus.STATUS3.getNumber());
                orderService.updateOrderData(order);

            } else if (childOrder.getGoodsType().equals(OrderChildGoodsType.TYPE4.getNumber())) {

            } else if (childOrder.getGoodsType().equals(OrderChildGoodsType.TYPE5.getNumber())) {

            } else if (childOrder.getGoodsType().equals(OrderChildGoodsType.TYPE6.getNumber())) {
                mobileRecharge(order);
            } else if (childOrder.getGoodsType().equals(OrderChildGoodsType.TYPE7.getNumber())) {
                eCouponPackageHandle(order , childOrder);
            } else if (childOrder.getGoodsType().equals(OrderChildGoodsType.TYPE8.getNumber())) {
                hltUnionCardRechargeHandle(order , childOrder);
            } else if (childOrder.getGoodsType().equals(OrderChildGoodsType.TYPE9.getNumber())) {

            } else if (childOrder.getGoodsType().equals(OrderChildGoodsType.TYPE10.getNumber())) {
                thirdOrderHandle(order);
            } else if (childOrder.getGoodsType().equals(OrderChildGoodsType.TYPE11.getNumber())) {
                goodsRecharge(order , childOrder);
            }
        }
    }

    /**
     * 卡券业务
     * @param order
     * @param childOrder
     * @throws Exception
     */
    public void couponHandle(HighOrder order,HighChildOrder childOrder) throws Exception {
        HighCoupon coupon = couponService.getCouponById(childOrder.getGoodsId());
        // 是否预约
        if (coupon.getReserveStatus()) {
            HighOrderPre orderPre = new HighOrderPre();
            orderPre.setCompanyId(coupon.getCompanyId());
            orderPre.setMerchantId(coupon.getMerchantId());
            orderPre.setMerchantStoreId(childOrder.getStoreId());
            orderPre.setPreOrderNo(System.currentTimeMillis()+"");
            orderPre.setOrderId(order.getId());
            orderPre.setOrderNo(order.getOrderNo());
            orderPre.setChildOrderId(childOrder.getId());
            orderPre.setPayRealPrice(order.getPayRealPrice());
            orderPre.setGoodsType(1);
            orderPre.setGoodsName(coupon.getCouponName());
            orderPre.setGoodsId(coupon.getId());
            orderPre.setPreUserId(order.getMemId());
            orderPre.setPreUserName(order.getMemName());
            orderPre.setPreUserPhone(order.getMemPhone());
            orderPre.setPreUserRemark(order.getRemarks());
            orderPre.setStatus(1);
            orderPreService.insertOrderPre(orderPre);
        }

        // 支付购买卡券
        couponCodeService.payCoupon(order,childOrder,coupon);

    }

    /**
     * 积分充值业务
     * @param order
     * @param childOrder
     */
    public void integralHandle(HighOrder order,HighChildOrder childOrder) {
        // 金币 1：100
        Integer goldNum = new BigDecimal(childOrder.getTotalPrice().toString()).multiply(new BigDecimal("100")).intValue();
        String remark = "订单" + order.getOrderNo() + "积分充值积分：" +  goldNum;
        userService.goldHandle(childOrder.getGoodsId(), goldNum, 1, 1, childOrder.getId() , remark , order.getOrderNo());
    }

    /**
     * 加油业务
     * @param order
     * @param childOrder
     */
    public void oilHandle(HighOrder order,HighChildOrder childOrder) throws Exception {
        // 查询加油订单
        HighGasOrder gasOrder = gasOrderService.getDetailByChildOrderNo(childOrder.getChildOrderNo());
        if (gasOrder != null) {
            gasOrder.setMemCardType(order.getMemCardType());
            gasOrder.setMemCardNo(order.getMemCardNo());
            gasOrder.setPayTime(new Date());
            gasOrder.setStatus(OrderOilStatus.STATUS2.getNumber());
            gasOrder.setPayType(order.getPayType());
            gasOrder.setPayPrice(order.getPayPrice());
            gasOrderService.updateGasOrder(gasOrder);

            // 查询油站
            HighMerchantStore store = merchantStoreService.getDetailById(gasOrder.getStoreId());
            if (store == null) {
                throw ErrorHelp.genException(SysCode.System, ErrorCode.COMMON_ERROR, "未找到门店");
            }
            if (gasOrder.getChannelType().equals(MerchantStoreSourceType.type1.getNumber())) {
                // 预存类型  0：非预存  1：预存门店
                if (store.getPrestoreType() != null && store.getPrestoreType().equals(1)) {
                    Map<String, Object> pushParam = new HashMap<>();
                    pushParam.put("businessType", MerStoreAmountTypeEnum.type2.getType());
                    pushParam.put("storeId", childOrder.getGoodsId());
                    pushParam.put("price", order.getTotalPrice());
                    pushParam.put("sourceType", MerStoreAmountSourceTypeEnum.type2.getType());
                    pushParam.put("sourceId", order.getId());
                    pushParam.put("sourceContent", "订单号：" + order.getOrderNo() + ",加油金额：￥" + order.getTotalPrice());
                    pushParam.put("opUserId", order.getMemId());
                    pushParam.put("opUserName", order.getMemName());
                    // 扣预存款
                    this.redisTemplate.boundListOps(MsgTopic.MerStoreAccount.getName()).leftPush(pushParam);
                }

            } else if (gasOrder.getChannelType().equals(MerchantStoreSourceType.type2.getNumber())) {
                // 推送团油订单
                Map<String, Object> paramMap = new HashMap<>();
                paramMap.put("gasId", store.getStoreKey());
                paramMap.put("oilNo", gasOrder.getGasOilNo());
                paramMap.put("gunNo", gasOrder.getGasGunNo());
                paramMap.put("priceGun", gasOrder.getGasPriceGun());  // 枪单价
                paramMap.put("priceVip", gasOrder.getGasPriceVip());  // 优惠价
                paramMap.put("driverPhone", gasOrder.getMemPhone());
                paramMap.put("thirdSerialNo", gasOrder.getOrderNo());
                paramMap.put("refuelingAmount", gasOrder.getGasRefuelPrice());

                // 油品类型 1:汽油:2:柴油;3:天然气
                if (gasOrder.getGasOilType() == 1) {
                    paramMap.put("accountNo", CommonSysConst.getSysConfig().getTuanYouGasolineAccount());
                } else if (gasOrder.getGasOilType() == 2) {
                    paramMap.put("accountNo", CommonSysConst.getSysConfig().getTuanYouDieselAccount());
                }
                JSONObject orderPushObject = TuanYouConfig.refuelingOrderPush(paramMap);
                if (orderPushObject != null && orderPushObject.getString("code").equals("200")) {
                    gasOrder.setChannelOrderNo(orderPushObject.getJSONObject("result").getString("orderNo"));
                }

            } else if (gasOrder.getChannelType().equals(MerchantStoreSourceType.type3.getNumber())) {
                // 推送加好油
                shellGroupService.gasSyncPayment(gasOrder.getOrderNo(),
                        store.getStoreKey(),
                        gasOrder.getPayTime(),
                        order.getTotalPrice(),
                        gasOrder.getGasOilNo(),
                        gasOrder.getGasGunNo(),
                        order.getPayablePrice(),
                        order.getTotalDeductionPrice()
                );

            } else if (gasOrder.getChannelType().equals(MerchantStoreSourceType.type4.getNumber())) {
                // 推送金猪加油
                jinZhuJiaYouService.payOrder(order.getOrderNo(), gasOrder.getGasPriceChannelPay());

            } else if (gasOrder.getChannelType().equals(MerchantStoreSourceType.type5.getNumber())) {
                // 推送paylo四川壳牌
                payloService.syncYcShellPaymentNotify(order.getOrderNo(),
                        store.getStoreKey(),
                        gasOrder.getPayTime(),
                        order.getTotalPrice(),
                        gasOrder.getGasOilNo(),
                        gasOrder.getGasGunNo(),
                        order.getPayablePrice(),
                        order.getTotalDeductionPrice()
                );
            }
        }
    }

    /**
     * @Author Sum1Dream
     * @Name kfcHandle
     * @Description // 肯德基订单操作
     * @Date 14:59 2022/10/24
     * @Param [order]
     * @Return void
     */
    private void kfcHandle(String channelOrderNo) throws Exception {

        // 支付给千猪
        QianZhuConfig.payKfcOrder(channelOrderNo);
        // 推送订单记录
//        HighGasOrderPush highGasOrderPush = new HighGasOrderPush();
//        highGasOrderPush.setType(OrderPushType.type3.getType());
//        highGasOrderPush.setOrderNo(order.getOrderNo());
//        highGasOrderPush.setCreateTime(new Date());
//        highGasOrderPush.setRequestContent(order.getOrderNo());
//        highGasOrderPush.setReturnContent(object.toJSONString());
//        highGasOrderPushMapper.insert(highGasOrderPush);
    }

    /**
     * @Author Sum1Dream
     * @Name eCouponPackage
     * @Description // 优惠券包订单操作
     * @Date 16:15 2022/10/24
     * @Param [order]
     * @Return void
     */
    private void eCouponPackageHandle(HighOrder order , HighChildOrder highChildOrder) throws Exception {
        HighDiscountPackageActual actual = discountPackageActualService.getDetailByChildOrderNo(highChildOrder.getChildOrderNo());
        if (actual != null) {
            List<HighDiscountPackageDiscountActual> discountList = discountPackageDiscountActualService.getHighDiscountPackageDiscountActualList(actual.getId());
            for (HighDiscountPackageDiscountActual discount : discountList) {
                highDiscountUserRelService.receiveDiscount(order.getMemId(), discount.getAgentDiscountCodeId());
            }
            HighDiscountPackage discountPackage = discountPackageService.findDiscountPackageById(actual.getDiscountPackageId());
            HighDiscountPackageRecord record = new HighDiscountPackageRecord();
            record.setDiscountPackageId(discountPackage.getId());
            record.setDiscountPackageTitle(discountPackage.getTitle());
            record.setUsingAttribution(discountPackage.getUsingAttribution());
            record.setCompanyId(discountPackage.getCompanyId());
            record.setOrderId(order.getId().intValue());
            record.setChildOrderId(highChildOrder.getId().intValue());
            record.setRecordNo(System.currentTimeMillis()+"");
            record.setSalesType(1);
            record.setPrice(order.getPayPrice());
            record.setUserId(order.getMemId().intValue());
            discountPackageRecordService.insertRecord(record);
            actual.setAllocationTime(new Date());
            actual.setStatus(3);  // 状态： 1: 待分配 2:预分配（售卖）3:已分配
            discountPackageActualService.updateHighDiscountPackageActual(actual);
        }
    }

    /**
     * @Author Sum1Dream
     * @Name hltUnionCardRechargeHandle
     * @Description // 汇联通充值订单操作
     * @Date 16:26 2022/10/24
     * @Param [order]
     * @Return void
     */
    private void hltUnionCardRechargeHandle(HighOrder order , HighChildOrder highChildOrder) throws Exception {
        // 汇联通充值
        String goodsDesc = "汇联通充值"+order.getPayPrice()+"元";
        String tranDesc = "";
        String businessType = "ghk_deposit";

        // 汇联通卡充值
        JSONObject deposit = HuiLianTongUnionCardConfig.deposit(order.getOrderNo(), highChildOrder.getGoodsSpecName(), order.getPayPrice(), businessType, order.getPaySerialNo(), goodsDesc);

        // 汇联通充值回调解析
        HuiLianTongUnionCardConfig.resolveResponse(deposit.getString("data"));

    }

    /**
     * @Author Sum1Dream
     * @Name starbucksOrderHandle
     * @Description // 星巴克订单操作
     * @Date 17:04 2022/10/24
     * @Param [order]
     * @Return void
     */
    private void starbucksOrderHandle(String channelOrderNo) throws Exception {
        // 订单支付
        QianZhuConfig.starbucksOrdersPay(channelOrderNo);
    }

    /**
     * @Author Sum1Dream
     * @Name thirdOrderHandle
     * @Description // 第三方会员充值订单操作
     * @Date 17:06 2022/10/24
     * @Param [order]
     * @Return void
     */
    private void thirdOrderHandle(HighOrder order) throws Exception {

        // 下单
        ApiMemberProduct memberProduct = apiMemberProductService.findById(order.getHighChildOrderList().get(0).getGoodsId());

        QianZhuConfig.insertV2(memberProduct.getProductId() , order.getOrderNo() , order.getRemarks());

    }


    /**
     * @Author Sum1Dream
     * @Name mobileRecharge
     * @Description // 话费订单操作
     * @Date 13:46 2022/11/2
     * @Param [order]
     * @Return void
     */
    private void mobileRecharge(HighOrder order) {
        OutRechargeOrder outRechargeOrder = outRechargeOrderService.findByOrderNo(order.getOrderNo());
        if (outRechargeOrder.getPayStatus() == null) {
            if (order.getProductType().equals(9)) {
                outRechargeOrderService.editOutRechargeOrder(order , outRechargeOrder);
            }
        }
        outRechargeOrderService.getPrepaidRechargeApi(outRechargeOrder);
    }

    /**
     * @Author Sum1Dream
     * @Name goodsRecharge
     * @Description // 实物商品订单操作
     * @Date 17:13 2023/4/20
     * @Param [order]
     * @Return void
     */
    private void goodsRecharge(HighOrder order , HighChildOrder highChildOrder) {
        GoodsOrder goodsOrder = goodsOrderExtService.findGoodsOrder(order.getOrderNo());
        goodsOrder.setUpdateTime(new Date());
        goodsOrder.setStatus("1");
        goodsOrderExtService.updateGoodsOrder(goodsOrder);
        presentService.presentUser(order , highChildOrder);
    }

}
