package com.ruoyi.test.seriver.Impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ruoyi.system.service.ISysUserService;
import com.ruoyi.test.domain.*;
import com.ruoyi.test.domain.DO.Correct;
import com.ruoyi.test.domain.DO.QuestionAnswerDO;
import com.ruoyi.test.domain.DO.ScoreListDO;
import com.ruoyi.test.domain.Vo.QuestionanswerVo;
import com.ruoyi.test.domain.Vo.QuestionbankVo;
import com.ruoyi.test.mapper.AnswerMapper;
import com.ruoyi.test.mapper.ExamPaperMapper;
import com.ruoyi.test.mapper.MarkedtestMapper;
import com.ruoyi.test.mapper.StudentClassMapper;
import com.ruoyi.test.seriver.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.PageRequest;
import org.springframework.security.core.parameters.P;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;

@Service
public class MarkedtestServiceImpl extends ServiceImpl<MarkedtestMapper, Markedtest> implements IMarkedtestService {

    @Autowired
    private StudentClassMapper studentClassMapper;

    @Autowired
    private MarkedtestMapper markedtestMapper;

    @Autowired
    private AnswerMapper answerMapper;

    @Autowired
    private ExamPaperMapper examPaperMapper;

    @Autowired
    private IQuestionanswerService iQuestionanswerService;

    @Autowired
    private IAnswerService iAnswerService;

    @Autowired
    private IExamPaperService iExamPaperService;

    @Autowired
    private ISysUserService iSysUserService;

    @Autowired
    private ITeacherSubjectService iTeacherSubjectService;

    @Autowired
    private ITeacherManageClassService iTeacherManageClassService;

    @Override
    public int addmarkedtest(Long senderId,Long testid) {
        QuestionAnswerDO questionAnswerDO = iQuestionanswerService.selectQuestionanswer(senderId,testid);

        double totalscore = 0;
        double score = 0;
        int tquestions = 0;
        int totalquestions = 0;

        List<QuestionanswerVo> list = questionAnswerDO.getList();

        for(QuestionanswerVo questionanswerVo : list){
            String tf = questionanswerVo.getTf();
            if(tf.equals("true")){
                score+=questionanswerVo.getScore();
                tquestions++;
            }
            totalscore+=questionanswerVo.getScore();
            totalquestions++;
        }

        Answer answer = iAnswerService.selectByTestId(senderId, testid);

        Markedtest markedtest = new Markedtest();
        markedtest.setSenderId(senderId);
        markedtest.setTestid(testid);
        markedtest.setScore(score);
        markedtest.setTotalscore(totalscore);
        markedtest.setFinishtime(answer.getFinishtime());
        markedtest.setTime(answer.getTime());
        markedtest.setTquestions(tquestions);
        markedtest.setTotalquestions(totalquestions);
        markedtest.setStatus(0L);
        return markedtestMapper.addmarkedtest(markedtest);
    }

    @Override
    public IPage<Markedtest> selectmarkedtest(int pagenum) {
        Page<Markedtest> page = new Page<>(pagenum,10);
        LambdaQueryWrapper<Markedtest> queryWrapper = new LambdaQueryWrapper<>();
        IPage iPage = markedtestMapper.selectPage(page,queryWrapper);
        return iPage;
    }

    @Override
    public IPage<Markedtest> selectmarkedtestBySubject(int pagenum,String subject){
        Page<ExamPaper> page = new Page<>(pagenum,10);
        LambdaQueryWrapper<ExamPaper> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(ExamPaper::getSubject,subject);
        IPage<ExamPaper> iPage = examPaperMapper.selectPage(page,queryWrapper);
        List<ExamPaper> list = page.getRecords();
        List<Markedtest> list1 = new ArrayList<>();
        for(ExamPaper examPaper : list){
            Long id = examPaper.getId();
            LambdaQueryWrapper<Markedtest> queryWrapper1 = new LambdaQueryWrapper<>();
            queryWrapper1.eq(Markedtest::getTestid,id);
            List<Markedtest> l = markedtestMapper.selectList(queryWrapper1);
            list1.addAll(l);
        }
        IPage<Markedtest> pageVo = new Page<>(page.getCurrent(), page.getSize(), page.getTotal());
        pageVo.setRecords(list1);
        return pageVo;
    }

    @Override
    public IPage<Markedtest> selectmarkedtest(int pagenum, List<StudentClass> list1) {
        List<Markedtest> list = new ArrayList<>();
        for(StudentClass studentClass : list1){
            LambdaQueryWrapper<Markedtest> queryWrapper = new LambdaQueryWrapper<>();
            list.addAll(markedtestMapper.selectList(queryWrapper));
        }
        Page<Markedtest> page = new Page<>(pagenum,10);
        IPage<Markedtest> iPage = new Page<>(page.getCurrent(),page.getSize(),page.getTotal());
        iPage.setRecords(list);
        return iPage;
    }

    @Override
    public IPage<Markedtest> selectmarkedtestBySubject(int pagenum, List<StudentClass> list, String subject) {
        LambdaQueryWrapper<ExamPaper> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(ExamPaper::getSubject,subject);
        List<ExamPaper> list1  = examPaperMapper.selectList(queryWrapper);
        List<Long> list2 = new ArrayList<>();
        for(ExamPaper examPaper : list1){
            list2.add(examPaper.getId());
        }
        List<Markedtest> list3 = new ArrayList<>();
        for(StudentClass studentClass : list){
            LambdaQueryWrapper<Markedtest> queryWrapper1 = new LambdaQueryWrapper<>();
            List<Markedtest> list4 = markedtestMapper.selectList(queryWrapper1);
            for(Markedtest markedtest : list4){
                if(list2.contains(markedtest.getTestid())){
                    list3.add(markedtest);
                }
            }
        }
        Page<Markedtest> page = new Page<>(pagenum,10);
        IPage<Markedtest> iPage = new Page<>(page.getCurrent(),page.getSize(),page.getTotal());
        iPage.setRecords(list3);
        return iPage;
    }

    @Override
    public List<Markedtest> selectmarkedtestListSenderId(Long senderId) {
        LambdaQueryWrapper<Markedtest> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Markedtest::getSenderId,senderId)
                .eq(Markedtest::getStatus,1L);
        return markedtestMapper.selectList(queryWrapper);
    }

    @Override
    public Markedtest selectmarkedtestBySenderId(Long senderId) {
        LambdaQueryWrapper<Markedtest> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Markedtest::getSenderId,senderId);
        return markedtestMapper.selectOne(queryWrapper);
    }

    @Override
    public Markedtest selectmarkedtestBySenderIdAndTestid(Long senderId, Long testId) {
        LambdaQueryWrapper<Markedtest> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Markedtest::getTestid,testId)
                .eq(Markedtest::getSenderId,senderId);
        return markedtestMapper.selectOne(queryWrapper);
    }

    @Override
    public Markedtest selectmarkedtestByTestid(Long id, Long testId) {
        LambdaQueryWrapper<Markedtest> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Markedtest::getSenderId,id)
                .eq(Markedtest::getTestid,testId)
                .eq(Markedtest::getStatus,1L);
        return markedtestMapper.selectOne(queryWrapper);
    }

    @Override
    public List<Correct> selectByStudentList(Long id,List<Long> list) {
        List<String> teacherSubjectList = iTeacherSubjectService.select(id);
        List<String> teacherManageClasses = iTeacherManageClassService.selectByTeacherId(id);
        LambdaQueryWrapper<ExamPaper> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.in(ExamPaper::getSubject,teacherSubjectList)
                .in(ExamPaper::getGrade,teacherManageClasses);
        List<ExamPaper> examPapers = examPaperMapper.selectList(queryWrapper);
        List<Correct> list1 = list.stream()
                .flatMap(studentId -> {
                    List<Correct> list2 = new ArrayList<>();

                    for(ExamPaper examPaper : examPapers){
                        Correct correct = new Correct();
                        correct.setSubject(examPaper.getSubject());
                        correct.setTestId(examPaper.getId());
                        correct.setName(examPaper.getName());
                        correct.setSenderName(iSysUserService.selectUserById(studentId).getUserName());
                        correct.setSendId(studentId);

                        if(iAnswerService.selectBySenderIdAndTestId(studentId,examPaper.getId())){
                            LambdaQueryWrapper<Markedtest> queryWrapper1 = new LambdaQueryWrapper<>();
                            queryWrapper1.eq(Markedtest::getSenderId,studentId)
                                    .eq(Markedtest::getTestid,examPaper.getId());
                            if(markedtestMapper.selectCount(queryWrapper1)>0){
                                correct.setStatus(0);
                            }else{
                                correct.setStatus(1);
                            }
                        }else{
                            correct.setStatus(2);
                        }
                        list2.add(correct);
                    }

                    return list2.stream();
                })
                .collect(Collectors.toList());

        return list1;
    }

    @Override
    public List<ScoreListDO> selectScoreList(Long testid, String grade, String Class1) {
        LambdaQueryWrapper<StudentClass> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(StudentClass::getGrade,grade)
                .eq(StudentClass::getClass1,Class1);
        List<StudentClass> list = studentClassMapper.selectList(queryWrapper);
        List<ScoreListDO> list1 = new ArrayList<>();
        for(StudentClass studentClass : list){
            ScoreListDO scoreListDO = new ScoreListDO();
            scoreListDO.setTestid(testid);
            scoreListDO.setSenderId(studentClass.getStudentid());
            scoreListDO.setSenderName(iSysUserService.selectUserById(studentClass.getStudentid()).getUserName());
            LambdaQueryWrapper<Markedtest> queryWrapper1 = new LambdaQueryWrapper<>();
            queryWrapper1.eq(Markedtest::getTestid,testid)
                    .eq(Markedtest::getSenderId,studentClass.getStudentid());
            Markedtest markedtest = markedtestMapper.selectOne(queryWrapper1);
            if(markedtest==null){
                scoreListDO.setScore(null);
            }else{
                scoreListDO.setScore(markedtest.getScore());
            }
            list1.add(scoreListDO);
        }
        list1.sort((o1, o2) -> {
            // 处理 null 分数的情况
            Double score1 = o1.getScore();
            Double score2 = o2.getScore();

            // 如果两个分数都为 null，认为它们相等
            if (score1 == null && score2 == null) {
                return 0;
            }

            // 如果分数1是 null，分数2不是 null，则分数1排在后面
            else if (score1 == null) {
                return 1;
            }

            // 如果分数2是 null，分数1不是 null，则分数2排在后面
            else if (score2 == null) {
                return -1;
            }

            // 否则按分数降序排列
            else {
                return Double.compare(o2.getScore(), o1.getScore());
            }
        });

        // 为每个ScoreListDO设置排名
        int rank = 1;
        for (int i = 0; i < list1.size(); i++) {
            ScoreListDO scoreListDO = list1.get(i);

            // 如果当前分数与前一个分数相同，则排名相同
            if (i > 0 && scoreListDO.getScore() != null && scoreListDO.getScore().equals(list1.get(i - 1).getScore())) {
                scoreListDO.setRanking(list1.get(i - 1).getRanking());
            } else if (scoreListDO.getScore() != null) {
                // 如果当前分数不为 null，设置当前排名
                scoreListDO.setRanking(rank);
            } else {
                // 如果分数为 null，直接设置一个排名值，跳过之前的排名
                scoreListDO.setRanking(rank);
            }

            // 增加排名
            rank++;
        }
        return list1;
    }

    @Override
    public Integer fabu(Long testid, String grade, String Class1) {
        LambdaQueryWrapper<StudentClass> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(StudentClass::getGrade,grade)
                .eq(StudentClass::getClass1,Class1);
        List<Long> list = studentClassMapper.selectList(queryWrapper).stream()
                .map(StudentClass::getStudentid)
                .collect(Collectors.toList());

        if(examPaperMapper.updateExamPaper(testid)>0){
            if(markedtestMapper.updateStatusBatch(testid,list)>0){
                return 1;
            }
            return -1;
        }
        return -1;
    }


}