package com.ruoyi.web.service;

import cn.hutool.core.lang.Dict;
import com.alibaba.fastjson2.JSONObject;
import com.alibaba.fastjson2.util.DateUtils;
import com.google.common.collect.Sets;
import com.ruoyi.common.annotation.Excel;
import com.ruoyi.common.core.domain.AjaxResult2;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.enums.ExamType;
import com.ruoyi.common.enums.SubjectType;
import com.ruoyi.common.utils.CommonUtils;
import com.ruoyi.common.utils.NumberUtils;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.dz.domain.DzSubject;
import com.ruoyi.dz.service.IDzSubjectService;
import com.ruoyi.enums.ExamineeStatus;
import com.ruoyi.enums.PaperType;
import com.ruoyi.learn.domain.LearnExaminee;
import com.ruoyi.learn.domain.LearnPaper;
import com.ruoyi.learn.domain.LearnStudent;
import com.ruoyi.learn.domain.LearnTestStudent;
import com.ruoyi.learn.mapper.*;
import com.ruoyi.learn.service.ILearnStudentService;
import com.ruoyi.system.service.ISysUserService;
import org.apache.commons.compress.utils.Lists;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.util.Date;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

@Service
public class StudentService {
    private final LearnPaperMapper learnPaperMapper;
    private final LearnTestStudentMapper learnTestStudentMapper;
    private final ILearnStudentService learnStudentService;
    private final IDzSubjectService dzSubjectService;
    private final LearnTeacherService learnTeacherService;
    private final LearnExamineeMapper learnExamineeMapper;
    private final LearnAnswerMapper learnAnswerMapper;

    public StudentService(LearnPaperMapper learnPaperMapper, LearnTestStudentMapper learnTestStudentMapper, ILearnStudentService learnStudentService, IDzSubjectService dzSubjectService, LearnTeacherService learnTeacherService, LearnExamineeMapper learnExamineeMapper, LearnAnswerMapper learnAnswerMapper) {
        this.learnPaperMapper = learnPaperMapper;
        this.learnTestStudentMapper = learnTestStudentMapper;
        this.learnStudentService = learnStudentService;
        this.dzSubjectService = dzSubjectService;
        this.learnTeacherService = learnTeacherService;
        this.learnExamineeMapper = learnExamineeMapper;
        this.learnAnswerMapper = learnAnswerMapper;
    }

    public List<DzSubject> getSubjectList(boolean directed) {
        SysUser sysUser = SecurityUtils.getLoginUser().getUser();
        DzSubject sCond = new DzSubject();
        sCond.setLocations(sysUser.getLocation());
        sCond.setExamTypes(sysUser.getExamType().name());
        List<DzSubject> list = dzSubjectService.selectDzSubjectList(sCond);
        Set<Long> subjectIdSet;
        if (!directed) {
            if(!ExamType.VHS.equals(sysUser.getExamType())){
                return list;
            }
            subjectIdSet = Sets.newHashSet(1L, 2L, 3L);
            Integer userSubjectId = SecurityUtils.getLoginUser().getUser().getExamMajor();
            if(null != userSubjectId) {
                subjectIdSet.add(userSubjectId.longValue());
            }
        } else {
            LearnStudent learnStudent = learnStudentService.selectLearnStudentByStudentId(SecurityUtils.getUserId());
            if (null == learnStudent || CollectionUtils.isEmpty((subjectIdSet = learnTeacherService.getSubjectIdSet(new Long[]{learnStudent.getMajorPlanId()})))) {
                return list;
            }
        }
        return list.stream().filter(t -> subjectIdSet.contains(t.getSubjectId())).collect(Collectors.toList());
    }

    public List<Dict> selectStatsForStudent(Long studentId) {
        Integer undone = 0, done = 0;
        for(LearnTestStudent ts : learnTestStudentMapper.selectStatsForStudent(studentId)) {
            if(ts.getStatus() < ExamineeStatus.Exam.getVal()) {
                undone += ts.getCount();
            } else {
                done += ts.getCount();
            }
        }
        List<Dict> list = Lists.newArrayList();
        list.add(Dict.create().set("全部", undone + done));
        list.add(Dict.create().set("未完成", undone));
        list.add(Dict.create().set("已完成", done));
        return list;
    }

    public List<LearnPaper> selectLearnPaperForStudent(Long studentId, Integer status) {
        return learnPaperMapper.selectLearnPaperForStudent(studentId, status);
    }

    public List<JSONObject> getSimulateStat(Long examineeId) {
        List<JSONObject> stats = learnAnswerMapper.selectSimulatedKnowledgeStats(examineeId);
        stats.forEach(CommonUtils::normalRate);
        return stats;
    }

    public List<JSONObject> getSimulateList(Long studentId) {
        LearnExaminee eCond = new LearnExaminee();
        eCond.setStudentId(studentId);
        eCond.setPaperType(PaperType.Simulated.getVal());

        List<JSONObject> list = learnExamineeMapper.selectLearnExamineeList(eCond).stream().map(t -> {
            JSONObject info = JSONObject.parseObject(t.getPaperInfo());
            String name = null;
            if(null == info) {
                name = t.getPaperKey();
            } else if(StringUtils.isBlank(name = info.getString("paperName"))) {
                name = info.getString("universityName") + "-" + info.getString("majorName");
            }
            String[] paperKey = t.getPaperKey().split("_");
            DzSubject dzSubject = dzSubjectService.selectDzSubjectBySubjectId(Long.parseLong(paperKey[paperKey.length - 1]));
            return JSONObject.of("id", t.getExamineeId(), "state", t.getState()
                    , "subjectName", dzSubject.getSubjectName()
                    , "name", name
                    , "subjectGroup", (dzSubject.getSubjectId() < 10 ? "公共课" : "专业课")
                    , "date", DateUtils.format(null != t.getEndTime() ? t.getEndTime() : t.getBeginTime(), "yyyy-MM-dd HH:mm")
                    , "score", t.getScore());
        }).collect(Collectors.toList());

        return list;
    }

    public List<JSONObject> getTestList(Long studentId, Integer state) {
        List<JSONObject> list = learnTestStudentMapper.selectExamineeTestList(studentId, state);
        list.forEach(t -> {
            DzSubject dzSubject = dzSubjectService.selectDzSubjectBySubjectId(t.getLong("subjectId"));
            t.put("subjectName", dzSubject.getSubjectName());
            t.remove("beginTime");

            Date date = t.getDate("endTime");
            t.remove("endTime");
            if(null != date) {
                t.put("endTime", DateUtils.format(date, "yyyy-MM-dd HH:mm"));
            }

            date = t.getDate("publishTime");
            t.remove("publishTime");
            t.put("publishTime", DateUtils.format(date, "yyyy-MM-dd HH:mm"));

            t.put("directed", StringUtils.isNotBlank(t.getString("directKey")));
            t.remove("directKey");
        });
        return list;
    }
}
