package com.ssj.dao.conch.parents.dao.impl;

import com.ssj.dao.conch.parents.dao.ParentsV1QueryDao;
import com.ssj.framework.core.persistence.PagingHibernateJdbcDao;
import com.ssj.framework.weixin.util.DateUtil;
import com.ssj.service.conch.parents.v1.dto.BookDTO;
import com.ssj.service.conch.parents.v2.dto.KnowHowDetailDTO;
import com.ssj.service.conch.parents.v2.dto.WrongBookKnowledgeDTO;
import com.ssj.service.conch.parents.v2.dto.WrongBookQuestionDTO;
import com.ssj.service.conch.parents.v2.request.WrongBookQuestionReq2;
import com.ssj.service.conch.parents.v2.request.WrongBookQuestionReq3;
import com.ssj.service.kmt.constant.KnowledgeVersion;
import com.ssj.service.kmt.service.KmtExerciseQuestionService;
import com.ssj.service.kmt.service.KmtHomeworkWrongQuestionService;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
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.text.ParseException;
import java.time.DayOfWeek;
import java.time.LocalDate;
import java.util.*;
import java.util.stream.Collectors;


@Repository
public class ParentsV1QueryDaoImpl implements ParentsV1QueryDao {

	private final Logger logger = LoggerFactory.getLogger(this.getClass());

	@Autowired
	private PagingHibernateJdbcDao dao;
	@Autowired
	private KmtHomeworkWrongQuestionService kmtHomeworkWrongQuestionService;
	@Autowired
	private KmtExerciseQuestionService kmtExerciseQuestionService;

	@Override
	public List<Map<String, Object>> getChildEasemobList(String userId) {
		StringBuffer selSql = new StringBuffer();
		List<Object> queryParams = new ArrayList<Object>();
		selSql.append("select u.id,u.easemob_name,v.child_name,v.img_url,v.derver,count(if(m.is_read=0,true,null)) as unreadnum ");
		selSql.append("from tb_user u LEFT JOIN tb_lib_vip v ON u.id = v.child_user_id ");
		selSql.append("LEFT JOIN ssj_user_message m ON m.send_user_id = v.child_user_id and m.receive_user_id = v.user_id ");
		selSql.append("where v.user_id = ? ");
		selSql.append("GROUP BY v.child_user_id");
		queryParams.add(userId);
		return dao.findMap(selSql.toString(), queryParams.toArray());
	}

	@Override
	public List<Map<String, Object>> parentsRoleList(String vipId) {
		StringBuffer selSql = new StringBuffer();
		List<Object> queryParams = new ArrayList<Object>();
		selSql.append("SELECT p.name,p.role_name,p.role_user_id from ssj_parent_role p ");
		selSql.append("where p.vip_id = ? ");
		queryParams.add(vipId);
		return dao.findMap(selSql.toString(), queryParams.toArray());
	}

	@Override
	public List<Map<String, Object>> getOtherChildEasemobList(String userId) {
		StringBuffer selSql = new StringBuffer();
		List<Object> queryParams = new ArrayList<Object>();
		selSql.append("select u.id,u.easemob_name,v.child_name,v.img_url,v.derver,count(if(m.is_read=0,true,null)) as unreadnum from ssj_parent_role p ");
		selSql.append("LEFT JOIN tb_lib_vip v ON v.id = p.vip_id ");
		selSql.append("LEFT JOIN tb_user u ON u.id = v.child_user_id ");
		selSql.append("LEFT JOIN ssj_user_message m ON m.send_user_id = v.child_user_id and m.receive_user_id = p.role_user_id ");
		selSql.append("where p.role_user_id = ? GROUP BY v.child_user_id");
		queryParams.add(userId);
		return dao.findMap(selSql.toString(), queryParams.toArray());
	}

    @Override
    public List<BookDTO> findChildBookList(String vipId) {
		String sql =
				"select book_id, book_name, subject, version\n" +
				"from tb_lib_vip_book\n" +
				"where vip_id = ?\n";

		List<BookDTO> bookDTOList = dao.findList(sql, Collections.singletonList(vipId).toArray(), BookDTO.class);
		if (CollectionUtils.isNotEmpty(bookDTOList)) {
			KnowledgeVersion knowledgeVersion = new KnowledgeVersion();
			knowledgeVersion.init();

			bookDTOList.forEach(bookDTO -> bookDTO.setVersionName(knowledgeVersion.getVersionNameBySubjectAndVersionNum(bookDTO.getSubject(), bookDTO.getVersion())));
		}

		return bookDTOList;
    }

	@Override
	public Page<WrongBookKnowledgeDTO> findWrongQuestionKnowledgePage(String vipId, String subject, String module, Pageable pageable) {
		StringBuilder sql = new StringBuilder();
		sql.append("select zyb_know_how_details.id know_how_detail_id,\n");
		sql.append("       zyb_know_how_details_sort.alias knowledge_alias,\n");
		sql.append("       count(distinct scon_homework_picture.id) wrong_question_sum\n");
		sql.append("from zyb_know_how_details_sort,\n");
		sql.append("     zyb_know_how_details,\n");
		sql.append("     scon_homework_how_details,\n");
		sql.append("     scon_homework_picture,\n");
		sql.append("     tb_lib_vip\n");
		sql.append("where zyb_know_how_details_sort.stat = 2\n");
		sql.append("  and zyb_know_how_details_sort.course_name = ?\n");
		sql.append("  and zyb_know_how_details_sort.how_details_id = zyb_know_how_details.id\n");
		if ("语文".equals(subject)) {
			sql.append("  and zyb_know_how_details.two_module = ?\n");
		} else {
			sql.append("  and zyb_know_how_details.module = ?\n");
		}
		sql.append("  and zyb_know_how_details.id = scon_homework_how_details.how_detail_id\n");
		sql.append("  and scon_homework_how_details.is_wrong_ques_delete = 0\n");
		sql.append("  and scon_homework_how_details.detail_count > 0\n");
		sql.append("  and zyb_know_how_details_sort.type = scon_homework_how_details.knowledge_version\n");
		sql.append("  and scon_homework_how_details.homework_picture_id = scon_homework_picture.id\n");
		sql.append("  and scon_homework_picture.vip_id = tb_lib_vip.id\n");
		sql.append("  and tb_lib_vip.id = ?\n");
		sql.append("group by know_how_detail_id\n");

		List<Object> paramList = new ArrayList<>();
		paramList.add(subject);
		paramList.add(module);
		paramList.add(vipId);

		return dao.findPage(sql.toString(), paramList.toArray(), pageable, WrongBookKnowledgeDTO.class);
	}

	@Override
	public Page<WrongBookQuestionDTO> findWrongBookQuestionPage(String vipId, String knowHowDetailId, Pageable pageable) {

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

		String sql =
				"select temp.homework_id, temp.create_time, group_concat(temp.picture_url) picture_url_str\n" +
				"from (select scon_homework_picture.homework_id,\n" +
				"             date(scon_homework_how_details.create_time) create_time,\n" +
				"             if(length(scon_homework_picture.corrected_picture_url) > 0, scon_homework_picture.corrected_picture_url,\n" +
				"                scon_homework_picture.file_key)          picture_url\n" +
				"      from scon_homework_picture,\n" +
				"           scon_homework_how_details\n" +
				"      where scon_homework_picture.id = scon_homework_how_details.homework_picture_id\n" +
				"        and scon_homework_how_details.is_wrong_ques_delete = 0\n" +
				"        and scon_homework_how_details.detail_count > 0\n" +
				"        and scon_homework_picture.vip_id = ?\n" +
				"        and scon_homework_how_details.how_detail_id = ?\n" +
				"      group by create_time, scon_homework_how_details.homework_picture_id\n" +
				"     ) temp\n" +
				"group by create_time\n" +
				"order by create_time desc, homework_id\n";

		Page<WrongBookQuestionDTO> page = dao.findPage(sql, paramList.toArray(), pageable, WrongBookQuestionDTO.class);
		page.getContent().forEach(it -> {
			Date createTime = it.getCreateTime();
			if (createTime != null) {
				it.setWeek(DateUtil.getWeekDateToStr(createTime));
			}

			String pictureUrlStr = it.getPictureUrlStr();
			if (StringUtils.isNotBlank(pictureUrlStr)) {
				List<Map<String, Object>> pictureList = new ArrayList<>();
				List<String> pictureUrlList = Arrays.asList(pictureUrlStr.split(","));
				pictureUrlList.forEach(pictureUrl -> pictureList.add(Collections.singletonMap("pictureUrl", pictureUrl)));
				it.setPictureList(pictureList);
			}
		});

		return page;
	}

	@Override
	public Page<WrongBookQuestionDTO> findWrongBookQuestionPage3(WrongBookQuestionReq3 req, Pageable pageable) {
		String vipId = req.getVipId();
		List<KnowHowDetailDTO> knowHowDetailDTOList = req.getKnowHowDetailList();
		Integer type = req.getType();
		List<Object> paramList = new ArrayList<>();

		StringBuilder beginDateTimeSb = new StringBuilder();
		StringBuilder endDateTimeSb = new StringBuilder();
		if (Objects.equals(3, type)) {
			Date beginDateTime = DateUtil.getEndOfLastWeek(new Date());
			LocalDate today = LocalDate.now();
			if (!Objects.equals(today.getDayOfWeek().getValue(), DayOfWeek.SUNDAY.getValue())) {
				beginDateTime = DateUtil.addDays(beginDateTime, -7);
			}
			Date endDateTime = DateUtil.getDateAfter(beginDateTime, 6);
			beginDateTimeSb.append(DateUtil.format_yyyyMMdd(beginDateTime)).append(" 00:00:00");
			endDateTimeSb.append(DateUtil.format_yyyyMMdd(endDateTime)).append(" 23:59:59");
		} else {
			if (StringUtils.isNotBlank(req.getBeginDate())) {
				try {
					beginDateTimeSb.append(DateUtil.format_yyyyMMdd(DateUtil.parseDate(req.getYear() + "." + req.getBeginDate(), "yyyy.MM.dd"))).append(" 00:00:00");
				} catch (ParseException e) {
					logger.warn("错题本错题列表3：开始时间格式错误[{}]", req.getBeginDate());
				}
			}
			if (StringUtils.isNotBlank(req.getEndDate())) {
				try {
					endDateTimeSb.append(DateUtil.format_yyyyMMdd(DateUtil.parseDate(req.getYear() + "." + req.getEndDate(), "yyyy.MM.dd"))).append(" 23:59:59");
				} catch (ParseException e) {
					logger.warn("错题本错题列表3：结束时间格式错误[{}]", req.getBeginDate());
				}
			}
		}

		StringBuilder sql = new StringBuilder("select temp.homework_id, temp.create_time, group_concat(temp.homework_picture_id) homework_picture_id_str, group_concat(temp.picture_url) picture_url_str from (\n");
		knowHowDetailDTOList.forEach(knowHowDetailDTO -> {
			sql.append("(select scon_homework_picture.id homework_picture_id, scon_homework_picture.homework_id,\n");
			sql.append("        date(scon_homework_picture.create_time) create_time,\n");
			sql.append("        if(length(scon_homework_picture.corrected_picture_url) > 0, scon_homework_picture.corrected_picture_url,\n");
			sql.append("           scon_homework_picture.file_key)          picture_url\n");
			sql.append(" from scon_homework_picture,\n");
			sql.append("      scon_homework_how_details\n");
			sql.append(" where scon_homework_picture.id = scon_homework_how_details.homework_picture_id\n");
			sql.append("   and scon_homework_how_details.is_wrong_ques_delete = 0\n");
			sql.append("   and scon_homework_how_details.detail_count > 0\n");
			sql.append("   and scon_homework_picture.vip_id = ?\n");
			sql.append("   and scon_homework_how_details.how_detail_id = ?\n");
			sql.append("   and scon_homework_how_details.knowledge_version = ?\n");
			paramList.add(vipId);
			paramList.add(knowHowDetailDTO.getKnowHowDetailId());
			paramList.add(knowHowDetailDTO.getKnowledgeVersion());
			if (Objects.equals(3, type)) {
				sql.append("   and scon_homework_picture.create_time > ?\n");
				sql.append("   and scon_homework_picture.create_time < ?\n");
				paramList.add(beginDateTimeSb.toString());
				paramList.add(endDateTimeSb.toString());
			} else {
				if (StringUtils.isNotBlank(req.getBeginDate())) {
					sql.append("  and scon_homework_picture.create_time > ? ");
					paramList.add(beginDateTimeSb.toString());
				}
				if (StringUtils.isNotBlank(req.getEndDate())) {
					sql.append("  and ? > scon_homework_picture.create_time ");
					paramList.add(endDateTimeSb.toString());
				}
			}
			sql.append(" group by create_time, scon_homework_how_details.homework_picture_id\n");
			sql.append(")\n");
			sql.append("union all\n");
		});

		sql.delete(sql.length() - 10, sql.length());

		sql.append(") temp\n");
		sql.append("group by create_time\n");
		sql.append("order by create_time desc, homework_id\n");

		Page<WrongBookQuestionDTO> page = dao.findPage(sql.toString(), paramList.toArray(), pageable, WrongBookQuestionDTO.class);
		page.getContent().forEach(it -> {
			Date createTime = it.getCreateTime();
			if (createTime != null) {
				it.setWeek(DateUtil.getWeekDateToStr(createTime));
			}

			String homeworkPictureIdStr = it.getHomeworkPictureIdStr();
			String pictureUrlStr = it.getPictureUrlStr();
			if (StringUtils.isNotBlank(homeworkPictureIdStr) && StringUtils.isNotBlank(pictureUrlStr)) {
				List<Map<String, Object>> pictureList = new ArrayList<>();
				List<String> homeworkPictureIdList = Arrays.asList(homeworkPictureIdStr.split(","));
				List<String> pictureUrlList = Arrays.asList(pictureUrlStr.split(","));
				for (int i = 0; i < homeworkPictureIdList.size(); i ++) {
					String homeworkPictureId = homeworkPictureIdList.get(i);
					if (pictureList.stream().anyMatch(tempMap -> Objects.equals(tempMap.get("homeworkPictureId").toString(), homeworkPictureId))) {
						continue;
					}

					List<String> questionList = new ArrayList<>();
					if (Objects.equals(2, type)) {
						//打印原题的查询类型，需要返回图片关联的错题原题
						List<Map<String, Object>> questionMapList = kmtHomeworkWrongQuestionService.findQuestionList(Collections.singletonList(homeworkPictureId));

						//取出没有分多个小题的题目
						questionList = questionMapList.stream()
								.filter(questionMap -> questionMap.get("parent_id") == null || StringUtils.isBlank(questionMap.get("parent_id").toString()))
								.map(questionMap -> String.valueOf(questionMap.get("question")))
								.distinct()
								.collect(Collectors.toList());

						//如果题目分多个小题，则需要把大题下所有小题返回
						List<String> parentQuestionIdList = questionMapList.stream()
								.filter(questionMap -> questionMap.get("parent_id") != null && StringUtils.isNotBlank(questionMap.get("parent_id").toString()))
								.map(questionMap -> String.valueOf(questionMap.get("parent_id")))
								.distinct()
								.collect(Collectors.toList());
						List<String> questionAndParentList = kmtExerciseQuestionService.findListAndParentByParentId(parentQuestionIdList);
						questionList.addAll(questionAndParentList);
					}

					Map<String, Object> pictureMap = new HashMap<>();
					pictureMap.put("homeworkPictureId", homeworkPictureId);
					pictureMap.put("pictureUrl", pictureUrlList.get(i));
					pictureMap.put("wrongQuestionList", questionList);

					pictureList.add(pictureMap);
				}
				it.setPictureList(pictureList);
			}
		});

		return page;
	}

	@Override
	public Page<WrongBookQuestionDTO> findWrongBookQuestionPage2(WrongBookQuestionReq2 req, Pageable pageable) {
		String vipId = req.getVipId();
		List<KnowHowDetailDTO> knowHowDetailDTOList = req.getKnowHowDetailList();
		List<Object> paramList = new ArrayList<>();

		StringBuilder sql = new StringBuilder("select temp.homework_id, temp.create_time, group_concat(temp.homework_picture_id) homework_picture_id_str, group_concat(temp.picture_url) picture_url_str from (\n");
		knowHowDetailDTOList.forEach(knowHowDetailDTO -> {
			sql.append("(select scon_homework_picture.id homework_picture_id, scon_homework_picture.homework_id,\n");
			sql.append("        date(scon_homework_how_details.create_time) create_time,\n");
			sql.append("        if(length(scon_homework_picture.corrected_picture_url) > 0, scon_homework_picture.corrected_picture_url,\n");
			sql.append("           scon_homework_picture.file_key)          picture_url\n");
			sql.append(" from scon_homework_picture,\n");
			sql.append("      scon_homework_how_details\n");
			sql.append(" where scon_homework_picture.id = scon_homework_how_details.homework_picture_id\n");
			sql.append("   and scon_homework_how_details.is_wrong_ques_delete = 0\n");
			sql.append("   and scon_homework_how_details.detail_count > 0\n");
			sql.append("   and scon_homework_picture.vip_id = ?\n");
			sql.append("   and scon_homework_how_details.how_detail_id = ?\n");
			sql.append("   and scon_homework_how_details.knowledge_version = ?\n");
			sql.append(" group by create_time, scon_homework_how_details.homework_picture_id\n");
			sql.append(")\n");
			sql.append("union all\n");
			paramList.add(vipId);
			paramList.add(knowHowDetailDTO.getKnowHowDetailId());
			paramList.add(knowHowDetailDTO.getKnowledgeVersion());
		});

		sql.delete(sql.length() - 10, sql.length());

		sql.append(") temp\n");
		sql.append("group by create_time\n");
		sql.append("order by create_time desc, homework_id\n");

		Page<WrongBookQuestionDTO> page = dao.findPage(sql.toString(), paramList.toArray(), pageable, WrongBookQuestionDTO.class);
		page.getContent().forEach(it -> {
			Date createTime = it.getCreateTime();
			if (createTime != null) {
				it.setWeek(DateUtil.getWeekDateToStr(createTime));
			}

			String homeworkPictureIdStr = it.getHomeworkPictureIdStr();
			String pictureUrlStr = it.getPictureUrlStr();
			if (StringUtils.isNotBlank(homeworkPictureIdStr) && StringUtils.isNotBlank(pictureUrlStr)) {
				List<Map<String, Object>> pictureList = new ArrayList<>();
				List<String> homeworkPictureIdList = Arrays.asList(homeworkPictureIdStr.split(","));
				List<String> pictureUrlList = Arrays.asList(pictureUrlStr.split(","));
				for (int i = 0; i < homeworkPictureIdList.size(); i ++) {
					String homeworkPictureId = homeworkPictureIdList.get(i);
					if (pictureList.stream().anyMatch(tempMap -> Objects.equals(tempMap.get("homeworkPictureId").toString(), homeworkPictureId))) {
						continue;
					}

					Map<String, Object> pictureMap = new HashMap<>();
					pictureMap.put("homeworkPictureId", homeworkPictureId);
					pictureMap.put("pictureUrl", pictureUrlList.get(i));
					pictureList.add(pictureMap);
				}
				it.setPictureList(pictureList);
			}
		});

		return page;
	}

}
