package com.ruoyi.web.task;

import com.alibaba.fastjson2.JSONObject;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.enums.BoolValues;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.vod.VodUtils;
import com.ruoyi.framework.web.service.SysLoginService;
import com.ruoyi.system.service.ISysUserService;
import com.ruoyi.voluntary.domain.BusiCards;
import com.ruoyi.voluntary.domain.BusiScoreLock;
import com.ruoyi.voluntary.service.IBusiCardsService;
import com.ruoyi.voluntary.service.IBusiScoreLockService;
import com.ruoyi.web.service.ZyService;
import org.apache.commons.collections4.CollectionUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

@Component("zyTask")
public class ZyTask
{
    @Autowired
    ZyService zyService;
    @Autowired
    IBusiCardsService cardsService;
    @Autowired
    IBusiScoreLockService scoreLockService;
    @Autowired
    ISysUserService userService;
    @Autowired
    SysLoginService sysLoginService;

    private boolean submitProcessing = false;
    private static Logger log = LoggerFactory.getLogger(ZyTask.class);

    public void ryParams(String params)
    {
        System.out.println("执行有参方法：" + params);
    }

    public void submitPlan(String location, Integer year) {
        if (submitProcessing) {
            throw new RuntimeException("还在处理中...");
        }
        submitProcessing = true;
        try {
            String[] locations = StringUtils.split(location, ",");
            for (String loc : locations) {
                zyService.calculateSubmitPlanData(loc, year);
            }
        } finally {
            submitProcessing = false;
        }
    }

    /**
     * 更新过期卡状态
     * @param status=9
     */
    public void updateCardsStatusBatch(Integer status) {
        cardsService.updateBusiCardsBatch(status);
    }

    /**
     * 更新锁分状态
     * @param 满足条件的status全部更新
     * ***处理是否锁分***
     * scoreLock: 0 非锁定状态  -1 待锁定状态（需要学生强制进入个人中心，调用improveUserInfo） 1 锁分状态
     * scoreLockingMsg: 待锁定状态时的提示消息
     */
    @Transactional
    public void updateUserScoreLock() {
        //查询有效的分数锁定配置参数
        List<BusiScoreLock> BusiScoreLockList = scoreLockService.selectBusiScoreLockList(new BusiScoreLock().setIsValid(BoolValues.yes.getValue()));

        //在设置的第一天，非锁定（状态0）改为中间状态（状态-1）
        List<String> provinceNameStartList = BusiScoreLockList.stream().filter(scoreLock -> DateUtils.inIntervalDate(scoreLock.getStartDate(),scoreLock.getEndDate())).collect(Collectors.toList())
                .stream().map(BusiScoreLock::getProvinceName).collect(Collectors.toList());

        if(CollectionUtils.isNotEmpty(provinceNameStartList)){
            Integer originalScoreLock = BoolValues.no.getValue();
            Integer newScoreLock = BoolValues.other.getValue();
            update(provinceNameStartList,originalScoreLock,newScoreLock);
        }

        //在设置的最后一天+1，锁定（状态1）改为非锁定（状态0和-1）
        List<String> provinceNameEndList = BusiScoreLockList.stream().filter(scoreLock -> DateUtils.inEndIntervalDate(scoreLock.getEndDate())).collect(Collectors.toList())
                .stream().map(BusiScoreLock::getProvinceName).collect(Collectors.toList());
        if(CollectionUtils.isNotEmpty(provinceNameEndList)){
            Integer originalScoreLock = BoolValues.yes.getValue();
            Integer newScoreLock = BoolValues.no.getValue();
            update(provinceNameEndList,originalScoreLock,newScoreLock);

            originalScoreLock = BoolValues.other.getValue();//-1的也需要更新（即在正式填报志愿期间没有使用）
            newScoreLock = BoolValues.no.getValue();
            update(provinceNameEndList,originalScoreLock,newScoreLock);
        }

        //在非设置的日期，锁定或中间状态（锁定1，中间状态-1）改为非锁定（状态0）
        List<String> provinceNameNoList = BusiScoreLockList.stream().filter(scoreLock -> !DateUtils.inIntervalDate(scoreLock.getStartDate(),scoreLock.getEndDate())).collect(Collectors.toList())
                .stream().map(BusiScoreLock::getProvinceName).collect(Collectors.toList());
        if(CollectionUtils.isNotEmpty(provinceNameNoList)){
            Integer originalScoreLock = BoolValues.yes.getValue();
            Integer newScoreLock = BoolValues.no.getValue();
            update(provinceNameNoList,originalScoreLock,newScoreLock);

            originalScoreLock = BoolValues.other.getValue();//-1的也需要更新（即在正式填报志愿期间没有使用）
            newScoreLock = BoolValues.no.getValue();
            update(provinceNameNoList,originalScoreLock,newScoreLock);
        }
    }

    private void update(List<String> provinceNameStartList,Integer originalScoreLock,Integer newScoreLock){
        List<SysUser> startUserList = userService.selectScoreLockUserList(new SysUser()
//                .setIsBind(BoolValues.yes.getValue())
                .setScoreLock(originalScoreLock).setProvinceNames(provinceNameStartList));
        //将锁定状态更新
        List<SysUser> updateUserList = new ArrayList<>();
        for (SysUser user : startUserList) {
            user.setScoreLock(newScoreLock);
            updateUserList.add(user);
            if (updateUserList.size() >= 500) {
                //更新
                userService.batchUpdateUser(updateUserList);
                log.info("update user's scoreLock to {}serList is {}",originalScoreLock, JSONObject.toJSONString(updateUserList));
                updateUserList.clear();
            }
        }
        if (updateUserList.size() > 0) {
            //更新剩余的
            userService.batchUpdateUser(updateUserList);
            log.info("update user's scoreLock to {},userList is {}",originalScoreLock, JSONObject.toJSONString(updateUserList));
            updateUserList.clear();
        }
        //有状态更新的需要将app用户的token清空
        if(CollectionUtils.isNotEmpty(startUserList)){
            //清空某省所有用户的token
            sysLoginService.resetTokens(userService.selectScoreLockUserList(new SysUser().setProvinceNames(startUserList.stream().map(SysUser::getProvinceName).collect(Collectors.toList()))));
        }
    }


}
