package com.qmth.teachcloud.eds.service.impl;

import cn.hutool.core.date.DateUtil;
import com.alibaba.fastjson.JSON;
import com.qmth.teachcloud.eds.dao.StudentScoreMapper;
import com.qmth.teachcloud.eds.entity.*;
import com.qmth.teachcloud.eds.service.StudentScoreService;
import com.qmth.teachcloud.eds.utils.DateUtils;
import com.qmth.teachcloud.eds.utils.gdpu.JdbcUtil;
import com.qmth.teachcloud.eds.vo.ExamQuestion;
import com.qmth.teachcloud.eds.vo.ExamStudent;
import com.qmth.teachcloud.eds.vo.ScoreItem;
import com.qmth.teachcloud.eds.vo.ScoreVo;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import java.text.DecimalFormat;
import java.util.*;

/**
 * 考生成绩 服务实现类
 */
@Service
public class StudentScoreServiceImpl implements StudentScoreService {
    private final static Logger log = LoggerFactory.getLogger(StudentScoreServiceImpl.class);

    static final String[] chars = {"A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z"};

    // test为数据库名,?后面这句很重要,设置useSSl=false
//    static final String DB_URL = "jdbc:mysql://localhost:3309/stmms_ft?allowPublicKeyRetrieval=true&useSSL=false&serverTimezone=UTC&useUnicode=true&characterEncoding=utf8";
    static final String DB_URL = "jdbc:mysql://localhost:3306/stmms-ft-1.3.14?allowPublicKeyRetrieval=true&useSSL=false&serverTimezone=UTC&useUnicode=true&characterEncoding=utf8";
    // 数据库的用户名与密码，需要根据自己的设置
//    static final String USER = "stmms";
    static final String USER = "root";
    //    static final String PASS = "stmms";
    static final String PASS = "12345678";

    private final static Map<String, List<ExamQuestion>> questionMap = new HashMap<>();

    @Value("${markingcloud.local.examTime}")
    private Long markExamTime;

    @Resource
    private StudentScoreMapper studentScoreMapper;

    @Override
    public String syncStudentSocre() {
        Date date = new Date(markExamTime);
        String dateString = DateUtil.format(date, "yyyy-MM-dd HH:mm:ss");

//        String sql = "select a.exam_id examId, a.subject_code subjectCode, a.subject_name subjectName,a.student_code studentCode ,a.name,a.objective_score objectiveScore,a.subjective_score subjectiveScore,a.objective_score_list objectiveScoreList,a.subjective_score_list subjectiveScoreList from eb_exam_student a left join eb_exam b on a.exam_id = b.id where b.create_time >='" + dateString +"'";
        String sql = "select a.exam_id, a.subject_code, a.subject_name,a.student_code ,a.name,a.objective_score,a.subjective_score,a.objective_score_list,a.subjective_score_list from eb_exam_student a left join eb_exam b on a.exam_id = b.id where b.create_time >='" + dateString + "'";
//        String sql = "select * from eb_exam_student";

        List<ExamStudent> examStudentList = new JdbcUtil(DB_URL, USER, PASS).query(sql, ExamStudent.class);
        List<StudentScore> studentScoreList = new ArrayList<>();
        if (!CollectionUtils.isEmpty(examStudentList)) {
            studentScoreMapper.deleteExamStudent();

            Long createTime = System.currentTimeMillis();
            // 每一次进来都清空缓存结构
            questionMap.clear();

            for (ExamStudent examStudent : examStudentList) {
                StudentScore studentScore = new StudentScore();
                studentScore.setExamId(Long.valueOf(examStudent.getExamId()));
                studentScore.setCourseCode(parseSubjectCode(examStudent.getSubjectCode()));
                studentScore.setCourseName(examStudent.getSubjectName());
                studentScore.setCoursePaperId(examStudent.getSubjectCode());
                studentScore.setStudentCode(examStudent.getStudentCode());
                studentScore.setStudentName(examStudent.getName());
                studentScore.setTotalScore(examStudent.getTotalScore());
                // 客观题打分明细、主观题打分明细
                makeScoreList(examStudent, studentScore);
                studentScore.setCreateTime(createTime);

                studentScoreList.add(studentScore);
            }

            List<StudentScore> data = new ArrayList<>();
            //2000条提交一次
            for (StudentScore examStudent : studentScoreList) {
                if (data.size() == 2000) {
                    studentScoreMapper.insertExamStudent(data);
                    data.clear();
                }
                data.add(examStudent);
            }
            //将剩下的数据也导入
            if (!data.isEmpty()) {
                studentScoreMapper.insertExamStudent(data);
            }
        }

        return "设置考试日期为：[" + dateString + "]。本次成功查询[" + examStudentList.size() + "]条数据，成功处理[" + studentScoreList.size() + "]条数据";
    }

    /**
     * 解析云阅卷科目代码中的知学知考课程代码
     *
     * @param subjectCode 云阅卷科目代码
     */
    private String parseSubjectCode(String subjectCode) {
        int lastIndex = 0;
        for (String aChar : chars) {
            lastIndex = subjectCode.lastIndexOf(aChar);
            if (lastIndex > 0) {
                break;
            }
        }
        if (lastIndex > 0) {
            return subjectCode.substring(0, lastIndex);
        }
        return null;
    }

    private void makeScoreList(ExamStudent student, StudentScore studentScore) {
        // 构造客观题得分明细
        List<ScoreItem> scoreList = student.getScoreList(true);
        List<ExamQuestion> questionList = listQuestions(Long.valueOf(student.getExamId()), student.getSubjectCode(), true);
        int i = 0;
        DecimalFormat df = new DecimalFormat("####.###");
        List<ScoreVo> objectiveListDetail = new ArrayList<>();
        for (ScoreItem item : scoreList) {
            i++;
            if (questionList.size() < i) {
                break;
            }
            ExamQuestion question = questionList.get(i - 1);
            if (question.getTotalScore() == null || question.getTotalScore() == 0) {
                continue;
            }
            objectiveListDetail.add(new ScoreVo(String.valueOf(question.getMainNumber()), question.getSubNumber(), df.format(item.getScore()), StringUtils.trimToEmpty(item.getAnswer())));
        }
        studentScore.setObjectiveScoreList(JSON.toJSONString(objectiveListDetail));

        // 构造主观题得分明细
        scoreList = student.getScoreList(false);
        questionList = listQuestions(Long.valueOf(student.getExamId()), student.getSubjectCode(), false);
        List<ScoreVo> subjectiveListDetail = new ArrayList<>();
        i = 0;
        for (ScoreItem item : scoreList) {
            i++;
            if (questionList.size() < i) {
                break;
            }
            ExamQuestion question = questionList.get(i - 1);
            if (question.getTotalScore() == null || question.getTotalScore() == 0) {
                continue;
            }
            subjectiveListDetail.add(new ScoreVo(String.valueOf(question.getMainNumber()), question.getSubNumber(), df.format(item.getScore())));
        }
        studentScore.setSubjectiveScoreList(JSON.toJSONString(subjectiveListDetail));
    }

    /**
     * 查询科目试卷结构
     *
     * @param examId      考试ID
     * @param subjectCode 科目代码
     * @param objective   是否客观题
     * @return list
     */
    private List<ExamQuestion> listQuestions(Long examId, String subjectCode, boolean objective) {
        String key = examId + subjectCode;
        if (questionMap.containsKey(key)) {
            return questionMap.get(key);
        }

        String sql = "select * from eb_exam_question where exam_id =" + examId + " and subject_code = '" + subjectCode + "' and is_objective =" + objective;
        List<ExamQuestion> questionList = new JdbcUtil(DB_URL, USER, PASS).query(sql, ExamQuestion.class);
        questionMap.putIfAbsent(key, questionList);
        return questionList;
    }
}

