package com.zd.exam.service.impl;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

import cn.hutool.json.JSONUtil;
import com.zd.common.core.exception.ServiceException;
import com.zd.common.core.utils.DateUtils;
import com.zd.common.core.utils.SecurityUtils;
import com.zd.common.security.service.TokenService;
import com.zd.common.security.utils.SaveUtil;

import com.zd.exam.domain.ElConvertRecord;
import com.zd.exam.domain.ElCourseChapter;
import com.zd.exam.domain.vo.ElCourseVo;
import com.zd.exam.enums.ConvertType;
import com.zd.exam.mapper.ElConvertRecordMapper;
import com.zd.exam.mapper.ElCourseChapterMapper;
import com.zd.exam.mapper.ElCourseMapper;
import com.zd.exam.service.IElConvertRecordService;
import com.zd.exam.service.convert.BonusPointsService;
import com.zd.exam.service.convert.ConvertTimingService;
import com.zd.exam.service.convert.LabBlackConfig;
import com.zd.exam.util.CourcseUtils;
import com.zd.system.api.laboratory.RemoteLaboratoryService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.zd.exam.mapper.ElChapterLearnRecordMapper;
import com.zd.exam.domain.ElChapterLearnRecord;
import com.zd.exam.service.IElChapterLearnRecordService;

/**
 * 学习记录Service业务层处理
 *
 * @author liubo
 * @date 2021-12-07
 */
@Service
public class ElChapterLearnRecordServiceImpl implements IElChapterLearnRecordService {
    private Logger logger = LoggerFactory.getLogger(ElChapterLearnRecordServiceImpl.class);

    @Autowired
    private ElChapterLearnRecordMapper elChapterLearnRecordMapper;
    @Autowired
    private ElCourseChapterMapper elCourseChapterMapper;
    @Autowired
    private ElCourseMapper elCourseMapper;
    @Autowired
    private IElConvertRecordService convertRecordService;
    @Autowired
    private ElConvertRecordMapper elConvertRecordMapper;
    @Autowired
    private TokenService tokenService;
    @Autowired
    private BonusPointsService bonusPointsService;
    @Autowired
    private ConvertTimingService convertTimingService;
    @Autowired
    private RemoteLaboratoryService remoteLaboratoryService;

    /**
     * 查询学习记录
     *
     * @param id 学习记录主键
     * @return 学习记录
     */
    @Override
    public ElChapterLearnRecord selectElChapterLearnRecordById(Long id) {
        return elChapterLearnRecordMapper.selectElChapterLearnRecordById(id);
    }

    /**
     * 查询学习记录列表
     *
     * @param elChapterLearnRecord 学习记录
     * @return 学习记录
     */
    @Override
    public List<ElChapterLearnRecord> selectElChapterLearnRecordList(ElChapterLearnRecord elChapterLearnRecord) {
        elChapterLearnRecord.setJoinUserId(SecurityUtils.getUserId());
        return elChapterLearnRecordMapper.selectElChapterLearnRecordList(elChapterLearnRecord);
    }

    /**
     * 新增学习记录
     *
     * @param elChapterLearnRecord 学习记录
     * @return 结果
     */
    @Override
    public int insertElChapterLearnRecord(ElChapterLearnRecord elChapterLearnRecord) {
        //设置其他公共字段
        SaveUtil.setCommonAttr(elChapterLearnRecord);
        elChapterLearnRecord.setJoinUserId(SecurityUtils.getUserId());
        elChapterLearnRecord.setStatus(0);
        elChapterLearnRecord.setProgress(0L);
        elChapterLearnRecord.setTotalEff(0);
        elChapterLearnRecord.setCurrentExer(1);
        elChapterLearnRecord.setStartTime(DateUtils.getNowDate());
        // 将该课程其他在学状态修改为0  setCurrentExer(0)
        int num = elChapterLearnRecordMapper.insertElChapterLearnRecord(elChapterLearnRecord);
        elChapterLearnRecordMapper.updateOtherCurrentById(elChapterLearnRecord.getId());
        return num;
    }

    /**
     * 修改学习记录
     *
     * @param elChapterLearnRecord 学习记录
     * @return 结果
     */
    @Override
    public int updateElChapterLearnRecord(ElChapterLearnRecord elChapterLearnRecord) {
        elChapterLearnRecord.setUpdateTime(DateUtils.getNowDate());
        elChapterLearnRecord.setUpdateBy(SecurityUtils.getUsername());
        elChapterLearnRecord.setStatus(0);
        elChapterLearnRecord.setProgress(0L);
        elChapterLearnRecord.setTotalEff(0);
        elChapterLearnRecord.setCurrentExer(1);
        elChapterLearnRecord.setStartTime(DateUtils.getNowDate());
        elChapterLearnRecord.setTotalEff(elChapterLearnRecord.getTotalEff() + 1);
        // 将该课程其他在学状态修改为0  setCurrentExer(0)
        elChapterLearnRecordMapper.updateOtherCurrentById(elChapterLearnRecord.getId());
        return elChapterLearnRecordMapper.updateElChapterLearnRecord(elChapterLearnRecord);
    }

    /**
     * 批量删除学习记录
     *
     * @param ids 需要删除的学习记录主键
     * @return 结果
     */
    @Override
    public int deleteElChapterLearnRecordByIds(Long[] ids) {
        return elChapterLearnRecordMapper.deleteElChapterLearnRecordByIds(ids);
    }

    /**
     * 删除学习记录信息
     *
     * @param id 学习记录主键
     * @return 结果
     */
    @Override
    public int deleteElChapterLearnRecordById(Long id) {
        return elChapterLearnRecordMapper.deleteElChapterLearnRecordById(id);
    }

    /**
     * 开始学习
     * @param learnRecord
     */
    @Override
    public void learnStart(ElChapterLearnRecord learnRecord) {
        List<ElChapterLearnRecord> list = selectElChapterLearnRecordList(learnRecord);
        if(list.size() > 1){
            // 根据  课程，章节，用户，应该只能查一条数据，否则数据异常
            throw new ServiceException("数据异常，请联系管理员！");
        }else if(list.size() > 0){
            updateElChapterLearnRecord(list.get(0));
        }else {
            insertElChapterLearnRecord(learnRecord);
        }
    }

    /**
     * 学习完成
     * @param learnRecord
     * @return
     */
    @Override
    public Map<String, Object> learnFinish(ElChapterLearnRecord learnRecord) {
        List<ElChapterLearnRecord> list = selectElChapterLearnRecordList(learnRecord);
        if(list.size() > 1){
            // 根据  课程，章节，用户，应该只能查一条数据，否则数据异常
            throw new ServiceException("数据异常，请联系管理员！");
        }else if(list.size() > 0){
            learnRecord = list.get(0);
            learnRecord.setLastTime(DateUtils.getNowDate());
            learnRecord.setProgress(100L);
            learnRecord.setStatus(1);

            ElCourseChapter chapter = elCourseChapterMapper.selectElCourseChapterById(learnRecord.getChapterId());
            learnRecord.setDuration(chapter.getDuration());
            elChapterLearnRecordMapper.updateElChapterLearnRecord(learnRecord);

            // 添加学习记录换算表，未满足的数据统计到下次换算
            Long convertRecordId = null;
            if(learnRecord.getDuration() > 0){
                ElConvertRecord elConvertRecord = new ElConvertRecord();
                elConvertRecord.setType(ConvertType.LEARN);
                // 此处业务ID 为学习记录ID 真正转换时需要查出对应的课程ID // learnRecord.getCourseId()
                elConvertRecord.setBusinessId(learnRecord.getId());
                elConvertRecord.setBusinessNum(learnRecord.getDuration());
                 elConvertRecord.setStatus(0);
                elConvertRecord.setUseNum(0L);

                convertRecordService.insertElConvertRecord(elConvertRecord);

                convertRecordId = elConvertRecord.getId();
            }

            // TODO 区分黑名单和负面清单

            //  练习结束 恢复黑名单
            LabBlackConfig blackConfig = bonusPointsService.getBlackTimeArea(learnRecord.getJoinUserId());
            Long durations = 0L;
            if(blackConfig != null && blackConfig.getCreateTime() != null && blackConfig.getHandleDay() != null){
                // 完成学习 根据违规时间范围统计学习时长，并处理

                // 统计学习时长
                durations = elConvertRecordMapper.selectALLDurationByTime(learnRecord.getJoinUserId(),blackConfig.getCreateTime(), blackConfig.getHandleDay());
                if(durations > 0){

                    Map<String, Object> data = new HashMap<>();
                    data.put("learnStatus", 0);
                    data.put("learnTime", durations);

                    bonusPointsService.blackCallback(learnRecord.getJoinUserId(), data, 3);
                }

            }
            // 学习完成 奖励分立即兑换
            Map<String, Object> map = new HashMap<>();
            // 获得积分
            map.put("points", convertRecordId != null ? convertTimingService.doConvertById(convertRecordId) : 0);
            // 学习时长 -- 应该是本章节的课程时长
            map.put("durationStr", learnRecord.getDurationStr());
            map.put("durations", durations);

            logger.error(learnRecord.getChapterId() + "章节学习完成，返回数据：" + JSONUtil.toJsonStr(map));
            return map;
        }else {
            throw new ServiceException("未查询到学习记录，请返回重试！");
        }
    }

    /**
     * 学习记录接口
     */
    @Override
    public List<ElCourseVo> learnList(ElCourseVo courseVo) {
        List<ElCourseVo> list = elChapterLearnRecordMapper.selectLearnListByUser(courseVo);

        if(courseVo.getJoinUserId() != null){
            List<ElCourseChapter> chapterList;
            ElCourseChapter elCourseChapter = new ElCourseChapter();
            for (ElCourseVo elCourseVo : list) {
                elCourseChapter.setCourseId(elCourseVo.getCourseId());
                elCourseChapter.setUserId(courseVo.getJoinUserId());

                chapterList = elCourseChapterMapper.selectUserCourseChapterList(elCourseChapter);
                Integer learnStatus = 1;
                for (ElCourseChapter chapter : chapterList) {
                    if(chapter.getType() != 0){
                        // 0 学习中，2 未学习，1 已完成
                        if(chapter.getLearnStatus() == 0){
                            learnStatus = 0;
                            break;
                        }else if(chapter.getLearnStatus() == 1) {
                            if(chapter.getIsAssess() == 1 && chapter.getAssessStatus() == 0){
                                learnStatus = 3;
                            }
                        }else {
                            learnStatus = 2;
                            break;
                        }
                    }
                }
                // 0 学习中，2 未学习，3 待考核，1 已完成
                elCourseVo.setLearnStatus(learnStatus);
            }
        }

        return list;
    }
}
