package com.ssj.service.test;

import com.alibaba.dubbo.config.annotation.Service;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ssj.bean.sys.homework.domain.HomeworkCount;
import com.ssj.bean.sys.homework.domain.KnowledgeProficiency;
import com.ssj.bean.sys.homework.domain.StudentWeeklyReport;
import com.ssj.bean.weixin.libmy.domain.LibVip;
import com.ssj.bean.weixin.push.domain.Miniprogram;
import com.ssj.bean.weixin.push.domain.SendTemplateShort;
import com.ssj.bean.weixin.user.domain.User;
import com.ssj.bean.weixin.zyb.domain.ZuoybStudentPush;
import com.ssj.es.service.base.BaseSearchService;
import com.ssj.framework.basic.config.bean.Config;
import com.ssj.framework.basic.config.service.ConfigService;
import com.ssj.framework.core.security.manager.TokenManager;
import com.ssj.framework.core.util.ResponseEntity;
import com.ssj.framework.weixin.util.DateUtil;
import com.ssj.framework.weixin.util.WxUtil;
import com.ssj.service.conch.parents.v2.request.LearningGrowthReportReq;
import com.ssj.service.conch.teacher.service.TeacherService;
import com.ssj.service.kmt.exercisesys.service.KmtExerciseSysService;
import com.ssj.service.kmt.service.KmtExerciseMapperService;
import com.ssj.service.mapper.KmtQuestionMapper;
import com.ssj.service.mapper.LearningGrowthReportMapper;
import com.ssj.service.sys.homework.service.HomeworkPictureService;
import com.ssj.service.sys.problem.service.IBanbenDetailService;
import com.ssj.service.sys.push.service.SconXingeService;
import com.ssj.service.sys.situation.service.LearningConditionService;
import com.ssj.service.weixin.library.service.ILibVipService;
import com.ssj.service.weixin.push.service.PushTemplateService;
import com.ssj.service.weixin.user.service.UserService;
import com.ssj.service.weixin.zuoyb.service.ZuoybStudentPushSerivce;
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.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.text.Collator;
import java.time.DayOfWeek;
import java.time.LocalDate;
import java.util.*;
import java.util.stream.Collectors;


/**
 * @author Mount Liu
 * @date 2019/12/11
 */
@Service(version = "1.0")
@Transactional
public class DeveloperServiceImpl implements DeveloperService {
    private Logger logger = LoggerFactory.getLogger(this.getClass());

    @Autowired
    private TeacherService teacherService;
    @Autowired
    private HomeworkPictureService homeworkPictureService;
    @Autowired
    private ILibVipService libVipService;
    @Autowired
    private UserService userService;
    @Autowired
    private LearningGrowthReportMapper learningGrowthReportMapper;
    @Autowired
    private PushTemplateService pushTemplateService;
    @Autowired
    private SconXingeService sconXingeService;
    @Autowired
    private KmtExerciseMapperService kmtExerciseMapperService;
    @Autowired
    private LearningConditionService learningConditionService;
    @Autowired
    private KmtQuestionMapper kmtQuestionMapper;
    @Autowired
    private BaseSearchService baseSearchService;
    @Autowired
    private KmtExerciseSysService kmtExerciseSysService;
    @Autowired
    private IBanbenDetailService banbenDetailService;
    @Autowired
    private ZuoybStudentPushSerivce zuoybStudentPushSerivce;

    @Autowired
    private ConfigService configService;

    @Autowired
    private TokenManager tokenManager;

    @Override
    public ResponseEntity testOneMethod() {
        ResponseEntity responseEntity = new ResponseEntity();
        String teacherId = teacherService.getHomeworkLibTeacherId("071f16a7-1328-4b58-890b-ad68f43778fb", "1361c559-550a-4fa9-bbcd-70e216d6168f", "英语");
        System.err.println(teacherId);
        responseEntity.success(teacherId,"成功");
        return responseEntity;
    }

    @Override
    public ResponseEntity testGrowthReportNotifyTask(String vipId) {
        ResponseEntity responseEntity = new ResponseEntity();

        LibVip libVip = libVipService.getById(vipId);
        if (libVip == null) {
            logger.warn("推送周成长报告通知时，发现学生(vipId=[{}])不存在", vipId);
            return responseEntity.failure("学生不存在");
        }
        String parentUserId = libVip.getUserId();
        User parentUser = userService.getById(parentUserId);
        if (parentUser == null) {
            logger.warn("推送周成长报告通知时，发现家长(userId=[{}])不存在", parentUserId);
            return responseEntity.failure("家长不存在");
        }

        if (StringUtils.isNotBlank(parentUser.getAccount())) {
            //公众号推送家长
            String firstStr = String.format("尊敬的%s家长，您名下的孩子%s上周的学习成长报告出炉啦！", parentUser.getUserName(), libVip.getChildName());

            Date beginDateTime = DateUtil.getEndOfLastWeek(new Date());
            LocalDate today = LocalDate.now();
            if (!Objects.equals(today.getDayOfWeek().getValue(), DayOfWeek.SUNDAY.getValue())) {
                beginDateTime = DateUtil.addDays(beginDateTime, -7);
            }
            List<StudentWeeklyReport> studentWeeklyReportList =
                    learningGrowthReportMapper.findWeeklyReportByVipIdAndBeginDate(vipId,
                            DateUtil.format_yyyyMMdd(beginDateTime));

            int totalNum = 0;
            int goodNum = 0;
            int notFirmNum = 0;
            int notMasteredNum = 0;
            for (StudentWeeklyReport studentWeeklyReport : studentWeeklyReportList) {
                totalNum += Optional.ofNullable(studentWeeklyReport.getTotalKnowledgeNum()).orElse(0);
                goodNum += Optional.ofNullable(studentWeeklyReport.getMasterWellKnowledgeNum()).orElse(0);
                notFirmNum += Optional.ofNullable(studentWeeklyReport.getMasterInfirmlyKnowledgeNum()).orElse(0);
                notMasteredNum += Optional.ofNullable(studentWeeklyReport.getNotMasteredKnowledgeNum()).orElse(0);
            }
            String keyword2 = "";
            if (totalNum > 0) {
                keyword2 += String.format("本周一共学了%s个知识点", totalNum);
            }
            if (goodNum > 0) {
                keyword2 += goodNum + "个知识点掌握良好";
            }
            if (notFirmNum > 0) {
                if (keyword2.length() > 0) {
                    keyword2 += "，";
                }
                keyword2 += notFirmNum + "个知识点掌握不牢固";
            }
            if (notMasteredNum > 0) {
                if (keyword2.length() > 0) {
                    keyword2 += "，";
                }
                keyword2 += notMasteredNum + "个知识点未掌握";
            }
            String url = String.format("pages/learning_report/learning_report?status=1&vipId=%s", vipId);
            Miniprogram miniprogram = new Miniprogram();
            miniprogram.setAppid(WxUtil.map.get("jzdAppId"));
            miniprogram.setPagepath(url);
            Map<String, String> dataMap = new HashMap<>();
            dataMap.put("first", firstStr);
            dataMap.put("keyword1", libVip.getChildName());
            dataMap.put("keyword2", keyword2);
            SendTemplateShort sendTemplateShort = new SendTemplateShort(parentUser.getAccount(), "OPENTM415124923", null, dataMap, miniprogram);
            pushTemplateService.saveAndSendPushWxTemplate(sendTemplateShort);
        }
        //推送家长端app
        String content = String.format("尊敬的%s家长，您名下的孩子%s上周的学习成长报告已经生成，快来查看吧。", parentUser.getUserName(), libVip.getChildName());
        sconXingeService.asynPushGrowthReportThreadTask(parentUserId, vipId, content, "WEEKLY_GROWTH_REPORT_NOTICE");

        if (StringUtils.isNotBlank(parentUser.getAccount())) {
            Date beginOfLastMonth = DateUtil.getBeginOfLastMonth(new Date());
            String simpleMonthStr = DateUtil.format(beginOfLastMonth.getTime(), "M");

            //公众号推送家长
            String firstStr = String.format("尊敬的%s家长，%s月的学习成长报告出炉啦！", libVip.getChildName(), simpleMonthStr);

            LearningGrowthReportReq req = new LearningGrowthReportReq();
            req.setVipId(vipId);
            HomeworkCount homeworkCount = kmtExerciseMapperService.findMonthHomeworkCount(req.getVipId(), DateUtil.format(beginOfLastMonth.getTime(), "yyyy-MM"));
            if (homeworkCount == null) {
                return responseEntity.failure(simpleMonthStr + "月无月报");
            }
            String transcendedStudentProportion = homeworkCount.getTranscendedStudentProportion().multiply(BigDecimal.valueOf(100)).intValue() + "%";
            Integer increasedScore = homeworkCount.getIncreasedScore();
            String keyword2;
            if (increasedScore > 0) {
                keyword2 = String.format("%s月整体得分%s分，超过了%s同年级学生，同比上个月提高了%s分，继续加油!", simpleMonthStr, homeworkCount.getAccuracyRate(), transcendedStudentProportion, increasedScore);
            } else if (increasedScore < 0) {
                keyword2 = String.format("%s月整体得分%s分，超过了%s同年级学生，同比上个月降低了%s分，继续加油!", simpleMonthStr, homeworkCount.getAccuracyRate(), transcendedStudentProportion, increasedScore * -1);
            } else {
                keyword2 = String.format("%s月整体得分%s分，超过了%s同年级学生，同比上个月无变化，继续加油!", simpleMonthStr, homeworkCount.getAccuracyRate(), transcendedStudentProportion);
            }
            String url = String.format("pages/learning_report/learning_report?status=2&vipId=%s", vipId);
            Miniprogram miniprogram = new Miniprogram();
            miniprogram.setAppid(WxUtil.map.get("jzdAppId"));
            miniprogram.setPagepath(url);
            Map<String, String> dataMap = new HashMap<>();
            dataMap.put("first", firstStr);
            dataMap.put("keyword1", libVip.getChildName());
            dataMap.put("keyword2", keyword2);
            SendTemplateShort sendTemplateShort = new SendTemplateShort(parentUser.getAccount(), "OPENTM415124923", null, dataMap, miniprogram);
            pushTemplateService.saveAndSendPushWxTemplate(sendTemplateShort);
        } else {
            logger.warn("家长(userId=[{}])openid为空", parentUserId);
        }

        //推送家长端app
        content = String.format("尊敬的%s家长，您名下的孩子%s上月的学习成长报告已经生成，快来查看吧。", parentUser.getUserName(), libVip.getChildName());
        sconXingeService.asynPushGrowthReportThreadTask(parentUserId, vipId, content, "MONTHLY_GROWTH_REPORT_NOTICE");

        return responseEntity;
    }

    @Override
    public void testAllGrowthReportNotifyTask() {
        learningConditionService.pushWeeklyGrowthReportNotify();

        Date beginOfLastMonth = DateUtil.getBeginOfLastMonth(new Date());
        learningConditionService.pushMonthlyGrowthReportNotify(DateUtil.format(beginOfLastMonth.getTime(), "yyyy-MM"));
    }

    @Override
    public int generateKnowledgeWrongQuestionCount(String homeworkId) {
        return learningConditionService.generateWrongQuestionKnowledge(homeworkId);
    }

    @Override
    public long updateAllKmtQuestion2Es() {
        int pageSize = 2500;
        long updateCount = 0;
        List<Map<String, Object>> dataMapList = new ArrayList<>();
        boolean updateSuccess;
        int failedCount = 0;
        boolean isContinue = true;

        do {
            if (dataMapList.isEmpty()) {
                dataMapList = kmtQuestionMapper.findAll2Es(pageSize);
                if (dataMapList.size() < pageSize) {
                    isContinue = false;
                }
            }

            if (!dataMapList.isEmpty()) {
                //添加到es
                updateSuccess = baseSearchService.updateOrInsertBatch("kmt_question_know", dataMapList);
                if (updateSuccess) {
                    baseSearchService.clearCache("kmt_question_know");
                    updateCount += dataMapList.size();

                    //更新加载状态为已加载
                    List<String> kmtQuestionKnowIdList = dataMapList.stream().map(it -> String.valueOf(it.get("id"))).collect(Collectors.toList());
                    kmtQuestionMapper.updateEsLoadStatus(kmtQuestionKnowIdList, 1);

                    logger.info("------>已加载{}条数据", updateCount);

                    dataMapList.clear();
                } else if (failedCount < 5){
                    failedCount ++;
                } else {
                    //更新加载状态为加载失败
                    List<String> kmtQuestionKnowIdList = dataMapList.stream().map(it -> String.valueOf(it.get("id"))).collect(Collectors.toList());
                    kmtQuestionMapper.updateEsLoadStatus(kmtQuestionKnowIdList, 2);
                    dataMapList.clear();
                    failedCount = 0;
                }
            }
        } while (isContinue);

        return updateCount;
    }

    @Override
    public int updateTranscendedStudentProportion(String month) {
        return learningConditionService.updateTranscendedStudentProportion(month);
    }

    @Override
    public int generateMasteryOfSemesterKnowledge(Boolean countAllHomework) {
        return learningConditionService.updateMasteryOfSemesterKnowledge();
    }

    @Override
    public void updateKnowHowDetailsSortInEs() {
        learningConditionService.updateKnowHowDetailsSortQuestionStatus();
    }

    @Override
    public int updateKnowledgeWrongQuestionCountQuestionStatus() {
        return learningConditionService.updateWrongQuestionKnowledgeQuestionStatus();
    }

    @Override
    public int updateKmtExerciseBookStatus(String exerciseBookId) {
        List<String> exerciseBookIdList = StringUtils.isBlank(exerciseBookId) ? Collections.emptyList() : Collections.singletonList(exerciseBookId);
        return kmtExerciseSysService.refreshBookStatus(exerciseBookIdList);
    }

    @Override
    public int updateKmtExerciseBookStatusCount(String exerciseBookId) {
        List<String> exerciseBookIdList = StringUtils.isBlank(exerciseBookId) ? Collections.emptyList() : Collections.singletonList(exerciseBookId);
        return kmtExerciseSysService.refreshExerciseBookCount(exerciseBookIdList);
    }

    @Override
    public int updateKnowledgeProficiencyKnowledgeVersion() {
        int pageNo = 1;
        int pageSize = 500;
        int updateCount = 0;
        int knowledgeVersion;
        LibVip libVip;
        List<KnowledgeProficiency> knowledgeProficiencyList;
        do {
            knowledgeProficiencyList = learningGrowthReportMapper.findAll2UpdateKnowledgeVersion(new Page<>(pageNo, pageSize));
            if (CollectionUtils.isNotEmpty(knowledgeProficiencyList)) {
                for (KnowledgeProficiency knowledgeProficiency : knowledgeProficiencyList) {
                    libVip = libVipService.getById(knowledgeProficiency.getVipId());
                    if (libVip == null) {
                        continue;
                    }

                    knowledgeVersion = banbenDetailService.findBanben(knowledgeProficiency.getSubject(),
                            libVip.getSchool(), knowledgeProficiency.getGrade());

                    learningGrowthReportMapper.updateKnowledgeVersion(knowledgeProficiency.getId(), knowledgeVersion);
                    updateCount ++;
                }
            }
        } while (knowledgeProficiencyList.size() >= pageSize);

        return updateCount;
    }

    @Override
    public int updateStudentPushType() {
        return zuoybStudentPushSerivce.updateType();
    }

    @Override
    public void addPress(List<String> pressList) {
        String key = "exercise_press";
        Config config = configService.findConfigByParamCode(key);
        JSONArray array = JSONObject.parseArray(config.getParamVal());
        List<String> list = JSONObject.parseArray(array.toJSONString(), String.class);
        list.addAll(pressList);
        //按照中文首字母排序
        Comparator<Object> comparator= Collator.getInstance(java.util.Locale.CHINA);
        Collections.sort(list, comparator);
        JSONArray newArray = JSONArray.parseArray(JSON.toJSONString(list));
        config.setParamVal(newArray.toString());
        configService.save(config);
        tokenManager.setString(key, config.getParamVal());
    }

    @Override
    public void deletePress(List<String> pressList) {
        String key = "exercise_press";
        Config config = configService.findConfigByParamCode(key);
        JSONArray array = JSONObject.parseArray(config.getParamVal());
        List<String> list = JSONObject.parseArray(array.toJSONString(), String.class);
        list.removeAll(pressList);
        //按照中文首字母排序
        Comparator<Object> comparator= Collator.getInstance(java.util.Locale.CHINA);
        Collections.sort(list, comparator);
        JSONArray newArray = JSONArray.parseArray(JSON.toJSONString(list));
        config.setParamVal(newArray.toString());
        configService.save(config);
        tokenManager.setString(key, config.getParamVal());
    }

    @Override
    public void refreshExerciseBookDistributionCount(String exerciseBookId) {
        if (StringUtils.isNotBlank(exerciseBookId)) {
            kmtExerciseSysService.refreshExerciseBookDistributionCount(Collections.singletonList(exerciseBookId), 1);
        } else {
            kmtExerciseSysService.refreshExerciseBookDistributionCount(Collections.emptyList(), 1);
        }
    }

    @Override
    public int updateFeedbackReportAndNotifyParent(String vipId) {
        ZuoybStudentPush studentPush = zuoybStudentPushSerivce.findByVipIdToDay(vipId);
        if (Objects.equals(3, studentPush.getType())) {
            homeworkPictureService.push2Parent(studentPush, vipId, 6);
            return 1;
        }
        return 0;
    }

    @Override
    public int regenerateTrainingRecommendQuestion(String studentWeeklyReportId) {
        return learningConditionService.regenerateTrainingRecommendQuestion(studentWeeklyReportId);
    }

}