package com.sqx.modules.bl.order.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.google.common.collect.Lists;
import com.sqx.common.utils.DateUtils;
import com.sqx.common.utils.PageUtils;
import com.sqx.common.utils.Result;
import com.sqx.modules.app.dao.VipDetailsDao;
import com.sqx.modules.app.entity.*;
import com.sqx.modules.app.service.UserMoneyDetailsService;
import com.sqx.modules.app.service.UserMoneyService;
import com.sqx.modules.app.service.UserService;
import com.sqx.modules.app.service.UserVipService;
import com.sqx.modules.artificer.entity.Artificer;
import com.sqx.modules.artificer.entity.MassageType;
import com.sqx.modules.artificer.entity.Orders;
import com.sqx.modules.artificer.entity.OrdersMassage;
import com.sqx.modules.artificer.service.MassageTypeService;
import com.sqx.modules.bl.massage.dao.MassagePackageDetailDao;
import com.sqx.modules.bl.massage.entity.MassagePackage;
import com.sqx.modules.bl.massage.entity.MassagePackageDetail;
import com.sqx.modules.bl.massage.service.MassagePackageService;
import com.sqx.modules.bl.order.dao.UserPackageOrderDao;
import com.sqx.modules.bl.order.entity.UserPackage;
import com.sqx.modules.bl.order.entity.UserPackageDetail;
import com.sqx.modules.bl.order.entity.UserPackageOrder;
import com.sqx.modules.bl.order.entity.UserPackageOrdersMapping;
import com.sqx.modules.bl.order.service.UserPackageDetailService;
import com.sqx.modules.bl.order.service.UserPackageOrderService;
import com.sqx.modules.bl.order.service.UserPackageOrdersMappingService;
import com.sqx.modules.bl.order.service.UserPackageService;
import com.sqx.modules.common.service.CommonInfoService;
import com.sqx.modules.coupon.entity.CouponUser;
import com.sqx.modules.coupon.service.CouponUserService;
import com.sqx.modules.pay.controller.app.AliPayController;
import com.sqx.modules.pay.service.WxService;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.concurrent.locks.ReentrantReadWriteLock;

@Service
public class UserPackageOrderServiceImpl extends ServiceImpl<UserPackageOrderDao, UserPackageOrder> implements UserPackageOrderService {

    @Autowired
    UserVipService userVipService;

    @Autowired
    VipDetailsDao vipDetailsDao;

    @Autowired
    MassagePackageService massagePackageService;

    @Autowired
    CouponUserService couponUserService;

    @Autowired
    UserPackageService userPackageService;

    @Autowired
    UserPackageDetailService userPackageDetailService;

    @Autowired
    UserMoneyDetailsService userMoneyDetailsService;

    @Autowired
    UserMoneyService userMoneyService;

    @Autowired
    UserPackageOrdersMappingService userPackageOrdersMappingService;

    @Autowired
    MassagePackageDetailDao massagePackageDetailDao;

    @Autowired
    MassageTypeService massageTypeService;

    @Autowired
    private CommonInfoService commonInfoService;

    @Autowired
    private WxService wxService;

    @Autowired
    private AliPayController aliPayController;

    @Autowired
    private UserService userService;

    private ReentrantReadWriteLock reentrantReadWriteLock = new ReentrantReadWriteLock(true);

    @Override
    public Result findPage(UserPackageOrder userPackageOrder){
        Page<UserPackageOrder> pages=new Page<>(userPackageOrder.getPage(),userPackageOrder.getLimit());
        return Result.success().put("data",new PageUtils(baseMapper.findPage(pages,userPackageOrder)));
    }

    @Override
    public Result findCoupon(UserPackageOrder userPackageOrder){
        return Result.success().put("data",baseMapper.findCoupon(userPackageOrder));
    }

    @Override
    public void refund(UserPackageOrder userPackageOrder){
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        BigDecimal refundMoney = userPackageOrder.getRefundMoney();
        //获取钱包余额
        UserMoney userMoney = userMoneyService.selectUserMoneyByUserId(userPackageOrder.getUserId());
        BigDecimal money = userMoney.getMoney();
        money = money.add(refundMoney);
        userMoney.setMoney(money);
        //修改钱包流水明细
        UserMoneyDetails userMoneyDetails = new UserMoneyDetails();
        userMoneyDetails.setUserId(userPackageOrder.getUserId());
        userMoneyDetails.setTitle("订单退款");
        userMoneyDetails.setType(1);
        userMoneyDetails.setState(1);
        userMoneyDetails.setMoney(refundMoney);
        userMoneyDetails.setContent("订单号："+userPackageOrder.getOrdersNo()+",已退款到钱包！");
        userMoneyDetails.setCreateTime(sdf.format(new Date()));
        userMoneyDetails.setManipulateType(1);
        userMoneyDetails.setBalance(money);
        userMoneyDetails.setBlRole(1);
        userMoneyDetails.setBlFlag(1);
        userMoneyDetailsService.insert(userMoneyDetails);
        //修改钱包主表
        userMoneyService.updateMoney(userMoney);
        //修改订单表
        userPackageOrder.setRefundTime(sdf.format(new Date()));
        baseMapper.refund(userPackageOrder);
        UserPackage userPackage = new UserPackage();
        userPackage.setOrdersId(userPackageOrder.getOrdersId());
        userPackage.setStatus(2);
        userPackageService.updateStatusByOrder(userPackage);
    }

    @Override
    public Result selectOrdersDetails(Long ordersId){
        UserPackageOrder orders = baseMapper.selectById(ordersId);
        List<UserPackageOrdersMapping> ordersPackageList = userPackageOrdersMappingService.findListByOrdersId(ordersId);
        for (UserPackageOrdersMapping ordersPackage : ordersPackageList) {
            if(ordersPackage.getType() == 105 || ordersPackage.getType() == 106){
                MassagePackageDetail massagePackageDetail = massagePackageDetailDao.findCkLcDetailCount(ordersPackage.getPackageId());
                ordersPackage.setServiceCount(massagePackageDetail.getServiceCount());
                ordersPackage.setIntervalDaysStr(massagePackageDetail.getIntervalDaysStr());
            }
        }
        orders.setOrdersPackageList(ordersPackageList);
        return Result.success().put("data", orders);
    }

    @Override
    public Result insertOrders(UserPackageOrder userPackageOrder){
        reentrantReadWriteLock.writeLock().lock();
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        try {
            BigDecimal canCouponMoney = BigDecimal.ZERO;//当可用代金券时的金额
            BigDecimal canVipMoney = BigDecimal.ZERO;//当可用vip时的金额
            BigDecimal totalMoney = BigDecimal.ZERO;//总金额
            List<Long> classifyIdArr = Lists.newArrayList();
            List<UserPackageOrdersMapping> ordersPackageList = userPackageOrder.getOrdersPackageList();
            for (UserPackageOrdersMapping ordersPackage : ordersPackageList) {
                MassagePackage massagePackage = massagePackageService.getById(ordersPackage.getPackageId());
                BigDecimal sum = massagePackage.getPrice().multiply(new BigDecimal(ordersPackage.getNum()));
                if(massagePackage.getIsCanCoupon() == 1){
                    canCouponMoney = canCouponMoney.add(sum);
                }
                if(massagePackage.getIsCanVip() == 1){
                    canVipMoney = canVipMoney.add(sum);
                }
                totalMoney = totalMoney.add(sum);
                Long classifyId = massagePackage.getClassifyId();
                classifyIdArr.add(classifyId);
            }

            BigDecimal couponMinMoney = BigDecimal.ZERO;//所有代金券的使用额度总和
            List<CouponUser> CouponUserList = Lists.newArrayList();
            String couponIds = userPackageOrder.getCouponId();
            if(couponIds!=null && couponIds.length()>0){
                if(canCouponMoney.compareTo(BigDecimal.ZERO)==0){
                    return Result.error("此次购买的服务不支持优惠券！");
                }
                String[] couponArr = couponIds.trim().split(",");
                BigDecimal couponMoney = new BigDecimal(0);
                int count = 0;
                for(int i=0;i<couponArr.length;i++){
                    if(couponArr[i]!=null && !couponArr[i].equals("")){
                        Long couponId = Long.valueOf(couponArr[i]);
                        CouponUser couponUser = couponUserService.getById(couponId);
                        if (!couponUser.getStatus().equals(0)) {
                            return Result.error("优惠券已被使用！");
                        }
                        if(couponUser.getClassifyId()!=0){
                            if(!classifyIdArr.contains(couponUser.getClassifyId())){
                                return Result.error("优惠券不满足使用条件！");
                            }
                        }
                        couponMinMoney = couponMinMoney.add(couponUser.getMinMoney());
                        CouponUserList.add(couponUser);
                        BigDecimal money= couponUser.getMoney();
                        couponMoney = couponMoney.add(money);
                        count++;
                    }
                }
                userPackageOrder.setCouponCount(count);
                userPackageOrder.setCouponMoney(couponMoney);
            }else{
                userPackageOrder.setCouponCount(0);
                userPackageOrder.setCouponMoney(BigDecimal.ZERO);
            }

            if(canCouponMoney.compareTo(couponMinMoney) < 0){
                return Result.error("当前应付总金额不满足优惠券使用的最小额度，请重新选择优惠券！");
            }

            //获取用户VIP的优惠信息
            BigDecimal vipRate = new BigDecimal(100);
            //服务包支持vip时，获取vip优惠比例
            if(canVipMoney.compareTo(BigDecimal.ZERO)>0) {
                UserVip userVip = userVipService.selectUserVipByUserId(userPackageOrder.getUserId());
                if (userVip != null) {
                    if (userVip.getIsVip() == 1) {
                        //获取用户到期时间
                        Date date = null;
                        try {
                            date = simpleDateFormat.parse(userVip.getEndTime());
                            if (date.getTime() >= System.currentTimeMillis()) {
                                VipDetails vipDetails = vipDetailsDao.selectOne(new QueryWrapper<VipDetails>().eq("vip_name_type", userVip.getVipNameType()));
                                if (vipDetails != null) {
                                    vipRate = vipDetails.getRate();
                                }
                            }
                        } catch (Exception e) {
                            e.getMessage();
                        }
                    }
                }
            }
            userPackageOrder.setVipRate(vipRate);
            BigDecimal vipMoney = canVipMoney;
            BigDecimal unCanVipMoney = totalMoney.subtract(canVipMoney);//非会员优惠金额
            canVipMoney = canVipMoney.multiply(userPackageOrder.getVipRate()).divide(new BigDecimal(100));//对可用vip的金额进行优惠
            canVipMoney = canVipMoney.setScale(0,BigDecimal.ROUND_UP);
            BigDecimal vipReductionMoney = vipMoney.subtract(canVipMoney);
            userPackageOrder.setVipReductionMoney(vipReductionMoney);//会员减免金额
            totalMoney = canVipMoney.add(unCanVipMoney);//优惠后的总金额
            totalMoney = totalMoney.subtract(userPackageOrder.getCouponMoney());//减去优惠券额度后的总金额

            userPackageOrder.setPayMoney(totalMoney);
            userPackageOrder.setCreateTime(simpleDateFormat.format(new Date()));
            userPackageOrder.setStatus(0);
            userPackageOrder.setOrdersNo(getGeneralOrder());
            //插入订单表
            baseMapper.insertOrders(userPackageOrder);
            Long ordersId = userPackageOrder.getOrdersId();

            //插入订单代金券表
            if(CouponUserList.size()>0){
                for(int i=0;i<CouponUserList.size();i++){
                    CouponUser couponUser = CouponUserList.get(i);
                    UserPackageOrder upo = new UserPackageOrder();
                    upo.setOrdersId(ordersId);
                    upo.setUserCouponId(couponUser.getId());
                    upo.setCouponName(couponUser.getCouponName());
                    upo.setCouponMoney(couponUser.getMoney());
                    baseMapper.insertCoupon(upo);
                    //更新用户代金券表
                    couponUserService.update(Wrappers.<CouponUser>lambdaUpdate().eq(CouponUser::getId, couponUser.getId()).set(CouponUser::getStatus, 1));
                }
                userPackageOrder.setCouponUserList(CouponUserList);
            }

            //插入用户-服务包-订单-服务包与订单映射关系表
            for (UserPackageOrdersMapping ordersPackage : ordersPackageList) {
                ordersPackage.setOrdersId(ordersId);
                userPackageOrdersMappingService.insert(ordersPackage);
            }

        } catch (Exception e) {
            e.printStackTrace();
            log.error("添加订单异常" + e.getMessage(), e);
        } finally {
            reentrantReadWriteLock.writeLock().unlock();
        }
        return Result.success().put("data", userPackageOrder);
    }

    @Override
    @Transactional
    public Result payOrder(Long ordersId) {
        try {
            UserPackageOrder orders = baseMapper.getById(ordersId);
            if (orders == null) {
                return Result.error("订单生成失败，请重新下单！");
            }else if(orders.getStatus()==1){
                return Result.error("订单已支付！");
            }else if(orders.getStatus()==2){
                return Result.error("订单已退款！");
            }else if(orders.getStatus()==3){
                return Result.error("订单支付超时，请重新发起购买！");
            }
            SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

            UserMoney userMoney = userMoneyService.selectUserMoneyByUserId(orders.getUserId());
            if (userMoney.getMoney().doubleValue() < orders.getPayMoney().doubleValue()) {
                return Result.error("钱包余额不足，请充值！");
            }

            userMoneyService.updateMoney(2, orders.getUserId(), orders.getPayMoney().doubleValue());
            UserMoneyDetails userMoneyDetails = new UserMoneyDetails();
            //查询用户当前余额
            UserMoney userNowMoney = userMoneyService.selectUserMoneyByUserId(orders.getUserId());
            //插入余额
            userMoneyDetails.setBalance(userNowMoney.getMoney());
            //插入操作类型为已操作用户余额
            userMoneyDetails.setManipulateType(2);
            userMoneyDetails.setMoney(orders.getPayMoney());
            userMoneyDetails.setUserId(orders.getUserId());
            userMoneyDetails.setContent("订单号：" + orders.getOrdersNo() + ",已经下单成功！");
            userMoneyDetails.setTitle("支付服务包订单");
            userMoneyDetails.setType(2);
            userMoneyDetails.setState(2);
            userMoneyDetails.setCreateTime(simpleDateFormat.format(new Date()));
            userMoneyDetails.setBlRole(1);
            userMoneyDetails.setBlFlag(1);
            userMoneyDetailsService.insert(userMoneyDetails);

            orders.setStatus(1);
            orders.setPayWay(5);
            orders.setPayTime(simpleDateFormat.format(new Date()));
            baseMapper.updateStatus(orders);

            //获取订单-服务包映射关系列表
            List<UserPackageOrdersMapping> mappingList = userPackageOrdersMappingService.findListByOrdersId(ordersId);
            for (UserPackageOrdersMapping ordersPackage : mappingList) {
                int quantity = ordersPackage.getNum();
                MassagePackage massagePackage = massagePackageService.getById(ordersPackage.getPackageId());
                //修改服务包销量
                int sales = massagePackage.getSales();
                sales = sales+quantity;
                massagePackage.setSales(sales);
                massagePackageService.updateSales(massagePackage);
                for(int i=0;i<quantity;i++){
                    //拆分插入用户服务包
                    UserPackage userPackage = new UserPackage();
                    userPackage.setUserId(orders.getUserId());
                    userPackage.setPackageId(massagePackage.getId());
                    userPackage.setOrdersId(ordersId);
                    userPackage.setOrdersNo(orders.getOrdersNo());
                    userPackage.setCreateTime(simpleDateFormat.format(new Date()));
                    userPackage.setTitle(massagePackage.getTitle());
                    userPackage.setType(massagePackage.getType());
                    userPackage.setOldPrice(massagePackage.getOldPrice());
                    userPackage.setPrice(massagePackage.getPrice());
                    userPackage.setPackageImg(massagePackage.getPackageImg());
                    userPackage.setContent(massagePackage.getContent());
                    userPackage.setContentImg(massagePackage.getContentImg());
                    userPackage.setLabels(massagePackage.getLabels());
                    userPackage.setCity(massagePackage.getCity());
                    userPackage.setClassifyId(massagePackage.getClassifyId());
                    userPackage.setLevel(massagePackage.getLevel());
                    userPackageService.insert(userPackage);
                    Long mainId = userPackage.getId();
                    //拆分插入用户服务器项目详情
                    UserPackageDetail userPackageDetail = new UserPackageDetail();
                    userPackageDetail.setMainId(ordersPackage.getPackageId());
                    List<UserPackageDetail> userPackageDetailList = userPackageDetailService.findMassagePackageDetails(userPackageDetail);
                    if(userPackageDetailList.size()>0){
                        for(int j=0;j<userPackageDetailList.size();j++){
                            UserPackageDetail upd = userPackageDetailList.get(j);
                            upd.setMainId(mainId);
                            upd.setCreateTime(simpleDateFormat.format(new Date()));
                            upd.setLevel(massagePackage.getLevel());
                            int serviceCount = upd.getServiceCount();
                            for(int k=0;k<serviceCount;k++){
                                userPackageDetailService.insert(upd);
                                updateMassageSale(upd.getMassageTypeId());
                            }
                        }
                    }
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
            log.error("钱包支付服务包订单异常：" + e.getMessage(), e);
            return Result.error();
        }
        return Result.success();
    }

    private void updateMassageSale(Long massageTypeId){
        MassageType massageType = massageTypeService.getById(massageTypeId);
        massageType.setSales(massageType.getSales()+1);
        massageTypeService.updateById(massageType);
    }

    @Override
    public Result findUserPackageOrders(UserPackageOrder userPackageOrder){
        Page<UserPackageOrder> pages=new Page<>(userPackageOrder.getPage(),userPackageOrder.getLimit());
        return Result.success().put("data", baseMapper.findUserPackageOrders(pages,userPackageOrder));
    }

    /**
     * 获取拼团订单团号和拼团人数
     * @param id
     * @param status
     * @return
     */
    @Override
    public List<UserPackageOrder> getActivityOrderList(Long id,Integer status){
        return baseMapper.getActivityOrderList(id,status);
    }

    /**
     * 获取拼团订单信息
     * @param groupNo
     * @return
     */
    @Override
    public List<UserPackageOrder> getActivityOrderListByGroupNo(String groupNo){
        return baseMapper.getActivityOrderListByGroupNo(groupNo,null);
    }

    @Override
    @Transactional
    public Result insertGroupOrders(UserPackageOrder userPackageOrder){
        try {
            Long userId = userPackageOrder.getUserId();
            String groupNo = userPackageOrder.getGroupNo();
            int isNewer = userPackageOrder.getIsNewer();
            String startTimeStr = userPackageOrder.getStartTime();
            String endTimeStr = userPackageOrder.getEndTime();
            Date startTime = DateUtils.stringToDate(startTimeStr,"yyyy-MM-dd HH:mm:ss");
            Date endTime = DateUtils.stringToDate(endTimeStr,"yyyy-MM-dd HH:mm:ss");
            if(startTime.getTime()>System.currentTimeMillis()){
                return Result.error("团购还未开始，请稍后重试！");
            }
            if(endTime.getTime()<System.currentTimeMillis()){
                return Result.error("团购已结束，无法进行团购！");
            }
            if(isNewer == 1){
                //只限新用户
                UserEntity user = userService.selectUserById(userId);
                String createTimeStr = user.getCreateTime();
                Date createTime = DateUtils.addDateDays(DateUtils.stringToDate(createTimeStr,"yyyy-MM-dd HH:mm:ss"),7);
                if(createTime.getTime()<System.currentTimeMillis()){
                    return Result.error("该团购只限新用户，请选择其他团购！");
                }
            }
            if(groupNo != null && !groupNo.equals("")){
                List<UserPackageOrder> list = baseMapper.getActivityOrderListByGroupNo(groupNo,userId);
                if(list.size()>0){
                    for(UserPackageOrder orders : list){
                        if(orders.getStatus().equals(1) || orders.getStatus().equals(4)){
                            return Result.error("您已参与此团购，无法重复参加！");
                        }
                        //取消代金券
                        if (orders.getCouponId() != null) {
                            String couponIds = orders.getCouponId();
                            if(couponIds.length()>0) {
                                String[] couponArr = couponIds.trim().split(",");
                                for(int i=0;i<couponArr.length;i++){
                                    if(couponArr[i]!=null && !couponArr[i].equals("")){
                                        Long couponId = Long.valueOf(couponArr[i]);
                                        CouponUser couponUser = couponUserService.getById(couponId);
                                        if (couponUser != null && couponUser.getStatus().equals(1)) {
                                            couponUser.setStatus(0);
                                            couponUserService.updateById(couponUser);
                                        }
                                    }
                                }
                            }
                        }
                        //删除订单项目
                        userPackageOrdersMappingService.deleteByOrdersId(orders.getOrdersId());
                        //删除订单
                        baseMapper.deleteById(orders.getOrdersId());
                    }
                }
            }
            BigDecimal canCouponMoney = BigDecimal.ZERO;//当可用代金券时的金额
            BigDecimal canVipMoney = BigDecimal.ZERO;//当可用vip时的金额
            BigDecimal totalMoney = BigDecimal.ZERO;//总金额
            List<Long> classifyIdArr = Lists.newArrayList();
            List<UserPackageOrdersMapping> ordersPackageList = userPackageOrder.getOrdersPackageList();
            for (UserPackageOrdersMapping ordersPackage : ordersPackageList) {
                MassagePackage massagePackage = massagePackageService.getById(ordersPackage.getPackageId());
                BigDecimal sum = massagePackage.getPrice().multiply(new BigDecimal(ordersPackage.getNum()));
                sum = sum.setScale(0,BigDecimal.ROUND_UP);
                if(massagePackage.getIsCanCoupon() == 1){
                    canCouponMoney = canCouponMoney.add(sum);
                }
                if(massagePackage.getIsCanVip() == 1){
                    canVipMoney = canVipMoney.add(sum);
                }
                totalMoney = totalMoney.add(sum);
                Long classifyId = massagePackage.getClassifyId();
                classifyIdArr.add(classifyId);
            }

            BigDecimal couponMinMoney = BigDecimal.ZERO;//所有代金券的使用额度总和
            List<CouponUser> CouponUserList = Lists.newArrayList();
            String couponIds = userPackageOrder.getCouponId();
            if(couponIds!=null && couponIds.length()>0){
                if(canCouponMoney.compareTo(BigDecimal.ZERO)==0){
                    return Result.error("此次团购不支持优惠券！");
                }
                String[] couponArr = couponIds.trim().split(",");
                BigDecimal couponMoney = new BigDecimal(0);
                int count = 0;
                for(int i=0;i<couponArr.length;i++){
                    if(couponArr[i]!=null && !couponArr[i].equals("")){
                        Long couponId = Long.valueOf(couponArr[i]);
                        CouponUser couponUser = couponUserService.getById(couponId);
                        if (!couponUser.getStatus().equals(0)) {
                            return Result.error("优惠券已被使用！");
                        }
                        if(couponUser.getClassifyId()!=0){
                            if(!classifyIdArr.contains(couponUser.getClassifyId())){
                                return Result.error("优惠券不满足使用条件！");
                            }
                        }
                        couponMinMoney = couponMinMoney.add(couponUser.getMinMoney());
                        CouponUserList.add(couponUser);
                        BigDecimal money= couponUser.getMoney();
                        couponMoney = couponMoney.add(money);
                        count++;
                    }
                }
                userPackageOrder.setCouponCount(count);
                userPackageOrder.setCouponMoney(couponMoney);
            }else{
                userPackageOrder.setCouponCount(0);
                userPackageOrder.setCouponMoney(BigDecimal.ZERO);
            }
            if(canCouponMoney.compareTo(couponMinMoney) < 0){
                return Result.error("当前应付总金额不满足优惠券使用的最小额度，请重新选择优惠券！");
            }
            //获取用户VIP的优惠信息
            BigDecimal vipRate = new BigDecimal(100);
            //服务包支持vip时，获取vip优惠比例
            if(canVipMoney.compareTo(BigDecimal.ZERO)>0) {
                UserVip userVip = userVipService.selectUserVipByUserId(userPackageOrder.getUserId());
                if (userVip != null) {
                    if (userVip.getIsVip() == 1) {
                        //获取用户到期时间
                        Date date = DateUtils.stringToDate(userVip.getEndTime(),"yyyy-MM-dd HH:mm:ss");
                        if (date.getTime() >= System.currentTimeMillis()) {
                            VipDetails vipDetails = vipDetailsDao.selectOne(new QueryWrapper<VipDetails>().eq("vip_name_type", userVip.getVipNameType()));
                            if (vipDetails != null) {
                                vipRate = vipDetails.getRate();
                            }
                        }
                    }
                }
            }
            userPackageOrder.setVipRate(vipRate);
            BigDecimal vipMoney = canVipMoney;
            BigDecimal unCanVipMoney = totalMoney.subtract(canVipMoney);//非会员优惠金额
            canVipMoney = canVipMoney.multiply(userPackageOrder.getVipRate()).divide(new BigDecimal(100));//对可用vip的金额进行优惠
            canVipMoney = canVipMoney.setScale(0,BigDecimal.ROUND_UP);
            BigDecimal vipReductionMoney = vipMoney.subtract(canVipMoney);
            userPackageOrder.setVipReductionMoney(vipReductionMoney);//会员减免金额
            totalMoney = canVipMoney.add(unCanVipMoney);//优惠后的总金额
            totalMoney = totalMoney.subtract(userPackageOrder.getCouponMoney());//减去优惠券额度后的总金额
            userPackageOrder.setPayMoney(totalMoney);
            userPackageOrder.setCreateTime(DateUtils.format(new Date()));
            userPackageOrder.setStatus(0);
            if(groupNo != null && !groupNo.equals("")){
                userPackageOrder.setGroupNo(groupNo);
            }else{
                userPackageOrder.setGroupNo(getGeneralGroupNo());
            }
            userPackageOrder.setOrdersNo(getGeneralOrder());
            //插入订单表
            baseMapper.insertOrders(userPackageOrder);
            Long ordersId = userPackageOrder.getOrdersId();
            //插入订单代金券表
            if(CouponUserList.size()>0){
                for(int i=0;i<CouponUserList.size();i++){
                    CouponUser couponUser = CouponUserList.get(i);
                    UserPackageOrder upo = new UserPackageOrder();
                    upo.setOrdersId(ordersId);
                    upo.setUserCouponId(couponUser.getId());
                    upo.setCouponName(couponUser.getCouponName());
                    upo.setCouponMoney(couponUser.getMoney());
                    baseMapper.insertCoupon(upo);
                    //更新用户代金券表
                    couponUserService.update(Wrappers.<CouponUser>lambdaUpdate().eq(CouponUser::getId, couponUser.getId()).set(CouponUser::getStatus, 1));
                }
                userPackageOrder.setCouponUserList(CouponUserList);
            }
            //插入用户-服务包-订单-服务包与订单映射关系表
            for (UserPackageOrdersMapping ordersPackage : ordersPackageList) {
                ordersPackage.setOrdersId(ordersId);
                userPackageOrdersMappingService.insert(ordersPackage);
            }
        } catch (Exception e) {
            e.printStackTrace();
            log.error("添加订单异常" + e.getMessage(), e);
        }
        return Result.success().put("data", userPackageOrder);
    }

    @Override
    @Transactional
    public Result payGroupOrders(Long ordersId) {
        try {
            UserPackageOrder orders = baseMapper.getById(ordersId);
            if (orders == null) {
                return Result.error("订单生成失败，请重新下单！");
            }else if(orders.getStatus()==1){
                return Result.error("订单已支付！");
            }else if(orders.getStatus()==2){
                return Result.error("订单已退款！");
            }else if(orders.getStatus()==3){
                return Result.error("订单支付超时，请重新发起购买！");
            }
            UserMoney userMoney = userMoneyService.selectUserMoneyByUserId(orders.getUserId());
            if (userMoney.getMoney().doubleValue() < orders.getPayMoney().doubleValue()) {
                return Result.error("钱包余额不足，请充值！");
            }
            userMoneyService.updateMoney(2, orders.getUserId(), orders.getPayMoney().doubleValue());
            UserMoneyDetails userMoneyDetails = new UserMoneyDetails();
            //查询用户当前余额
            UserMoney userNowMoney = userMoneyService.selectUserMoneyByUserId(orders.getUserId());
            //插入余额
            userMoneyDetails.setBalance(userNowMoney.getMoney());
            //插入操作类型为已操作用户余额
            userMoneyDetails.setManipulateType(2);
            userMoneyDetails.setMoney(orders.getPayMoney());
            userMoneyDetails.setUserId(orders.getUserId());
            userMoneyDetails.setContent("订单号：" + orders.getOrdersNo() + ",已经下单成功！");
            userMoneyDetails.setTitle("支付服务包订单");
            userMoneyDetails.setType(2);
            userMoneyDetails.setState(2);
            userMoneyDetails.setCreateTime(DateUtils.format(new Date()));
            userMoneyDetails.setBlRole(1);
            userMoneyDetails.setBlFlag(1);
            userMoneyDetailsService.insert(userMoneyDetails);
            orders.setStatus(4);//团购中
            orders.setPayWay(5);
            orders.setPayTime(DateUtils.format(new Date()));
            baseMapper.updateStatus(orders);
            //获取支付已支付的数量是否满足此次团购人数，是则完成此次拼团，并将商品发送给客户
            int buyGroupNum = 0;
            int groupNum = 0;
            List<UserPackageOrder> list = baseMapper.getActivityOrderListByGroupNo(orders.getGroupNo(),null);
            if(list.size()>0){
                for(UserPackageOrder userPackageOrder : list) {
                    if (userPackageOrder.getStatus().equals(1) || userPackageOrder.getStatus().equals(4)) {
                        buyGroupNum++;
                    }
                }
            }
            MassagePackage massagePackage = null;
            List<UserPackageOrdersMapping> mappingList = userPackageOrdersMappingService.findListByOrdersId(ordersId);
            if(mappingList.size()>0){
                Long packageId = mappingList.get(0).getPackageId();
                massagePackage = massagePackageService.getById(packageId);
                groupNum = massagePackage.getGroupNum();
            }
            if(buyGroupNum>0 && groupNum>0 && buyGroupNum>=groupNum){
                for(UserPackageOrder userPackageOrder : list) {
                    if (userPackageOrder.getStatus().equals(1) || userPackageOrder.getStatus().equals(4)) {
                        //删除单据防止重复数据
                        List<UserPackage> userPackageList = userPackageService.findList(userPackageOrder.getOrdersId());
                        if(userPackageList.size()>0){
                            for(UserPackage userPackage : userPackageList){
                                userPackageService.removeById(userPackage.getId());
                                userPackageDetailService.deleteDetailByMain(userPackage.getId());
                            }
                        }
                        //插入单据
                        List<UserPackageOrdersMapping> packageOrderMappingList = userPackageOrdersMappingService.findListByOrdersId(userPackageOrder.getOrdersId());
                        for (UserPackageOrdersMapping ordersPackage : packageOrderMappingList) {
                            int quantity = ordersPackage.getNum();
                            for(int i=0;i<quantity;i++){
                                //拆分插入用户团购
                                UserPackage userPackage = new UserPackage();
                                userPackage.setUserId(userPackageOrder.getUserId());
                                userPackage.setPackageId(massagePackage.getId());
                                userPackage.setOrdersId(userPackageOrder.getOrdersId());
                                userPackage.setOrdersNo(userPackageOrder.getOrdersNo());
                                userPackage.setCreateTime(DateUtils.format(new Date()));
                                userPackage.setTitle(massagePackage.getTitle());
                                userPackage.setType(massagePackage.getType());
                                userPackage.setOldPrice(massagePackage.getOldPrice());
                                userPackage.setPrice(massagePackage.getPrice());
                                userPackage.setPackageImg(massagePackage.getPackageImg());
                                userPackage.setContent(massagePackage.getContent());
                                userPackage.setContentImg(massagePackage.getContentImg());
                                userPackage.setLabels(massagePackage.getLabels());
                                userPackage.setCity(massagePackage.getCity());
                                userPackage.setClassifyId(massagePackage.getClassifyId());
                                userPackage.setLevel(massagePackage.getLevel());
                                userPackageService.insert(userPackage);
                                Long mainId = userPackage.getId();
                                //拆分插入用户服务器项目详情
                                UserPackageDetail userPackageDetail = new UserPackageDetail();
                                userPackageDetail.setMainId(ordersPackage.getPackageId());
                                List<UserPackageDetail> userPackageDetailList = userPackageDetailService.findMassagePackageDetails(userPackageDetail);
                                if(userPackageDetailList.size()>0){
                                    for(int j=0;j<userPackageDetailList.size();j++){
                                        UserPackageDetail upd = userPackageDetailList.get(j);
                                        upd.setMainId(mainId);
                                        upd.setCreateTime(DateUtils.format(new Date()));
                                        upd.setLevel(massagePackage.getLevel());
                                        int serviceCount = upd.getServiceCount();
                                        for(int k=0;k<serviceCount;k++){
                                            userPackageDetailService.insert(upd);
                                            updateMassageSale(upd.getMassageTypeId());
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
                //完成团购
                UserPackageOrder packageOrder = new UserPackageOrder();
                packageOrder.setGroupNo(orders.getGroupNo());
                packageOrder.setStatus(1);
                baseMapper.updateStatusByGroupNo(packageOrder);
                //修改团购销量
                int sales = massagePackage.getSales();
                sales = sales+1;
                massagePackage.setSales(sales);
                massagePackageService.updateSales(massagePackage);
            }
        } catch (Exception e) {
            e.printStackTrace();
            log.error("钱包支付服务包订单异常：" + e.getMessage(), e);
            return Result.error("钱包支付服务包订单异常!");
        }
        return Result.success();
    }

    @Override
    @Transactional
    public Result insertFlashOrders(UserPackageOrder userPackageOrder){
        try {
            Long userId = userPackageOrder.getUserId();
            String startTimeStr = userPackageOrder.getStartTime();
            String endTimeStr = userPackageOrder.getEndTime();
            int isNewer = userPackageOrder.getIsNewer();
            Date startTime = DateUtils.stringToDate(startTimeStr,"yyyy-MM-dd HH:mm:ss");
            Date endTime = DateUtils.stringToDate(endTimeStr,"yyyy-MM-dd HH:mm:ss");
            if(startTime.getTime()>System.currentTimeMillis()){
                return Result.error("限时秒杀还未开始，请稍后重试！");
            }
            if(endTime.getTime()<System.currentTimeMillis()){
                return Result.error("限时秒杀已结束，无法进行限时秒杀！");
            }
            if(isNewer == 1){
                //只限新用户
                UserEntity user = userService.selectUserById(userId);
                String createTimeStr = user.getCreateTime();
                Date createTime = DateUtils.addDateDays(DateUtils.stringToDate(createTimeStr,"yyyy-MM-dd HH:mm:ss"),7);
                if(createTime.getTime()<System.currentTimeMillis()){
                    return Result.error("该限时秒杀只限新用户，请选择其他限时秒杀！");
                }
            }
            BigDecimal canCouponMoney = BigDecimal.ZERO;//当可用代金券时的金额
            BigDecimal canVipMoney = BigDecimal.ZERO;//当可用vip时的金额
            BigDecimal totalMoney = BigDecimal.ZERO;//总金额
            List<Long> classifyIdArr = Lists.newArrayList();
            List<UserPackageOrdersMapping> ordersPackageList = userPackageOrder.getOrdersPackageList();
            for (UserPackageOrdersMapping ordersPackage : ordersPackageList) {
                MassagePackage massagePackage = massagePackageService.getById(ordersPackage.getPackageId());
                BigDecimal sum = massagePackage.getPrice().multiply(new BigDecimal(ordersPackage.getNum()));
                sum = sum.setScale(0,BigDecimal.ROUND_UP);
                if(massagePackage.getIsCanCoupon() == 1){
                    canCouponMoney = canCouponMoney.add(sum);
                }
                if(massagePackage.getIsCanVip() == 1){
                    canVipMoney = canVipMoney.add(sum);
                }
                totalMoney = totalMoney.add(sum);
                Long classifyId = massagePackage.getClassifyId();
                classifyIdArr.add(classifyId);
            }
            BigDecimal couponMinMoney = BigDecimal.ZERO;//所有代金券的使用额度总和
            List<CouponUser> CouponUserList = Lists.newArrayList();
            String couponIds = userPackageOrder.getCouponId();
            if(couponIds!=null && couponIds.length()>0){
                if(canCouponMoney.compareTo(BigDecimal.ZERO)==0){
                    return Result.error("此次限时秒杀不支持优惠券！");
                }
                String[] couponArr = couponIds.trim().split(",");
                BigDecimal couponMoney = new BigDecimal(0);
                int count = 0;
                for(int i=0;i<couponArr.length;i++){
                    if(couponArr[i]!=null && !couponArr[i].equals("")){
                        Long couponId = Long.valueOf(couponArr[i]);
                        CouponUser couponUser = couponUserService.getById(couponId);
                        if (!couponUser.getStatus().equals(0)) {
                            return Result.error("优惠券已被使用！");
                        }
                        if(couponUser.getClassifyId()!=0){
                            if(!classifyIdArr.contains(couponUser.getClassifyId())){
                                return Result.error("优惠券不满足使用条件！");
                            }
                        }
                        couponMinMoney = couponMinMoney.add(couponUser.getMinMoney());
                        CouponUserList.add(couponUser);
                        BigDecimal money= couponUser.getMoney();
                        couponMoney = couponMoney.add(money);
                        count++;
                    }
                }
                userPackageOrder.setCouponCount(count);
                userPackageOrder.setCouponMoney(couponMoney);
            }else{
                userPackageOrder.setCouponCount(0);
                userPackageOrder.setCouponMoney(BigDecimal.ZERO);
            }
            if(canCouponMoney.compareTo(couponMinMoney) < 0){
                return Result.error("当前应付总金额不满足优惠券使用的最小额度，请重新选择优惠券！");
            }
            //获取用户VIP的优惠信息
            BigDecimal vipRate = new BigDecimal(100);
            //服务包支持vip时，获取vip优惠比例
            if(canVipMoney.compareTo(BigDecimal.ZERO)>0) {
                UserVip userVip = userVipService.selectUserVipByUserId(userPackageOrder.getUserId());
                if (userVip != null) {
                    if (userVip.getIsVip() == 1) {
                        //获取用户到期时间
                        Date date = DateUtils.stringToDate(userVip.getEndTime(),"yyyy-MM-dd HH:mm:ss");
                        if (date.getTime() >= System.currentTimeMillis()) {
                            VipDetails vipDetails = vipDetailsDao.selectOne(new QueryWrapper<VipDetails>().eq("vip_name_type", userVip.getVipNameType()));
                            if (vipDetails != null) {
                                vipRate = vipDetails.getRate();
                            }
                        }
                    }
                }
            }
            userPackageOrder.setVipRate(vipRate);
            BigDecimal vipMoney = canVipMoney;
            BigDecimal unCanVipMoney = totalMoney.subtract(canVipMoney);//非会员优惠金额
            canVipMoney = canVipMoney.multiply(userPackageOrder.getVipRate()).divide(new BigDecimal(100));//对可用vip的金额进行优惠
            canVipMoney = canVipMoney.setScale(0,BigDecimal.ROUND_UP);
            BigDecimal vipReductionMoney = vipMoney.subtract(canVipMoney);
            userPackageOrder.setVipReductionMoney(vipReductionMoney);//会员减免金额
            totalMoney = canVipMoney.add(unCanVipMoney);//优惠后的总金额
            totalMoney = totalMoney.subtract(userPackageOrder.getCouponMoney());//减去优惠券额度后的总金额
            userPackageOrder.setPayMoney(totalMoney);
            userPackageOrder.setCreateTime(DateUtils.format(new Date()));
            userPackageOrder.setStatus(0);
            userPackageOrder.setOrdersNo(getGeneralOrder());
            //插入订单表
            baseMapper.insertOrders(userPackageOrder);
            Long ordersId = userPackageOrder.getOrdersId();
            //插入订单代金券表
            if(CouponUserList.size()>0){
                for(int i=0;i<CouponUserList.size();i++){
                    CouponUser couponUser = CouponUserList.get(i);
                    UserPackageOrder upo = new UserPackageOrder();
                    upo.setOrdersId(ordersId);
                    upo.setUserCouponId(couponUser.getId());
                    upo.setCouponName(couponUser.getCouponName());
                    upo.setCouponMoney(couponUser.getMoney());
                    baseMapper.insertCoupon(upo);
                    //更新用户代金券表
                    couponUserService.update(Wrappers.<CouponUser>lambdaUpdate().eq(CouponUser::getId, couponUser.getId()).set(CouponUser::getStatus, 1));
                }
                userPackageOrder.setCouponUserList(CouponUserList);
            }
            //插入用户-服务包-订单-服务包与订单映射关系表
            for (UserPackageOrdersMapping ordersPackage : ordersPackageList) {
                ordersPackage.setOrdersId(ordersId);
                userPackageOrdersMappingService.insert(ordersPackage);
            }
        } catch (Exception e) {
            e.printStackTrace();
            log.error("添加订单异常" + e.getMessage(), e);
        }
        return Result.success().put("data", userPackageOrder);
    }

    /**
     * 每5分钟自动扫描未支付订单，进行取消，释放代金券
     */
    @Scheduled(cron = "0 0/5 * * * ?")
    public void autoCancelOrders() {
        String value1 = commonInfoService.findOne(388).getValue();
        List<UserPackageOrder> ordersList = baseMapper.selectOrdersStatusByTime(value1);
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        for (UserPackageOrder orders : ordersList) {
            //取消订单
            orders.setStatus(3);//取消状态
            orders.setPayTime(simpleDateFormat.format(new Date()));//取消时间
            baseMapper.updateById(orders);
            //取消代金券
            if (orders.getCouponId() != null) {
                String couponIds = orders.getCouponId();
                if(couponIds.length()>0) {
                    String[] couponArr = couponIds.trim().split(",");
                    for(int i=0;i<couponArr.length;i++){
                        if(couponArr[i]!=null && !couponArr[i].equals("")){
                            Long couponId = Long.valueOf(couponArr[i]);
                            CouponUser couponUser = couponUserService.getById(couponId);
                            if (couponUser != null && couponUser.getStatus().equals(1)) {
                                couponUser.setStatus(0);
                                couponUserService.updateById(couponUser);
                            }
                        }
                    }
                }
            }
        }
    }

    /**
     * 每5分钟自动扫描未成团的订单，进行退款，释放代金券
     */
    @Scheduled(cron = "0 0/5 * * * ?")
    public void autoRefundGroupOrders() {
        List<UserPackageOrder> ordersList = baseMapper.getUnGroupOrderList();
        for (UserPackageOrder orders : ordersList) {
            BigDecimal userMoney = orders.getPayMoney();
            //取消订单
            orders.setStatus(2);//取消状态
            orders.setRefundTime(DateUtils.format(new Date()));//取消时间
            orders.setRefundMoney(userMoney);
            baseMapper.updateById(orders);
            //取消代金券
            if (orders.getCouponId() != null) {
                String couponIds = orders.getCouponId();
                if(couponIds.length()>0) {
                    String[] couponArr = couponIds.trim().split(",");
                    for(int i=0;i<couponArr.length;i++){
                        if(couponArr[i]!=null && !couponArr[i].equals("")){
                            Long couponId = Long.valueOf(couponArr[i]);
                            CouponUser couponUser = couponUserService.getById(couponId);
                            if (couponUser != null && couponUser.getStatus().equals(1)) {
                                couponUser.setStatus(0);
                                couponUserService.updateById(couponUser);
                            }
                        }
                    }
                }
            }
            UserMoneyDetails userMoneyDetails = new UserMoneyDetails();
            if (orders.getPayWay() == 1 || orders.getPayWay() == 2 || orders.getPayWay() == 3 || orders.getPayWay() == 4) {
                if(userMoney.compareTo(BigDecimal.ZERO) > 0){
                    boolean refund = wxService.refund(orders.getOrdersNo(), orders.getPayMoney(), userMoney, orders.getPayWay());
                    if (!refund) {
                        log.error("订单号："+orders.getOrdersNo()+"团购订单支付宝退款失败！");
                        continue;
                    }
                }
                userMoneyDetails.setManipulateType(1);
                userMoneyDetails.setBlFlag(2);
            } else if (orders.getPayWay() == 6) {
                if(userMoney.compareTo(BigDecimal.ZERO) > 0) {
                    String data = aliPayController.alipayRefund(orders.getOrdersNo(), userMoney);
                    if (StringUtils.isNotBlank(data)) {
                        log.error(data);
                        JSONObject jsonObject = JSON.parseObject(data);
                        JSONObject alipay_trade_refund_response = jsonObject.getJSONObject("alipay_trade_refund_response");
                        String code1 = alipay_trade_refund_response.getString("code");
                        if (!"10000".equals(code1)) {
                            log.error("订单号："+orders.getOrdersNo()+"团购订单微信退款失败！");
                            continue;
                        }
                    } else {
                        log.error("订单号："+orders.getOrdersNo()+"团购订单微信退款失败！");
                        continue;
                    }
                }
                userMoneyDetails.setManipulateType(1);
                userMoneyDetails.setBlFlag(2);
            } else {
                userMoneyService.updateMoney(1, orders.getUserId(), userMoney.doubleValue());
                //查询用户当前余额
                UserMoney userNowMoney = userMoneyService.selectUserMoneyByUserId(orders.getUserId());
                //插入余额
                userMoneyDetails.setBalance(userNowMoney.getMoney());
                //插入操作类型为已操作用户余额
                userMoneyDetails.setManipulateType(2);
                userMoneyDetails.setBlFlag(1);
            }
            userMoneyDetails.setMoney(userMoney);
            userMoneyDetails.setUserId(orders.getUserId());
            userMoneyDetails.setContent("订单号：" + orders.getOrdersNo() + ",已原路退款！");
            userMoneyDetails.setTitle("团购订单退款");
            userMoneyDetails.setType(1);
            userMoneyDetails.setState(2);
            userMoneyDetails.setCreateTime(DateUtils.format(new Date()));
            userMoneyDetails.setBlRole(1);
            userMoneyDetailsService.save(userMoneyDetails);
        }
    }

    public String getGeneralOrder() {
        Date date = new Date();
        String newString = String.format("%0" + 4 + "d", (int) ((Math.random() * 9 + 1) * 1000));
        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss");
        String format = sdf.format(date);
        return format + newString;
    }

    public String getGeneralGroupNo() {
        Date date = new Date();
        String newString = String.format("%0" + 4 + "d", (int) ((Math.random() * 9 + 1) * 1000));
        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss");
        String format = sdf.format(date);
        return "G"+format + newString;
    }

}