package com.kxs.system.biz.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.LocalDateTimeUtil;
import cn.hutool.core.util.NumberUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.metadata.IPage;
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.kxs.common.core.constant.SecurityConstants;
import com.kxs.common.core.constant.enums.ErrorTypeEnum;
import com.kxs.common.core.exception.GlobalCustomerException;
import com.kxs.common.core.util.R;
import com.kxs.common.core.util.RetOps;
import com.kxs.common.security.util.SecurityUtils;
import com.kxs.product.api.feign.RemoteKxsProductService;
import com.kxs.system.api.feign.RemoteOldService;
import com.kxs.system.api.model.KxsCampUser;
import com.kxs.system.api.vo.admin.CampUserExcelVO;
import com.kxs.system.api.vo.kxsapp.camp.CampGetByIdVO;
import com.kxs.system.api.vo.kxsapp.camp.CampPageVO;
import com.kxs.system.api.amqp.rabbit.RabbitOrderQueueMQ;
import com.kxs.system.biz.constant.enums.CampStatusEnum;
import com.kxs.system.biz.constant.enums.SysErrorTypeEnum;
import com.kxs.system.biz.mapper.KxsCampMapper;
import com.kxs.system.api.model.KxsCamp;
import com.kxs.system.biz.service.KxsCampService;
import com.kxs.system.biz.service.KxsCampUserService;
import com.kxs.user.api.feign.RemoteKxsUserService;
import com.kxs.user.api.model.KxsUser;
import com.pig4cloud.plugin.excel.vo.ErrorMessage;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.stereotype.Service;
import org.springframework.validation.BindingResult;

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

/**
 * 训练营(KxsCamp)表服务实现类
 *
 * @author 系统
 * @since 2024-04-08 15:44:02
 */
@Service("kxsCampService")
@RequiredArgsConstructor
@EnableAsync
@Slf4j
public class KxsCampServiceImpl extends ServiceImpl<KxsCampMapper, KxsCamp> implements KxsCampService {

    private final RemoteKxsUserService remoteKxsUserService;

    private final RemoteKxsProductService remoteKxsProductService;

    private final RemoteOldService remoteOldService;


    private final KxsCampUserService kxsCampUserService;


    @Override
    public R addData(KxsCamp param) {

        R<KxsUser> kxsUserR = remoteKxsUserService.loadUserById(param.getCreateUserId(), SecurityConstants.FROM_IN);
        KxsUser user = RetOps.of(kxsUserR)
                .getData()
                .orElseThrow(() -> new GlobalCustomerException(ErrorTypeEnum.USER_NOT_FOUND.getDescription()));

        param.setCreateUsername(user.getUsername());
        param.setCreateCode(user.getUserCode());

        return R.ok(baseMapper.insert(param));
    }

    @Override
    public R updateData(KxsCamp param) {

        if (param.getId() == null) {
            return R.failed(SysErrorTypeEnum.PARAM_ERROR.getDescription());
        }
        KxsCamp kxsCamp = baseMapper.selectById(param.getId());
        if (kxsCamp == null) {
            return R.failed(SysErrorTypeEnum.NOT_DATA.getDescription());
        }

        R<KxsUser> kxsUserR = remoteKxsUserService.loadUserById(param.getCreateUserId(), SecurityConstants.FROM_IN);
        KxsUser user = RetOps.of(kxsUserR)
                .getData()
                .orElseThrow(() -> new GlobalCustomerException(ErrorTypeEnum.USER_NOT_FOUND.getDescription()));

        param.setCreateUsername(user.getUsername());
        param.setCreateCode(user.getUserCode());

        return R.ok(baseMapper.updateById(param));
    }

    @Override
    public R importUserData(List<CampUserExcelVO> campUserExcelVOList, BindingResult bindingResult) {

        if (campUserExcelVOList.isEmpty()) {
            return R.failed(SysErrorTypeEnum.IMPORT_EMPTY.getDescription());
        }

        //查询正在进行中的活动
        LocalDateTime now = LocalDateTime.now();

        // 通用校验获取失败的数据
        List<ErrorMessage> errorMessageList = (List<ErrorMessage>) bindingResult.getTarget();
        // 执行数据插入操作
        for (CampUserExcelVO excel : campUserExcelVOList) {
            Set<String> errorMsg = new HashSet<>();
            //查询用户
            R<KxsUser> kxsUserR = remoteKxsUserService.loadUserByCode(excel.getUserCode(), SecurityConstants.FROM_IN);
            KxsUser user = RetOps.of(kxsUserR)
                    .getData()
                    .orElse(null);
            KxsCamp kxsCamp = baseMapper.selectById(excel.getCampId());
            if (kxsCamp == null) {
                return R.failed(excel.getCampId() + "训练营编号不存在，请重新上传！");
            }

            if (Objects.isNull(user)) {
                errorMsg.add(excel.getUserCode() + "创客未找到！");
            } else {
                if (user.getRealStatus() != 1) {
                    errorMsg.add(excel.getUserCode() + "创客未实名！");
                }
                //判断创客是否已在其他训练营
                KxsCampUser kxsCampUser = baseMapper.selectByUserId(user.getId(), now);
                if (kxsCampUser != null) {
                    errorMsg.add(excel.getUserCode() + "已在训练营！");
                }
            }

            //判断创客是否加入
//            KxsCampUser kxsCampUser = kxsCampUserService.getOne(Wrappers.<KxsCampUser>lambdaQuery()
//                    .eq(KxsCampUser::getCampId, excel.getCampId())
//                    .eq(KxsCampUser::getUserId, user.getId()));

            // 数据合法情况
            if (CollUtil.isEmpty(errorMsg)) {
                KxsCampUser campUser = new KxsCampUser();
                campUser.setCampId(excel.getCampId());
                campUser.setUserId(user.getId());
                campUser.setUsername(user.getUsername());
                campUser.setUserCode(user.getUserCode());
                kxsCampUserService.save(campUser);
            } else {
                // 数据不合法
                errorMessageList.add(new ErrorMessage(excel.getLineNum(), errorMsg));
            }
        }
        //刷新参与人数
        List<KxsCamp> kxsCamps = baseMapper.selectList(Wrappers.<KxsCamp>lambdaQuery().lt(KxsCamp::getStatus, CampStatusEnum.STATUS_END.getType()));
        for (KxsCamp kxsCamp : kxsCamps) {
            long count = kxsCampUserService.count(Wrappers.<KxsCampUser>lambdaQuery().eq(KxsCampUser::getCampId, kxsCamp.getId()));
            baseMapper.update(null, Wrappers.<KxsCamp>lambdaUpdate().set(KxsCamp::getUserNum, count).eq(KxsCamp::getId, kxsCamp.getId()));
        }
        if (CollUtil.isNotEmpty(errorMessageList)) {
            return R.failed(JSON.toJSONString(errorMessageList));
        }

        return R.ok();
    }

    @Override
    public IPage<CampPageVO> getByPage(Page<CampPageVO> page) {
        LocalDateTime now = LocalDateTime.now();
        Long userId = SecurityUtils.getUser().getId();
        IPage<CampPageVO> pageData = baseMapper.getByPage(page, userId);
        pageData.getRecords().forEach(item -> {
            statusChange(item, now);
        });
        return pageData;
    }

    @Override
    public R getByData(Integer id) {
        KxsCamp kxsCamp = baseMapper.selectById(id);
        if (kxsCamp == null) {
            return R.failed(SysErrorTypeEnum.NOT_DATA.getDescription());
        }
        statusChange(kxsCamp, LocalDateTime.now());
        CampGetByIdVO campGetByIdVO = new CampGetByIdVO();
        BeanUtil.copyProperties(kxsCamp, campGetByIdVO);
        return R.ok(campGetByIdVO);
    }

    @Override
    public void prizePoolIsRefreshed(RabbitOrderQueueMQ.MsgEntity parse) {
        //查询正在进行中的活动
        LocalDateTime now = LocalDateTime.now();
        //兑换券下单
        if(parse.getGoodsId() == 11 || parse.getGoodsId() == 12) {

            //订单奖金
            BigDecimal amount = NumberUtil.mul(NumberUtil.div(parse.getTotalPrice(), 600), 90);
            //查询此用户是否参加进行中的训练营
            KxsCamp kxsCamp = baseMapper.selectUserCamp(parse.getUserId(), now);
            if (kxsCamp != null) {
                //给训练营加金额
                kxsCamp.setBonusPool(NumberUtil.add(kxsCamp.getBonusPool(), amount));
                kxsCamp.setOrderNum(kxsCamp.getOrderNum() + 1);
                baseMapper.updateById(kxsCamp);

                //给创客团队加金额
                KxsCampUser kxsCampUser = kxsCampUserService.getOne(Wrappers.<KxsCampUser>lambdaQuery()
                        .eq(KxsCampUser::getCampId, kxsCamp.getId())
                        .eq(KxsCampUser::getUserId, parse.getUserId()));
                kxsCampUser.setTeamOrderPool(NumberUtil.add(kxsCampUser.getTeamOrderPool(), amount));
                kxsCampUser.setTeamOrderNum(kxsCampUser.getTeamOrderNum() + 1);
                kxsCampUserService.updateById(kxsCampUser);
                log.info("用户{}参加训练营{}，订单ID{}, 奖金池{}，订单数{}", parse.getUserId(), kxsCamp.getId(), parse.getOrderId(), kxsCamp.getBonusPool(), kxsCamp.getOrderNum());
                return;
            }
            //查找此用户上级倒序后参加了训练营，把奖金加入到自己和训练营里
            R<KxsUser> kxsUserR = remoteKxsUserService.loadUserById(parse.getUserId(), SecurityConstants.FROM_IN);
            KxsUser user = RetOps.of(kxsUserR)
                    .getData()
                    .orElseThrow(() -> new GlobalCustomerException(ErrorTypeEnum.USER_NOT_FOUND.getDescription()));
            //下单用户的上级路径
            String[] pidPaths = user.getPidPath().split(",");
            //翻转上级从最近的开始查询
            Arrays.sort(pidPaths, Collections.reverseOrder());
            KxsCampUser campUser = baseMapper.selectUsersCamp(pidPaths, now);
            if (campUser != null) {
                //给训练营加金额
                KxsCamp camp = baseMapper.selectById(campUser.getCampId());
                camp.setBonusPool(NumberUtil.add(camp.getBonusPool(), amount));
                camp.setOrderNum(camp.getOrderNum() + 1);
                baseMapper.updateById(camp);

                //给创客团队加金额
                campUser.setTeamOrderPool(NumberUtil.add(campUser.getTeamOrderPool(), amount));
                campUser.setTeamOrderNum(campUser.getTeamOrderNum() + 1);
                kxsCampUserService.updateById(campUser);
                log.info("用户{}的上级{}参加训练营{}，订单ID{}, 奖金池{}，订单数{}", parse.getUserId(), campUser.getUserId(), camp.getId(), parse.getOrderId(), camp.getBonusPool(), camp.getOrderNum());
            }
        }

    }

    @Override
    public IPage<KxsCamp> getBySysPage(Page<KxsCamp> page, KxsCamp param) {
        LocalDateTime now = LocalDateTime.now();
        Page<KxsCamp> pageData = this.page(page, Wrappers.<KxsCamp>lambdaQuery()
                .eq(StrUtil.isNotEmpty(param.getCreateCode()), KxsCamp::getCreateCode, param.getCreateCode())
                .orderByDesc(KxsCamp::getId));

        pageData.getRecords().forEach(item -> statusChange(item, now));
        return pageData;
    }

//    @Override
//    public void prizePoolIsRefreshed(RabbitOrderQueueMQ.MsgEntity parse) {
//        //查询正在进行中的活动
//        LocalDateTime now = LocalDateTime.now();
//        //定时任务执行中时，查询当前正在进行的活动，由于定时任务执行时间偏差，当前时间减1一分钟判断
//        List<KxsCamp> list = baseMapper.selectList(Wrappers.<KxsCamp>lambdaQuery().le(KxsCamp::getStartTime, now).ge(KxsCamp::getEndTime, now.minusMinutes(1)));
//        //查询活动参与的创客
//        for (KxsCamp kxsCamp : list) {
//            //初始化奖金池
//            BigDecimal totalBonusPool = BigDecimal.ZERO;
//            //开机数
//            int openNum = 0;
//            //下单数
//            int orderNum = 0;
//
//            List<KxsCampUser> campUsers = kxsCampUserService.list(Wrappers.<KxsCampUser>lambdaQuery().eq(KxsCampUser::getCampId, kxsCamp.getId()));
//            //清除参与创客的所有统计数据然后封装在map里方便统计
//            Map<Integer, KxsCampUser> campUsersMap = new HashMap<>();
//            for (KxsCampUser campUser : campUsers) {
//                KxsCampUser kxsCampUser = new KxsCampUser();
//                BeanUtil.copyProperties(campUser, kxsCampUser);
//                kxsCampUser.setTeamOrderPool(BigDecimal.ZERO);
//                kxsCampUser.setTeamLeaderPool(BigDecimal.ZERO);
//                kxsCampUser.setTeamOrderNum(0);
//                kxsCampUser.setTeamLeaderNum(0);
//                kxsCampUser.setTeamOpenNum(0);
//                campUsersMap.put(campUser.getUserId(), kxsCampUser);
//            }
//
//            //转换为userID集合
//            List<Integer> userIds = campUsers.stream().map(KxsCampUser::getUserId).toList();
//
//
//            /*
//             * 查询当前活动的时间区间所有电签大机的订单
//             */
//            R<List<ShopOrderGoodsUserVO>> ordersR = remoteKxsProductService.getDateBetweenOrders(LocalDateTimeUtil.format(kxsCamp.getStartTime(), DatePattern.NORM_DATETIME_PATTERN)
//                    , LocalDateTimeUtil.format(kxsCamp.getEndTime(), DatePattern.NORM_DATETIME_PATTERN), SecurityConstants.FROM_IN);
//            List<ShopOrderGoodsUserVO> orders = RetOps.of(ordersR)
//                    .getData()
//                    .orElse(Collections.emptyList());
//            //循环区间订单查询用户的上级是否包含参与创客的ID
//            for (ShopOrderGoodsUserVO order : orders) {
//                //如果是参与者自己下的单
//                if (userIds.contains(order.getUserId())) {
//                    int currentNum = NumberUtil.div(order.getTotalPrice(), 600).intValue();
//                    //刷新参与创客的团队累计
//                    KxsCampUser kxsCampUser = campUsersMap.get(order.getUserId());
//                    BigDecimal amount = NumberUtil.mul(NumberUtil.div(order.getTotalPrice(), 600), 90);
//                    totalBonusPool = NumberUtil.add(totalBonusPool, amount);
//                    //兑换券下单
//                    kxsCampUser.setTeamOrderPool(NumberUtil.add(kxsCampUser.getTeamOrderPool(), amount));
//                    kxsCampUser.setTeamOrderNum(kxsCampUser.getTeamOrderNum() + currentNum);
////                    if(order.getId() == 27 || order.getId() == 28){
////                        //大小盟主下单, 奖金池+60，订单数+1
////                        kxsCampUser.setTeamLeaderPool(NumberUtil.add(kxsCampUser.getTeamLeaderPool(), 60));
////                        kxsCampUser.setTeamLeaderNum(kxsCampUser.getTeamLeaderNum() + 1);
////                        currentNum = 1;
////                    }
//                    orderNum += currentNum;
//                    continue;
//                }
//
//                R<KxsUser> kxsUserR = remoteKxsUserService.loadUserById(order.getUserId(), SecurityConstants.FROM_IN);
//                KxsUser user = RetOps.of(kxsUserR)
//                        .getData()
//                        .orElseThrow(() -> new GlobalCustomerException(ErrorTypeEnum.USER_NOT_FOUND.getDescription()));
//                //下单用户的上级路径
//                String[] pidPaths = user.getPidPath().split(",");
//                //通过用户的pidPath倒序查找最近所属的上级
//                Integer userId = SysUtils.checkUserIsChildren(pidPaths, userIds);
//                if(userId != null){
//                    int currentNum = NumberUtil.div(order.getTotalPrice(), 600).intValue();
//                    //刷新参与创客的团队累计
//                    KxsCampUser kxsCampUser = campUsersMap.get(userId);
//                    BigDecimal amount = NumberUtil.mul(NumberUtil.div(order.getTotalPrice(), 600), 90);
//                    totalBonusPool = NumberUtil.add(totalBonusPool, amount);
//
//                    kxsCampUser.setTeamOrderPool(NumberUtil.add(kxsCampUser.getTeamOrderPool(), amount));
//                    kxsCampUser.setTeamOrderNum(kxsCampUser.getTeamOrderNum() + currentNum);
////                    if(order.getId() == 27 || order.getId() == 28){
////                        //大小盟主下单, 奖金池+60，订单数+1
////                        kxsCampUser.setTeamLeaderPool(NumberUtil.add(kxsCampUser.getTeamLeaderPool(), 60));
////                        kxsCampUser.setTeamLeaderNum(kxsCampUser.getTeamLeaderNum() + 1);
////                        currentNum = 1;
////                    }
//                    orderNum += currentNum;
//                }
//            }
//
//            /*
//             * 查询活动区间开通的大盟主添加到奖金池
//             */
//            R<List<KxsLeader>> leadersR = remoteKxsUserService.getDateBetweenLeaders(LocalDateTimeUtil.format(kxsCamp.getStartTime(), DatePattern.NORM_DATETIME_PATTERN)
//                    , LocalDateTimeUtil.format(kxsCamp.getEndTime(), DatePattern.NORM_DATETIME_PATTERN), SecurityConstants.FROM_IN);
//            List<KxsLeader> leaders = RetOps.of(leadersR)
//                    .getData()
//                    .orElse(Collections.emptyList());
//            for (KxsLeader leader : leaders) {
//                //如果是参与者自己下的单
//                if (userIds.contains(leader.getUserId())) {
//                    BigDecimal amount;
//                    if(leader.getLeaderType().equals(LeaderTypeEnum.SMALL_LEADER.getType())){
//                        amount = new BigDecimal("2000");
//                    }else{
//                        amount = new BigDecimal("8000");
//                    }
//                    totalBonusPool = NumberUtil.add(totalBonusPool, amount);
//
//                    //刷新参与创客的团队累计
//                    KxsCampUser kxsCampUser = campUsersMap.get(leader.getUserId());
//                    kxsCampUser.setTeamLeaderPool(NumberUtil.add(kxsCampUser.getTeamLeaderPool(), amount));
//                    kxsCampUser.setTeamLeaderNum(kxsCampUser.getTeamLeaderNum() + 1);
//                    orderNum += 1;
//                    log.info("参与者{}自己下单盟主,进入到{}奖金池", leader.getUserId(), kxsCamp.getTitle());
//                    continue;
//                }
//                //查询此盟主的上级
//                R<KxsUser> kxsUserR = remoteKxsUserService.loadUserById(leader.getUserId(), SecurityConstants.FROM_IN);
//                KxsUser user = RetOps.of(kxsUserR)
//                        .getData()
//                        .orElseThrow(() -> new GlobalCustomerException(ErrorTypeEnum.USER_NOT_FOUND.getDescription()));
//                //下单用户的上级路径
//                String[] pidPaths = user.getPidPath().split(",");
//                //通过用户的pidPath倒序查找最近所属的上级
//                Integer userId = SysUtils.checkUserIsChildren(pidPaths, userIds);
//                if(userId != null){
//                    BigDecimal amount;
//                    if(leader.getLeaderType().equals(LeaderTypeEnum.SMALL_LEADER.getType())){
//                        amount = new BigDecimal("2000");
//                    }else{
//                        amount = new BigDecimal("8000");
//                    }
//                    totalBonusPool = NumberUtil.add(totalBonusPool, amount);
//
//                    //刷新参与创客的团队累计
//                    KxsCampUser kxsCampUser = campUsersMap.get(userId);
//                    kxsCampUser.setTeamLeaderPool(NumberUtil.add(kxsCampUser.getTeamLeaderPool(), amount));
//                    kxsCampUser.setTeamLeaderNum(kxsCampUser.getTeamLeaderNum() + 1);
//                    orderNum += 1;
//                    log.info("创客:{}的团队购买盟主:{},进入到:{}奖金池", userId, leader.getUserId(), kxsCamp.getTitle());
//                }
//            }
//
//            /*
//             * 查询活动区间开机数
//             */
//            for (Integer userId : campUsersMap.keySet()) {
//                KxsCampUser kxsCampUser = campUsersMap.get(userId);
//                HashMap<String, Object> data = new HashMap<>();
//                data.put("UserId", userId);
//                data.put("StartTime", LocalDateTimeUtil.format(kxsCamp.getStartTime(), DatePattern.PURE_DATE_PATTERN));
//                data.put("EndTime", LocalDateTimeUtil.format(kxsCamp.getStartTime(), DatePattern.PURE_DATE_PATTERN));
//                R resR = remoteOldService.teamOpenTotalData(JSON.toJSONString(data));
//                if(resR.getStatus() == 1){
//                    if(resR.getData() != null){
//                        JSONObject jsonObject = JSON.parseObject(JSON.toJSONString(resR.getData()));
//                        int total = jsonObject.getInteger("TeamPosMerchantCount")
//                                + jsonObject.getInteger("TeamSimMerchantCount")
//                                + jsonObject.getInteger("TeamMpMerchantCount");
//                        openNum += total;
//                        kxsCampUser.setTeamOpenNum(kxsCampUser.getTeamOpenNum() + total);
//                    }
//                }
//            }
//
//            kxsCamp.setBonusPool(totalBonusPool);
//            kxsCamp.setOrderNum(orderNum);
//            kxsCamp.setOpenNum(openNum);
//            baseMapper.updateById(kxsCamp);
//            //刷新参与创客的统计
//            kxsCampUserService.updateBatchById(new ArrayList<>(campUsersMap.values()));
//            log.info("训练营{}统计结束", kxsCamp.getCampNum());
//        }
//
//    }


    /**
     * 状态变更
     *
     * @param campT 营地
     * @param now   现在
     */
    private <T> void statusChange(T campT, LocalDateTime now) {
        if (campT instanceof KxsCamp camp) {
            if (camp.getEndTime().isBefore(now)) {
                camp.setStatus(CampStatusEnum.STATUS_END.getType());
            } else if (LocalDateTimeUtil.isIn(now, camp.getStartTime(), camp.getEndTime(), false, false)) {
                camp.setStatus(CampStatusEnum.STATUS_NORMAL.getType());
            } else {
                camp.setStatus(CampStatusEnum.STATUS_CLOSE.getType());
            }
        }
        if (campT instanceof CampPageVO camp) {
            if (camp.getEndTime().isBefore(now)) {
                camp.setStatus(CampStatusEnum.STATUS_END.getType());
            } else if (LocalDateTimeUtil.isIn(now, camp.getStartTime(), camp.getEndTime(), false, false)) {
                camp.setStatus(CampStatusEnum.STATUS_NORMAL.getType());
            } else {
                camp.setStatus(CampStatusEnum.STATUS_CLOSE.getType());
            }
        }
    }

}

