package com.xhkjedu.sstudy.service.resource;

import com.xhkjedu.sstudy.listener.MessageSender;
import com.xhkjedu.sstudy.mapper.gradeclass.ClassMapper;
import com.xhkjedu.sstudy.mapper.resource.*;
import com.xhkjedu.sstudy.mapper.subjectbook.SubjectMapper;
import com.xhkjedu.sstudy.mapper.subjectbook.TeacherSubjectbookMapper;
import com.xhkjedu.sstudy.mapper.system.SchoolMapper;
import com.xhkjedu.sstudy.model.resource.*;
import com.xhkjedu.sstudy.utils.ConvertUtil;
import com.xhkjedu.sstudy.utils.StudyUtil;
import com.xhkjedu.sstudy.vo.paper.AStudentPaperVo;
import com.xhkjedu.sstudy.vo.paper.AnalyzeSearchVo;
import com.xhkjedu.sstudy.vo.resource.GuideAnalyzeVo;
import com.xhkjedu.sstudy.vo.resource.GuideVo;
import com.xhkjedu.utils.N_Utils;
import com.xhkjedu.vo.ResultVo;
import com.xhkjedu.vo.system.UserVo;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @ClassName GuideService
 * Description TODO 学生预习
 * Author WN
 * Date 2021/10/20 10:37
 **/
@Service
@Slf4j
public class GuideService {
    @Resource
    private GuideMapper guideMapper;
    @Resource
    private GuideResourceMapper guideResourceMapper;
    @Resource
    private ResourceMapper resourceMapper;

    @Resource
    private GuideGroupStudentMapper guideGroupStudentMapper;
    @Resource
    private ClassMapper classMapper;
    @Resource
    private GuideGroupMapper guideGroupMapper;
    @Resource
    private SchoolMapper schoolMapper;
    @Resource
    private SubjectMapper subjectMapper;
    @Autowired
    private MessageSender messageSender;
    @Autowired
    private ConvertUtil convertUtil;
    @Resource
    private TeacherSubjectbookMapper teacherSubjectbookMapper;

    //学生预习列表--教师网页端
    public List<GuideVo> listGuidesForTeacherWeb(TGuide guide, UserVo userVo){
        return guideMapper.listGuidesForTeacherWeb(guide, userVo);
    }

    //学生预习列表--教师网页端--我的
    public List<GuideVo> listGuidesForTeacherWebMy(TGuide guide){
        return guideMapper.listGuidesForTeacherWebMy(guide);
    }
    //学生预习列表--教师app
    public List<Map> listGuidesForTeacherApp(TGuide guide){
        return guideMapper.listGuidesForTeacherApp(guide);
    }
    //学生预习列表--学生网页
    public List<GuideVo> listGuidesForStuWeb(TGuide guide){
        return guideMapper.listGuidesForStuWeb(guide);
    }
    //学生预习列表--学生app
    public List<Map> listGuidesForStuApp(TGuide guide){
        return guideMapper.listGuidesForStuApp(guide);
    }

    //预习详情
    public GuideVo getGuideByGuideid(Integer guideid){
        GuideVo guide = guideMapper.getGuideByGuideid(guideid);
        if(guide!=null) {
            List<Map> resources = guide.getResources();
            for (Map resource : resources) {
                Integer converted = (Integer) resource.get("converted");
                if (converted == 0) {
                    TResource r = new TResource();
                    r.setResourceid(resource.get("resourceid").toString());
                    r.setResourceclass((Integer) resource.get("resourceclass"));
                    r.setSuffix((String) resource.get("suffix"));
                    r.setResourceurl(resource.get("resourceurl").toString());
                    r.setConverted(converted);
                    convertUtil.convertResource(r);
                }
            }

        }
        return guide;
    }


    //保存学生预习
    @Transactional(rollbackFor = Exception.class)
    public ResultVo save(TGuide guide){
        try {
            //根据用户id获取用户权限科目，如果上传科目和权限科目不一致，不允许保存
            String subjectid = teacherSubjectbookMapper.listSubjectidByTeacherid(guide.getCreateid());
            if(!subjectid.equals(guide.getSubjectid())){
                return new ResultVo(1,"保存失败");
            }else{
                Integer timestamp = N_Utils.getSecondTimestamp();
                guide.setCreatetime(timestamp);
                Integer hashb = 0;
                if (N_Utils.isListNotEmpty(guide.getJtrclist())) {
                    hashb = 1;
                }
                guide.setHashb(hashb);
                int year = schoolMapper.getYearByUserId(guide.getCreateid());
                guide.setYear(year);
                guideMapper.insertUseGeneratedKeys(guide);
                Integer guideid = guide.getId();//预习id
                guide.setGuideid(guideid);

                //保存资源
                List<TResource> resources = guide.getResources();
                for(TResource r : resources) {
                    r.setCreateid(guide.getCreateid());
                    r.setCreatetime(guide.getCreatetime());
                    r.setLevel(3);
                    r.setResourcestate(1);
                    r.setResourcetype(10);
                    r.setBelong(4);
                    r.setSchoolid(guide.getSchoolid());
                    r.setSubjectid(guide.getSubjectid());

                    String resourceid = StudyUtil.getId();//资源id
                    r.setResourceid(resourceid);
                    Integer resourceclass = r.getResourceclass();
                    if (resourceclass == 3 || resourceclass == 4 || resourceclass == 6) {
                        r.setConverted(1);
                    } else if (resourceclass == 5) {
                        if("h264".equals(r.getMp4code())){
                            r.setConverted(1);
                        } else {
                            r.setConverted(0);
                        }

                    }
                    //保存资源信息
                    resourceMapper.insertSelective(r);
                    //保存预习资源关联关系
                    TGuideResource gr = new TGuideResource();
                    gr.setGuideid(guideid);
                    gr.setResourceid(resourceid);
                    gr.setCreateid(guide.getCreateid());
                    gr.setCreatetime(guide.getCreatetime());
                    guideResourceMapper.insertUseGeneratedKeys(gr);

                    convertUtil.convertResource(r);//资源转换（word或ppt转为pdf，视频非h264编码转码，压缩包解压）
                }

                //保存预习学生关联信息
                batchSaveGuideStudent(guide);
                return new ResultVo(0,"保存成功");
            }
        }catch (Exception e){
            log.error("保存预习失败：" + e.getMessage());
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return new ResultVo(1,"保存失败");
        }

    }

    //个人空间分享到学生预习
    @Transactional(rollbackFor = Exception.class)
    public ResultVo shareGuide(TGuide guide){

        try {
            //根据用户id获取用户权限科目，如果上传科目和权限科目不一致，不允许保存
            String subjectid = teacherSubjectbookMapper.listSubjectidByTeacherid(guide.getCreateid());
            if(!subjectid.equals(guide.getSubjectid())){
                return new ResultVo(1,"分享失败");
            }else{
                String resourceid = guide.getResourceid();
                Integer timestamp = N_Utils.getSecondTimestamp();
                guide.setCreatetime(timestamp);
                Integer hashb = 0;
                if (N_Utils.isListNotEmpty(guide.getJtrclist())) {
                    hashb = 1;
                }
                guide.setHashb(hashb);
                int year = schoolMapper.getYearByUserId(guide.getCreateid());
                guide.setYear(year);
                guideMapper.insertUseGeneratedKeys(guide);
                Integer guideid = guide.getId();//预习id

                //保存预习资源
                TGuideResource guideResource = new TGuideResource();
                guideResource.setGuideid(guideid);
                guideResource.setResourceid(resourceid);
                guideResource.setCreateid(guide.getCreateid());
                guideResource.setCreatetime(timestamp);
                guideResourceMapper.insert(guideResource);
                guide.setGuideid(guideid);

                //保存预习学生关联信息
                batchSaveGuideStudent(guide);
                return new ResultVo(0,"分享成功");
            }
        }catch (Exception e){
            log.error("分享预习失败：" + e.getMessage());
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return new ResultVo(1,"分享失败");
        }

    }

    //批量维护预习班级和学生信息
    private void batchSaveGuideStudent(TGuide guide) throws Exception {
        List<TGuideGroup> guideGroups = guide.getGuideGroups().stream().distinct().collect(Collectors.toList());
        List<TGuideGroup> savegroup = new ArrayList<>();
        List<TGuideGroupStudent> savestus = new ArrayList<>();
        Integer schoolid = guide.getSchoolid();
        Integer guideid = guide.getGuideid();
        Integer createid = guide.getCreateid();
        for (TGuideGroup gg : guideGroups) {
            Integer classid =gg.getClassid();
            TGuideGroup g = new TGuideGroup();
            g.setGuideid(guideid);
            g.setClassid(classid);
            g.setCreateid(createid);
            g.setCreatetime(N_Utils.getSecondTimestamp());
            g.setSchoolid(schoolid);
            savegroup.add(g);

            if(gg.getGroups() != null && gg.getGroups().size() > 0){
                //页面选择的学生预习学生集合
                String groupids = StringUtils.join(gg.getGroups(),",");

                //获取选中班级分组下所有学生
                List<Integer> stus = classMapper.listStudentidsByGroupids(groupids);
                for (Integer studentid : stus) {
                    TGuideGroupStudent ggs = new TGuideGroupStudent();
                    ggs.setGuideid(guideid);
                    ggs.setClassid(classid);
                    ggs.setStudentid(studentid);
                    ggs.setCosttime(0);
                    ggs.setCreatetime(N_Utils.getSecondTimestamp());
                    ggs.setSchoolid(schoolid);
                    savestus.add(ggs);

                }
            }
        }

        //集团校班级学生
        List<Map> jtrclist = guide.getJtrclist();
        if(N_Utils.isListNotEmpty(jtrclist)) {
            for (Map schoolmap : jtrclist) {
                schoolid = Integer.parseInt(schoolmap.get("schoolid").toString());
                List<Map> classlist = (List<Map>) schoolmap.get("classlist");
                for(Map classmap : classlist) {
                    Integer classid = Integer.parseInt(classmap.get("classid").toString());
                    List<Integer> grouplist = (List<Integer>) classmap.get("groups");
                    if (N_Utils.isListNotEmpty(grouplist)) {
                        TGuideGroup g = new TGuideGroup();
                        g.setGuideid(guideid);
                        g.setClassid(classid);
                        g.setCreateid(createid);
                        g.setCreatetime(N_Utils.getSecondTimestamp());
                        g.setSchoolid(schoolid);
                        savegroup.add(g);

                        //页面选择的学生预习学生集合
                        String groupids = StringUtils.join(grouplist,",");

                        //获取选中班级分组下所有学生
                        List<Integer> stus = classMapper.listStudentidsByGroupids(groupids);
                        for (Integer studentid : stus) {
                            TGuideGroupStudent ggs = new TGuideGroupStudent();
                            ggs.setGuideid(guideid);
                            ggs.setClassid(classid);
                            ggs.setStudentid(studentid);
                            ggs.setCosttime(0);
                            ggs.setCreatetime(N_Utils.getSecondTimestamp());
                            ggs.setSchoolid(schoolid);
                            savestus.add(ggs);
                        }
                    }
                }
            }
        }

        if(savestus == null || savestus.size() == 0){
            throw new Exception("未选择学生");
        }

        //保存预习班级、预习学生信息
        guideGroupMapper.insertList(savegroup);
        guideGroupStudentMapper.insertList(savestus);
    }

    //删除预习
    @Transactional
    public void delete(Integer guideid){
        //获取预习关联的资源信息
        List<Map> resources = guideResourceMapper.listResourcesByGuideid(guideid);
        //删除预习
        guideMapper.deleteByGuideid(guideid);
        List<String> resourceUrls = new ArrayList<>();
        //删除预习关联资源
        for(int i=0;i<resources.size();i++){
            String resourceid = resources.get(i).get("resourceid").toString();

            //先判断该资源是否是从我的空间中分享过来的
            Integer count = resourceMapper.getResourceNumByLevelAndResourceid(resourceid);
            if(count==0){
                // count=0,说明该资源不在我的空间使用，如果大于0说明是我的空间分享的资源，资源不能删除
                resourceMapper.deleteByIdReal(resourceid);
                Map resource = resources.get(i);
                String resourceurl = resource.get("resourceurl").toString();
                resourceUrls.add(resourceurl);
                if(N_Utils.isNotEmpty(resource.get("pdfurl"))){
                    String pdfurl = resource.get("pdfurl").toString();
                    resourceUrls.add(pdfurl);
                }
                if(N_Utils.isNotEmpty(resource.get("resourcecover"))){
                    String resourcecover = resource.get("resourcecover").toString();
                    resourceUrls.add(resourcecover);
                }
            }
        }

        if(resourceUrls!=null && resourceUrls.size()>0){
            messageSender.resourceDel(resourceUrls);//给文件服务器发送mq删除文件
        }
    }

    /**
     * 获取年级下学生预习统计列表
     * @Param [paper]
     * @Author ywx
     * @Date 2020/9/28 11:42
     * @return java.util.List<com.xhkjedu.vo.resource.GuideAnalyzeVo>
     **/
    public List<GuideAnalyzeVo> getPreviewAnalyze(AnalyzeSearchVo paper) {
        //setYear(paper);
        setClassIds(paper);//设置教师权限班级
        List<GuideAnalyzeVo> list = guideMapper.listUser(paper);
        List<GuideAnalyzeVo> guidelist = guideMapper.getPreviewAnalyze(paper);//获取有预习教师的预习情况

        if(guidelist!=null && guidelist.size()>0){
            //处理有作业的教师的预习情况
            for(GuideAnalyzeVo ga : guidelist){
                GuideAnalyzeVo teacher = list.stream().filter(t -> t.getTeacherid().equals(ga.getTeacherid())).findFirst().orElse(null);
                if(teacher != null){
                    Integer yyxnum = ga.getYyxnum();
                    Integer yxnum = ga.getYxnum();
                    teacher.setFbnum(ga.getFbnum());
                    teacher.setYyxnum(yyxnum);
                    teacher.setYxnum(yxnum);
                    teacher.setYxrate(N_Utils.getIntegerDivideAndMulitiply(yxnum, yyxnum));
                }
            }
        }
        return list.stream().sorted(Comparator.comparing(GuideAnalyzeVo::getFbnum).reversed()
                                              .thenComparing(GuideAnalyzeVo::getTeachername)).collect(Collectors.toList());
    }

    //设置年份
    public void setYear(AnalyzeSearchVo paper) {
        Integer year;
        if (paper.getSchoolid() != null) {
            year = schoolMapper.getYearById(paper.getSchoolid());
        } else {
            Integer studentid = paper.getStudentid();
            Integer teacherid = paper.getTeacherid();
            Integer userid = studentid == null ? teacherid : studentid;
            year = schoolMapper.getYearByUserId(userid);
        }
        paper.setYear(year);
    }

    //设置教师权限班级
    public void setClassIds(AnalyzeSearchVo paper) {
        if (paper.getUsertype() == 1 && N_Utils.isEmptyInteger(paper.getClassid())) {
            String classIds = classMapper.getClassIds(paper);//获取教师任教行政和提高班id
            paper.setClassids(classIds);
        }
    }

    /**
     * 获取年级下教师发布学生预习列表
     * @Param [paper]
     * @Author ywx
     * @Date 2020/9/28 14:16
     **/
    public List<Map> listPreview(AnalyzeSearchVo paper) {
        return guideMapper.listPreview(paper);
    }


    //预习统计--按学生列表
    public List<Map> listPreviewStuGrade(AnalyzeSearchVo paper) {
        List<Map> list = guideMapper.listPreviewStuGrade(paper);
        List<Map> classlist = classMapper.getClassBySchoolid(paper.getSchoolid(),paper.getYear());
        Map<Integer,Map> stuMap = new HashMap();//存放学生班级信息
        for(Map stu : classlist){
            Integer studentid = (Integer) stu.get("studentid");
            stuMap.put(studentid,stu);
        }

        for (Map map : list) {
            Integer studentid = (Integer) map.get("studentid");
            Map stuStr = stuMap.get(studentid);
            if (stuStr != null) {
                map.put("gradeid", stuStr.get("gradeid").toString());
                map.put("classname", stuStr.get("classname").toString());
            }
        }
        return list;
    }

    //预习统计--按学生详情
    public Map listPreviewStuDetail(AnalyzeSearchVo paper) {
        setClassIds(paper);//设置教师权限班级
        Map map = new HashMap();
        List<AStudentPaperVo> subjects = guideMapper.listPreviewStuDetail(paper);
        Integer sdnum = subjects.stream().mapToInt(AStudentPaperVo::getSdnum).sum();
        map.put("sdnum",sdnum);
        Integer commitnum = subjects.stream().mapToInt(AStudentPaperVo::getCommitnum).sum();
        map.put("commitnum",commitnum);
        map.put("commitrate", N_Utils.getIntegerDivideAndMulitiply(commitnum,sdnum));
        map.put("subjects",subjects);
        return map;
    }


    //预习统计--按学生导出
    public Map listPreviewStuExport(AnalyzeSearchVo paper) {
        Map map = new HashMap();
        Integer schoolid = paper.getSchoolid();
        //TSchool school = schoolMapper.selectByPrimaryKey(schoolid);
        //paper.setYear(school.getYear());
        setClassIds(paper);//设置教师权限班级
        Map slist = new HashMap();
        List<AStudentPaperVo> subjects = new ArrayList<>();
        List<AStudentPaperVo> students = classMapper.listStu(paper);
        for (AStudentPaperVo student : students) {
            Integer studentid = student.getStudentid();
            paper.setStudentid(studentid);
            List<AStudentPaperVo> papers = guideMapper.listPreviewStuExport(paper);
            //按学生统计
            setRate(student, papers);//设置学生预习比例

            //按科目统计
            Map<String, List<AStudentPaperVo>> scollect = papers.stream().collect(Collectors.groupingBy(AStudentPaperVo::getSubjectid));
            for(Map.Entry s:scollect.entrySet()){
                List<AStudentPaperVo> subjects2 = (List<AStudentPaperVo>) s.getValue();
                AStudentPaperVo subject = subjects2.get(0);
                setRate(subject,subjects2);//设置学生预习比例
                String subjectid = subject.getSubjectid();
                String subjectname = (String) slist.get(subjectid);
                if (N_Utils.isEmpty(subjectname)) {
                    subjectname = subjectMapper.getNameById(subjectid);
                }
                subject.setSubjectname(subjectname);
                subject.setStudentname(student.getStudentname());
                subject.setLoginname(student.getLoginname());
                subject.setGradeid(student.getGradeid());
                subject.setClassname(student.getClassname());
                subjects.add(subject);
            }
        }
        students = students.stream().sorted(Comparator
                .comparing(AStudentPaperVo::getCommitnum).reversed()
                .thenComparing(AStudentPaperVo::getStudentid)
        ).collect(Collectors.toList());
        map.put("students", students);
        map.put("subjects", subjects);
        return map;
    }

    //设置学生预习比例
    private void setRate(AStudentPaperVo student, List<AStudentPaperVo> papers) {
        Integer sdnum = papers.size();
        student.setSdnum(sdnum);
        Integer commitnum = papers.stream().filter(p -> p.getPsstate() != 0).collect(Collectors.toList()).size();
        student.setCommitnum(commitnum);
        student.setCommitrate(N_Utils.getIntegerDivideAndMulitiply(commitnum, sdnum));
    }

    //预习关联班级
    public Map listGuideClassByGuide(TGuide guide){
        Map<String,List<Map>> rtnMap = new LinkedHashMap<>();
        //获取本背诵内容
        TGuide guideObj = guideMapper.selectByPrimaryKey(guide.getGuideid());

        if (guide.getCreateid().equals(guideObj.getCreateid())) {//自己发布的看所有班级
            guide.setClassids(null);
        } else if(guideObj.getHashb() == 1 && guide.getSchoolid().equals(guideObj.getSchoolid())){
            //当前登录用户发布的包含伙伴学校的内容
        }else{
            guide.setClassids(guide.getBxclassids());
        }

        List<Map> classlist = guideMapper.listGuideClassByGuide(guide);

        List<Map> bxclass = new ArrayList<>();
        List<Map> hbclass = new ArrayList<>();
        if(N_Utils.isListNotEmpty(classlist)){
            for(Map map : classlist){
                Integer gschoolid = Integer.parseInt(map.get("schoolid").toString());
                if(gschoolid.equals(guideObj.getSchoolid())){
                    //代表本校
                    bxclass.add(map);
                }else{
                    hbclass.add(map);
                }
            }
        }

        rtnMap.put("bx",bxclass);
        rtnMap.put("hb",hbclass);

        return rtnMap;
    }

    //获取预习年份
    public Integer getYearById(Integer guideid){
        return guideMapper.getYearById(guideid);
    }

    /*
     * @Description 获取预习是否存在
     * @Date 2023/12/4 17:05:30
     * @Author WN
     * @Param [guideid]
     * @Return boolean
     **/
    public boolean getGuideidInfo(Integer guideid){
        Integer gid = guideMapper.getGuideIdInfo(guideid);
        return N_Utils.isTrueInteger(gid);
    }
}
