package com.willalp.yiqing.service.impl;

import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
import com.willalp.clockingin.domain.HsPnsVacateTime;
import com.willalp.clockingin.mapper.HsPnsVacateTimeMapper;
import com.willalp.common.cglib.DynamicBean;
import com.willalp.common.core.domain.entity.SysDictData;
import com.willalp.common.exception.base.BaseException;
import com.willalp.common.utils.DateUtils;
import com.willalp.common.utils.StringUtils;
import com.willalp.common.utils.bean.BeanUtils;
import com.willalp.system.service.ISysDictDataService;
import com.willalp.yiqing.domain.*;
import com.willalp.yiqing.domain.vo.*;
import com.willalp.yiqing.mapper.HsYiqingQuestionMapper;
import com.willalp.yiqing.mapper.HsYiqingUserMapper;
import com.willalp.yiqing.service.HsYiQingService;
import com.willalp.yiqing.service.IHsTaskBelongUserService;
import com.willalp.yiqing.service.IHsYiqingTaskService;
import com.willalp.yiqing.service.IHsYiqingUserQueResultService;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.*;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.Collectors;

/**
 * @author xian
 */
@Service
public class HsYiQingServiceImpl implements HsYiQingService {

    @Resource
    private HsYiqingUserMapper userMapper;

    @Resource
    private HsYiqingQuestionMapper questionMapper;

    @Resource
    private IHsYiqingUserQueResultService resultService;

    @Resource
    private IHsYiqingTaskService taskService;

    @Resource
    private IHsTaskBelongUserService belongUserService;

    @Resource
    private ISysDictDataService dictDataService;

    @Resource
    private HsPnsVacateTimeMapper vacateTimeMapper;

    static void setBelong(HsYiqingTask t, List<HsTaskBelongUser> belongUsersDb) {
        belongUsersDb.forEach(b -> {
            if (0 == b.getBelongLevel()) {
                t.setBelongMain(b.getNickName());
            }
        });
        t.setBelongMinors(
                belongUsersDb.stream().filter(b -> b.getBelongLevel() == 1)
                        .map(HsTaskBelongUser::getNickName).collect(Collectors.toList()));
        t.setExecutors(
                belongUsersDb.stream().filter(b -> b.getBelongLevel() == 2)
                        .map(HsTaskBelongUser::getNickName).collect(Collectors.toList()));
    }

    @Override
    public List<Object> selectRegistrationInformationList(HsYiqingUser hsYiqingUser) {
        //查询当前分页的用户登记信息
        List<HsYiqingUser> users = userMapper.selectHsYiqingUserList(hsYiqingUser);
        if (0 == users.size()) {
            throw new BaseException("未查询到登记信息");
        }
        List<Object> list = new ArrayList<>();
        //获取 问题 以及 答案
        String[] queList = hsYiqingUser.getQueList();
        String[] queData = hsYiqingUser.getQueData();
        int isQueList = 0;
        //按每个用户都去遍历一遍答案
        for (HsYiqingUser user : users) {
            int isAdd = 0;
            String userNo = user.getUserNo();
            //根据用户编号查询视图中 对应登记信息
            List<QueResultVo> queResultVos = userMapper.selectQueResultList(userNo);
            List<HsPnsVacateTime> newVacateTimes = vacateTimeMapper.selectNewVacateInfo();
            //生成动态属性
            HashMap<String, Class<?>> propertyMap = new HashMap<>(16);
            try {
                //生成基本属性
                propertyMap.put("userNo", Class.forName("java.lang.String"));
                propertyMap.put("userName", Class.forName("java.lang.String"));
                propertyMap.put("orgNo", Class.forName("java.lang.String"));
                propertyMap.put("orgName", Class.forName("java.lang.String"));
                propertyMap.put("createTime", Class.forName("java.lang.String"));
                propertyMap.put("vacateTime", Class.forName("java.lang.String"));
                if (isQueList == 0) {
                    propertyMap.put("list", Class.forName("java.util.List"));
                }
                //循环生成答案属性
                for (int i = 0; i < queResultVos.size(); i++) {
                    propertyMap.put("queResultText" + (i + 1), Class.forName("java.lang.String"));
                }
            } catch (ClassNotFoundException e) {
                e.printStackTrace();
            }
            // 生成动态 Bean
            DynamicBean bean = new DynamicBean(propertyMap);
            bean.setValue("userNo", user.getUserNo());
            bean.setValue("userName", user.getUserName());
            bean.setValue("orgNo", user.getOrgNo());
            bean.setValue("orgName", user.getOrgName());
            bean.setValue("createTime", DateUtils.dateTime(user.getCreateTime()));
            newVacateTimes.stream().anyMatch(v -> {
                if (StringUtils.equals(v.getUserNo(), userNo)) {
                    bean.setValue("vacateTime",
                            DateUtils.dateTime(newVacateTimes.get(0).getVacateStartTime())
                                    + " 至 " +
                            DateUtils.dateTime(newVacateTimes.get(0).getVacateEndTime()));
                    return true;
                } else {
                    bean.setValue("vacateTime", "空闲中");
                    return false;
                }
            });
            if (isQueList == 0) {
                bean.setValue("list", this.getQueTableLabel("0"));
                isQueList++;
            }
            //循环生成答案属性
            for (int i = 0; i < queResultVos.size(); i++) {
                // 给 Bean 设置值
                bean.setValue("queResultText" + (i + 1),
                        queResultVos.get(i).getQueResultText());
            }
            if (null != queData) {
                for (int i1 = 0; i1 < queData.length; i1++) {
                    if (StringUtils.isNotBlank(queData[i1])) {
                        String queDatum = queData[i1];
                        if (!StringUtils.equals(queDatum,
                                bean.getValue("queResultText" + (i1 + 1)) + ""
                        )) {
                            isAdd++;
                        }
                    }
                }
            }
            //判断本次是否保存该用户
            if (isAdd == 0) {
                list.add(bean.getObject());
            }
        }
        return list;
    }

    @Override
    public List<DynamicTable> getQueTableLabel(String queGroupId) {
        QueryWrapper<HsYiqingQuestion> last;
        //0：查询所有
        if ("0".equals(queGroupId)) {
            last = new QueryWrapper<HsYiqingQuestion>().eq("que_level", 0)
                    .eq("enable_or_disable", 0);
//                    .last("ORDER BY que_result_no");
        } else {
            last = new QueryWrapper<HsYiqingQuestion>().eq("que_level", 0)
                    .eq("que_group_id", queGroupId)
                    .eq("enable_or_disable", 0);
//                    .last("ORDER BY que_result_no");
        }
        List<HsYiqingQuestion> questions = questionMapper.selectList(last);
        if (0 == questions.size()) {
            throw new BaseException("请配置筛选题目");
        }
        int i = 1;
        List<DynamicTable> dts = new ArrayList<>();
        for (HsYiqingQuestion question : questions) {
            DynamicTable dt = new DynamicTable();
            dt.setId(question.getQueId());
            dt.setLabel(question.getQueTextOrPid());
            dt.setProp("queResultText" + i);
            dts.add(dt);
            i++;
        }
        questions = questionMapper.selectList(
                new QueryWrapper<HsYiqingQuestion>().eq("que_level", 1));
        if (0 == questions.size()) {
            throw new BaseException("请配置筛选题目答案");
        }
        for (DynamicTable dt : dts) {
            for (HsYiqingQuestion question : questions) {
                Map<String, String> map = new HashMap<>(4);
                if (1 == question.getQueLevel()) {
                    if (StringUtils.equals(dt.getId(), question.getQueTextOrPid())) {
                        map.put("id", String.valueOf(question.getQueResultNo()));
                        map.put("value", question.getQueResultText());
                        dt.getResultList().add(map);
                    }
                }
            }
        }
        return dts;
    }

    @Override
    public int saveQueResult(UserQueResultVo userQueResultVo) {
        userQueResultVo.verify(userQueResultVo);
        UserQueResultVo userQueResultVo1 = this.verifyUserQueAndInsert(userQueResultVo);
        if (null == userQueResultVo1) {
            return 0;
        }
        return 1;
    }

    @Override
    public UserQueResultVo verifyUserQueAndInsert(UserQueResultVo userQueResultVo) {
        String userName = userQueResultVo.getUserName();
        String userNo = userQueResultVo.getUserNo();
        String orgNo = userQueResultVo.getOrgNo();
        String orgName = userQueResultVo.getOrgName();
        List<String> ques = userQueResultVo.getQues();
        List<String> queResults = userQueResultVo.getQueResults();
        for (int i = 0; i < queResults.size(); i++) {
            if (StringUtils.isBlank(queResults.get(i))) {
                throw new BaseException("请完整填写答案");
            }
            if (i == ques.size() - 1) {
                break;
            }
        }
        HsYiqingUser user = userMapper.selectOne(new QueryWrapper<HsYiqingUser>()
                .eq("user_no", userNo).eq("org_no", orgNo));
        String idStr;
        if (null == user) {
            HsYiqingUser yqUser = new HsYiqingUser();
            idStr = IdWorker.getIdStr();
            yqUser.setId(idStr);
            yqUser.setUserNo(userNo);
            yqUser.setUserName(userName);
            yqUser.setOrgName(orgName);
            yqUser.setOrgNo(orgNo);
            yqUser.setCreateBy("yq");
            yqUser.setCreateTime(new Date());
            userMapper.insert(yqUser);
        } else {
            idStr = user.getId();
        }
        //删除之前的答案
        resultService.remove(new QueryWrapper<HsYiqingUserQueResult>()
                .eq("yq_user_id", idStr).in("yq_que_id", ques));
        List<HsYiqingUserQueResult> resultsList = new ArrayList<>();
        for (int i = 0; i < ques.size(); i++) {
            HsYiqingUserQueResult userQueResult = new HsYiqingUserQueResult();
            userQueResult.setYqUserId(idStr);
            userQueResult.setYqQueId(ques.get(i));
            userQueResult.setQueResultText(queResults.get(i));
            userQueResult.setCreateBy("yq");
            userQueResult.setCreateTime(new Date());
            resultsList.add(userQueResult);
        }
        resultService.saveBatch(resultsList);
        return userQueResultVo;
    }

    @Override
    public List<PushVo> needPushUser() {
        List<HsYiqingTask> hsYiqingTasks = taskService.getBaseMapper().selectList(
                new QueryWrapper<HsYiqingTask>().eq("task_status", 1)
                        .eq("push_num", 0));
        if (0 == hsYiqingTasks.size()) {
            throw new BaseException("暂时没有可推送的任务");
        }
        List<PushVo> list = new ArrayList<>();
        hsYiqingTasks.forEach(task -> {
            List<HsTaskBelongUser> belongUser = belongUserService.getBaseMapper().selectList(
                    new QueryWrapper<HsTaskBelongUser>()
                            .eq("yq_task_id", task.getYqTaskId()));
            List<String> userNos = belongUser.stream().map(HsTaskBelongUser::getBelongUserNo).collect(Collectors.toList());
            PushVo pushVo = new PushVo();
            BeanUtils.copyBeanProp(pushVo, task);
            pushVo.setIdList(userNos);
            list.add(pushVo);
        });
        return list;
    }

    @Override
    public Integer getUserNotRead(String userNo, String orgNo) {
        //查询用户被分配的任务
        List<HsTaskBelongUser> belongUsers = verifyOrgInfoGetUsers(userNo, orgNo);
        AtomicInteger count = new AtomicInteger();
        //查询机构下所有任务
        List<HsYiqingTask> taskDbsByOrgNo = taskService.getBaseMapper().selectList(
                new QueryWrapper<HsYiqingTask>().eq("org_no", orgNo));
        if (ObjectUtils.isNotEmpty(taskDbsByOrgNo)) {
            taskDbsByOrgNo.forEach(tdb -> belongUsers.forEach(b -> {
                //用户任务ID 比对 机构所有任务 并且 不是未发布状态
                if (Objects.equals(b.getYqTaskId(), tdb.getYqTaskId()) && 0 != tdb.getTaskStatus()) {
                    //判断是否未读
                    if (b.getMsgIsRead() == 0) {
                        count.getAndIncrement();
                    }
                }
            }));
        }
        return count.get();
    }

    private List<HsTaskBelongUser> verifyOrgInfoGetUsers(String userNo, String orgNo) {
        if (StringUtils.isBlank(userNo)) {
            throw new BaseException("用户编号不能为空");
        }
        if (StringUtils.isBlank(orgNo)) {
            throw new BaseException("机构编号不能为空");
        }
        HsYiqingUser userByUserNo = userMapper.selectOne(new QueryWrapper<HsYiqingUser>()
                .eq("user_no", userNo));
        if (StringUtils.equals(userByUserNo.getOrgNo(), orgNo)) {
            return belongUserService.getBaseMapper().selectList(
                    new QueryWrapper<HsTaskBelongUser>()
                            .eq("belong_user_no", userNo)
                            .last("group by yq_task_id"));
        }
        throw new BaseException("暂无任务");
    }

    @Override
    public Map<String, Object> readTask(String userNo, String orgNo) {
        List<HsTaskBelongUser> belongUsers = verifyOrgInfoGetUsers(userNo, orgNo);
        if (0 == belongUsers.size()) {
            throw new BaseException("暂无任务");
        }
        //记录用户拥有的任务
        List<String> taskIds = new ArrayList<>();
        List<String> notReadTaskIds = new ArrayList<>();
        for (HsTaskBelongUser belongUser : belongUsers) {
            taskIds.add(belongUser.getYqTaskId());
        }
        List<SysDictData> sysDictData = dictDataService.getBaseMapper().selectList(new QueryWrapper<SysDictData>()
                .eq("dict_type", "yq_task_status"));
        List<String> dictValues = sysDictData.stream()
                .map(SysDictData::getDictValue).collect(Collectors.toList());
        List<PushVo> pushVos = new ArrayList<>();
        List<HsYiqingTask> tasksDb = taskService.getBaseMapper().selectList(new QueryWrapper<HsYiqingTask>()
                .eq("org_no", orgNo)
                .in("yq_task_id", taskIds)
                .between("task_status", dictValues.get(1), dictValues.get(dictValues.size() - 1)));
        if (0 == tasksDb.size()) {
            throw new BaseException("暂无任务");
        }
        //数据装配到伪类中
        tasksDb.forEach(okt -> {
            belongUsers.forEach(b -> {
                //未读
                if (okt.getYqTaskId().equals(b.getYqTaskId())
                        && 0 == b.getMsgIsRead()) {
                    notReadTaskIds.add(b.getYqTaskId());
                }
            });
            PushVo pushVo = new PushVo();
            notReadTaskIds.forEach(nri -> {
                if (StringUtils.equals(okt.getYqTaskId(), nri)) {
                    pushVo.setIsRead(0);
                }
            });
            BeanUtils.copyBeanProp(pushVo, okt);
            pushVos.add(pushVo);
        });
        List<PushVo> pushVoSort = pushVos.stream()
                .sorted(Comparator.comparing(PushVo::getCreateTime).reversed())
                .collect(Collectors.toList());
        Map<String, Object> map = new HashMap<>(16);
        map.put("data", pushVoSort);
        map.put("count", notReadTaskIds.size());
        return map;

    }

    @Override
    public PushVo clickTaskRead(String taskId, String userNo) {
        HsTaskBelongUser belongUser = this.verifyParamsGetUser(taskId, userNo);
        //修改为已读的数据
        belongUser.setMsgIsRead(1);
        if (!belongUserService.updateById(belongUser)) {
            throw new BaseException("修改已读状态错误");
        }
        HsYiqingTask t = taskService.getOne(new QueryWrapper<HsYiqingTask>()
                .eq("yq_task_id", taskId));
        if (t == null) {
            throw new BaseException("任务不存在 - 02");
        }
        PushVo p = new PushVo();
        List<HsTaskBelongUser> belongUsersDb = belongUserService.getBaseMapper().selectList(new QueryWrapper<HsTaskBelongUser>()
                .eq("yq_task_id", taskId));
        setBelong(t, belongUsersDb);
        BeanUtils.copyBeanProp(p, t);
        p.setUserTaskStatus(belongUser.getUserTaskStatus());
        p.setIsOrder(belongUser.getIsOrder());
        p.setIsRead(1);
        return p;
    }

    /**
     * 验证并获取用户
     *
     * @param taskId
     * @param userNo
     * @return
     */
    private HsTaskBelongUser verifyParamsGetUser(String taskId, String userNo) {
        if (StringUtils.isBlank(taskId)) {
            throw new BaseException("任务ID不能为空");
        }
        if (StringUtils.isBlank(userNo)) {
            throw new BaseException("用户编号不能为空");
        }
        HsTaskBelongUser belongUser = belongUserService.getOne(
                new QueryWrapper<HsTaskBelongUser>()
                        .eq("yq_task_id", taskId)
                        .eq("belong_user_no", userNo));
        if (null == belongUser) {
            throw new BaseException("任务不存在 - 01");
        }
        return belongUser;
    }

    @Override
    public Integer upDateUserTaskStatus(String taskId, String userNo, Integer status) {
        HsTaskBelongUser belongUser = this.verifyParamsGetUser(taskId, userNo);
        if (ObjectUtil.isEmpty(status)) {
            throw new BaseException("用户任务状态不能为空");
        }
        HsYiqingTask task = taskService.getOne(new QueryWrapper<HsYiqingTask>()
                .eq("yq_task_id", taskId));
        if (task == null) {
            throw new BaseException("任务不存在 - 02");
        }
        //如果为主要负责人
        if (0 == belongUser.getBelongLevel()) {
            if (5 == status) {
                //主负责人开始时间
                task.setActualStartTime(new Date());
            } else if (2 == status) {
                //主负责人结束时间
                task.setActualEndTime(new Date());
            }
            task.setTaskStatus(status);
            if (!taskService.updateById(task)) {
                throw new BaseException("更新任务实际实际失败");
            }
        }

        if (1 == task.getTaskStatus()) {
            throw new BaseException("任务暂未开始");
        }
        belongUser.setUserTaskStatus(status);
        if (!belongUserService.updateById(belongUser)) {
            throw new BaseException("状态更新失败");
        }
        return 1;
    }

    @Override
    public Integer upDateUserIsOrder(String taskId, String userNo, Integer status) {
        HsTaskBelongUser belongUser = this.verifyParamsGetUser(taskId, userNo);
        belongUser.setIsOrder(status);
        if (0 == belongUser.getBelongLevel()) {
            HsYiqingTask byId = taskService.getById(taskId);
            byId.setTaskStatus(5);
        }
        if (0 == status) {
            belongUser.setUserTaskStatus(0);
        }
        if (!belongUserService.updateById(belongUser)) {
            throw new BaseException("状态更新失败");
        }
        return 1;
    }

    @Override
    public int taskBelongSave(TaskBelongSaveVo taskBelongSaveVo) {
        int belongLevel = taskBelongSaveVo.getBelongLevel();
        String taskId = taskBelongSaveVo.getTaskId();
        List<HsTaskBelongUser> belongUsers = taskBelongSaveVo.getList();
        if (StringUtils.isBlank(taskId)) {
            throw new BaseException("任务ID不能为空");
        }
        if (0 == belongUsers.size()) {
            throw new BaseException("未选择用户");
        }
        List<HsTaskBelongUser> belongUsersDb
                = belongUserService.getBaseMapper().selectList(new QueryWrapper<HsTaskBelongUser>()
                .eq("yq_task_id", taskId));
        belongUsersDb.forEach(b -> belongUsers.forEach(b1 -> {
            if (StringUtils.equals(
                    b.getBelongUserNo(), b1.getBelongUserNo())) {
                if (!b.getBelongLevel().equals(b1.getBelongLevel())) {
                    String text;
                    if (0 == b.getBelongLevel()) {
                        text = "主要负责人";
                    } else if (1 == b.getBelongLevel()) {
                        text = "二级负责人";
                    } else {
                        text = "执行人";
                    }
                    throw new BaseException(b1.getBelongUserNo() + " - " + b1.getNickName() + " - 已经是 { " + text + "}");
                }
            }
        }));
        belongUserService.remove(
                new QueryWrapper<HsTaskBelongUser>().eq("yq_task_id", taskId)
                        .eq("belong_level", belongLevel));
        if (0 == belongLevel) {
            if (1 != belongUsers.size()) {
                throw new BaseException("只能有一个主要负责人");
            }
        }
        if (!belongUserService.saveBatch(belongUsers)) {
            throw new BaseException("保存负责人失败");
        }
        return 1;
    }
}

