package com.ssj.dao.kmt.kmt.dao.impl;

import com.ssj.dao.kmt.kmt.dao.KmtCorrectHomeworkQueryDao;
import com.ssj.framework.core.persistence.PagingHibernateJdbcDao;
import com.ssj.service.kmt.dto.OriginalQuestionDTO;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Repository;

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

/**
 * @author yrf
 * @date 2019/1/21 11:22
 */
@Repository
public class KmtCorrectHomeworkQueryDaoImpl implements KmtCorrectHomeworkQueryDao {

    @Autowired
    private PagingHibernateJdbcDao pagingHibernateJdbcDao;

    @Override
    public Map<String, Object> findHomeworkInfoByHomeworkPictureId(String homeworkPictureId) {
        String sql =
                "select tb_lib_vip.grade, scon_homework.subject, tb_lib_vip.banben\n" +
                "from scon_homework_picture, scon_homework, tb_lib_vip\n" +
                "where scon_homework_picture.homework_id = scon_homework.id \n" +
                "  and scon_homework.vip_id = tb_lib_vip.id\n" +
                "  and scon_homework_picture.id = ? ";

        List<Map<String, Object>> mapList = pagingHibernateJdbcDao.findMap(sql, Collections.singleton(homeworkPictureId).toArray());
        if (CollectionUtils.isEmpty(mapList)) {
            return null;
        } else {
            return mapList.get(0);
        }
    }

    @Override
    public Page<Map<String, Object>> findWrongQuestionByPage(Map<String, Object> searchParams, Pageable pageable){
        StringBuilder selSql = new StringBuilder();
        List<Object> queryParams = new ArrayList<>();
        selSql.append("select\n" +
                "  t.question_id,\n" +
                "  t2.book_name,\n" +
                "  t2.unit,\n" +
                "  t2.period,\n" +
                "  t1.question,\n" +
                "  t1.option_content,\n" +
                "  t1.option_answer,\n" +
                "  t3.question big_question\n" +
                "from (select\n" +
                "        question_id,\n" +
                "        student_id,\n" +
                "        max(create_time) create_time\n" +
                "      from kmt_homework_wrong_question\n" +
                "      where is_delete = 0 and type = 1\n" +
                "      group by question_id, student_id) t\n" +
                "  left join kmt_exercise_questions t1 on t.question_id = t1.id\n" +
                "  left join kmt_exercise_book_course t2 on t1.book_course_id = t2.id\n" +
                "  left join kmt_exercise_questions t3 on t1.parent_id = t3.id" +
                "  where 1=1 ");
        //会员id
        String vipId= (String) searchParams.get("vipId");
        selSql.append(" and t.student_id = ?");
        queryParams.add(vipId);
        //科目
        String subject = (String) searchParams.get("subject");
        if (StringUtils.isNotBlank(subject)) {
            selSql.append(" and t2.course_name = ?");
            queryParams.add(subject);
        }
        //0：全部，1：近一月，2：近一周
        int type = (int)searchParams.get("type");
        if (type == 1) {
            selSql.append(" and DATE_SUB(CURDATE(), INTERVAL 30 DAY) <= date(t.create_time)");
        } else if (type == 2) {
            selSql.append(" and DATE_SUB(CURDATE(), INTERVAL 7 DAY) <= date(t.create_time)");
        }
        //当前时间
        String maxCreateTime = (String) searchParams.get("maxCreateTime");
        if (StringUtils.isNotBlank(maxCreateTime)) {
            selSql.append(" and t.create_time <= ?");
            queryParams.add(maxCreateTime);
        }
        selSql.append(" order by t2.book_name asc, t2.unit asc, t2.period asc, t3.question asc, t1.question asc ");
        return pagingHibernateJdbcDao.findPage(selSql.toString(), queryParams.toArray(), pageable);
    }

    @Override
    public Page<Map<String, Object>> findWrongQuestionNewByPage(Map<String, Object> searchParams, Pageable pageable) {
        StringBuilder selSql = new StringBuilder();
        List<Object> queryParams = new ArrayList<>();
        selSql.append("select *\n" +
                "from (select t.question_id,\n" +
                "             t1.question,\n" +
                "             t1.option_content,\n" +
                "             t1.option_answer,\n" +
                "             t3.question big_question,\n" +
                "             t.create_time,\n" +
                "             ''          homework_id\n" +
                "      from (select question_id,\n" +
                "                   max(create_time) create_time\n" +
                "            from kmt_homework_wrong_question\n" +
                "            where is_wrong_ques_delete = 0\n" +
                "              and type = 1\n" +
                "              and student_id = ?\n" +
                "            group by question_id) t\n" +
                "               left join kmt_exercise_questions t1 on t.question_id = t1.id\n" +
                "               left join kmt_exercise_questions t3 on t1.parent_id = t3.id\n" +
                "      where 1 = 1\n" +
                "        and exists(\n" +
                "              select 1\n" +
                "              from zyb_know_how_details s1\n" +
                "                       join kmt_exercise_question_know s2 on s1.id = s2.how_details_id\n" +
                "              where s2.question_id = t.question_id\n");
        if ("语文".equals(searchParams.get("subject").toString()) || "数学".equals(searchParams.get("subject").toString())) {
            selSql.append("and s1.two_module = ?\n");
        } else {
            selSql.append("and s1.module = ?\n");
        }
        selSql.append("          )\n" +
                "      union\n" +
                "      select ''                 question_id,\n" +
                "             ''                 question,\n" +
                "             ''                 option_content,\n" +
                "             ''                 option_answer,\n" +
                "             ''                 big_question,\n" +
                "             max(t.create_time) create_time,\n" +
                "             t.homework_id\n" +
                "      from scon_homework_how_details t\n" +
                "      where t.detail_count > 0\n" +
                "        and t.is_wrong_ques_delete = 0\n" +
                "        and exists(\n" +
                "              select 1\n" +
                "              from zyb_know_how_details s1\n" +
                "              where t.how_detail_id = s1.id\n");
        if ("语文".equals(searchParams.get("subject").toString()) || "数学".equals(searchParams.get("subject").toString())) {
            selSql.append("and s1.two_module = ?\n");
        } else {
            selSql.append("and s1.module = ?\n");
        }
        selSql.append("          )\n" +
                "        and exists(\n" +
                "              select 1\n" +
                "              from scon_homework s2\n" +
                "              where t.homework_id = s2.id\n" +
                "                and s2.vip_id = ?\n" +
                "          )\n" +
                "      group by t.homework_id) t\n");
        //会员id
        String vipId = (String) searchParams.get("vipId");
        //模块
        String module = (String) searchParams.get("module");
        queryParams.add(vipId);
        queryParams.add(module);
        queryParams.add(vipId);
        queryParams.add(module);
        //当前时间
        String maxCreateTime = (String) searchParams.get("maxCreateTime");
        if (StringUtils.isNotBlank(maxCreateTime)) {
            selSql.append(" and t.create_time <= ?");
            queryParams.add(maxCreateTime);
        }
        selSql.append(" order by t.create_time desc ");
        return pagingHibernateJdbcDao.findPage(selSql.toString(), queryParams.toArray(), pageable);
    }

    @Override
    public List<Map<String, Object>> findQuestionList(List<String> homeworkPictureIdList) {
        String sql =
                "select kmt_homework_wrong_question.homework_picture_id, kmt_exercise_questions.question_path, kmt_exercise_questions.parent_id\n" +
                "from kmt_homework_wrong_question,\n" +
                "     kmt_exercise_questions\n" +
                "where kmt_homework_wrong_question.question_id = kmt_exercise_questions.id\n" +
                "  and kmt_homework_wrong_question.type = 1\n" +
                "  and kmt_homework_wrong_question.is_delete = 0\n" +
                "  and kmt_homework_wrong_question.is_wrong_ques_delete = 0\n" +
                "  and kmt_homework_wrong_question.homework_picture_id in ('" +  StringUtils.join(homeworkPictureIdList, "','") + "')";

        return pagingHibernateJdbcDao.findMap(sql, new Object[]{});
    }

    @Override
    public List<OriginalQuestionDTO> findQuestionContainParentAndBrotherList(List<String> homeworkPictureIdList) {
        String homeworkPictureIdStr = "('" + StringUtils.join(homeworkPictureIdList, "','") + "')";
        String sql =
                "select parentQuestion.id, parentQuestion.book_id, parentQuestion.parent_id, parentQuestion.num, parentQuestion.question, 0 as is_wrong\n" +
                "from kmt_exercise_questions parentQuestion,\n" +
                "     kmt_exercise_questions,\n" +
                "     kmt_homework_wrong_question\n" +
                "where kmt_homework_wrong_question.question_id = kmt_exercise_questions.id\n" +
                "  and kmt_exercise_questions.parent_id = parentQuestion.id\n" +
                "  and kmt_homework_wrong_question.type = 1\n" +
                "  and kmt_homework_wrong_question.is_delete = 0\n" +
                "  and kmt_homework_wrong_question.is_wrong_ques_delete = 0\n" +
                "  and kmt_homework_wrong_question.homework_picture_id in " + homeworkPictureIdStr + "\n" +
                "union all\n" +
                "select self.id,\n" +
                "       self.book_id,\n" +
                "       self.parent_id,\n" +
                "       self.num,\n" +
                "       self.question,\n" +
                "       1 as is_wrong\n" +
                "from kmt_exercise_questions self,\n" +
                "     kmt_homework_wrong_question\n" +
                "where kmt_homework_wrong_question.question_id = self.id\n" +
                "  and kmt_homework_wrong_question.type = 1\n" +
                "  and kmt_homework_wrong_question.is_delete = 0\n" +
                "  and kmt_homework_wrong_question.is_wrong_ques_delete = 0\n" +
                "  and kmt_homework_wrong_question.homework_picture_id  in " + homeworkPictureIdStr + "\n" +
                "union all\n" +
                "select brotherQuestion.id, brotherQuestion.book_id, brotherQuestion.parent_id, brotherQuestion.num, brotherQuestion.question, 0 as is_wrong\n" +
                "from kmt_exercise_questions brotherQuestion,\n" +
                "     kmt_exercise_questions,\n" +
                "     kmt_homework_wrong_question\n" +
                "where brotherQuestion.parent_id = kmt_exercise_questions.parent_id\n" +
                "  and length(kmt_exercise_questions.parent_id) > 0\n" +
                "  and kmt_homework_wrong_question.question_id = kmt_exercise_questions.id\n" +
                "  and kmt_homework_wrong_question.type = 1\n" +
                "  and kmt_homework_wrong_question.is_delete = 0\n" +
                "  and kmt_homework_wrong_question.is_wrong_ques_delete = 0\n" +
                "  and kmt_homework_wrong_question.homework_picture_id  in " + homeworkPictureIdStr + "\n";

        List<OriginalQuestionDTO> mapList = pagingHibernateJdbcDao.findList(sql, OriginalQuestionDTO.class);

        return mapList.stream()
                .collect(Collectors.collectingAndThen(Collectors.toCollection(
                () -> new TreeSet<>(Comparator.comparing(OriginalQuestionDTO::getId))), ArrayList::new)).stream()
                .sorted((question1, question2) -> {
                    String bookId1 = Optional.ofNullable(question1.getBookId()).orElse("");
                    String bookId2 = Optional.ofNullable(question2.getBookId()).orElse("");
                    Integer num1 = Optional.ofNullable(question1.getNum()).orElse(0);
                    Integer num2 = Optional.ofNullable(question2.getNum()).orElse(0);
                    return Objects.equals(bookId1, bookId2) ? num1 - num2 : bookId1.compareTo(bookId2);
                })
                .collect(Collectors.toList());
    }

    @Override
    public List<Map<String, Object>> findFullBigQuestion(String questionId) {
        String sql =
                "select parentQuestion.id, 2 as type, parentQuestion.question, parentQuestion.num\n" +
                "from kmt_exercise_questions parentQuestion,\n" +
                "     kmt_exercise_questions\n" +
                "where kmt_exercise_questions.parent_id = parentQuestion.id\n" +
                "  and kmt_exercise_questions.id = ?\n" +
                "union all\n" +
                "select self.id, 1 as type, self.question, self.num\n" +
                "from kmt_exercise_questions self\n" +
                "where self.id = ?\n" +
                "union all\n" +
                "select brotherQuestion.id, 1 as type, brotherQuestion.question, brotherQuestion.num\n" +
                "from kmt_exercise_questions brotherQuestion,\n" +
                "     kmt_exercise_questions\n" +
                "where brotherQuestion.parent_id = kmt_exercise_questions.parent_id\n" +
                "  and length(kmt_exercise_questions.parent_id) > 0\n" +
                "  and brotherQuestion.id <> kmt_exercise_questions.id\n" +
                "  and kmt_exercise_questions.id = ?";

        List<Object> paramList = new ArrayList<>();
        paramList.add(questionId);
        paramList.add(questionId);
        paramList.add(questionId);

        return pagingHibernateJdbcDao.findMap(sql, paramList.toArray()).stream()
                .sorted(Comparator.comparingInt(it -> Integer.parseInt(it.get("num").toString())))
                .collect(Collectors.toList());
    }
}
