package com.yonge.cooleshow.biz.dal.service.impl;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.yonge.cooleshow.biz.dal.dao.CourseScheduleDao;
import com.yonge.cooleshow.biz.dal.dao.HomeDao;
import com.yonge.cooleshow.biz.dal.dto.SubjectHomeSearch;
import com.yonge.cooleshow.biz.dal.dto.req.TotalReq;
import com.yonge.cooleshow.biz.dal.enums.CourseScheduleEnum;
import com.yonge.cooleshow.biz.dal.enums.TeacherTagEnum;
import com.yonge.cooleshow.biz.dal.service.CourseScheduleService;
import com.yonge.cooleshow.biz.dal.service.HomeService;
import com.yonge.cooleshow.biz.dal.support.WrapperUtil;
import com.yonge.cooleshow.biz.dal.vo.CourseHomeVo;
import com.yonge.cooleshow.biz.dal.vo.SubjectHomeVo;
import com.yonge.cooleshow.biz.dal.vo.TagTotalTeacher;
import com.yonge.cooleshow.biz.dal.vo.res.HomeTotalStudent;
import com.yonge.cooleshow.biz.dal.vo.res.HomeTotalTeacher;
import com.yonge.cooleshow.biz.dal.vo.res.HomeUserToDoNum;
import com.yonge.cooleshow.common.entity.HttpResponseResult;
import com.yonge.toolset.base.page.PageInfo;
import com.yonge.toolset.mybatis.support.PageUtil;
import org.apache.commons.collections.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.time.LocalDate;
import java.time.temporal.TemporalAdjusters;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * @Author: liweifan
 * @Data: 2022/3/30 18:08
 */
@Service
public class HomeServiceImpl implements HomeService {
    @Autowired
    private HomeDao baserMapper;
    @Autowired
    private CourseScheduleService courseScheduleService;

    @Override
    public HomeUserToDoNum getUserToDoNum() {
        HomeUserToDoNum userToDoNum = baserMapper.getUserToDoNum();
        userToDoNum.setEntryNum(null == userToDoNum.getEntryNum() ? 0 : userToDoNum.getEntryNum());
        userToDoNum.setMusicianNum(null == userToDoNum.getMusicianNum() ? 0 : userToDoNum.getMusicianNum());
        userToDoNum.setMusicNum(null == userToDoNum.getMusicNum() ? 0 : userToDoNum.getMusicNum());
        userToDoNum.setVideoCourseNum(null == userToDoNum.getVideoCourseNum() ? 0 : userToDoNum.getVideoCourseNum());
        userToDoNum.setStyleNum(null == userToDoNum.getStyleNum()? 0 : userToDoNum.getStyleNum());
        return userToDoNum;
    }

    @Override
    public HttpResponseResult<HomeTotalTeacher> totalTeacher(TotalReq query) {
        //统计查询
        List<HomeTotalTeacher> totalList = baserMapper.totalTeacher(query.getTimeType().getCode(), query);

        // 点亮图标
        List<TagTotalTeacher> tagList = baserMapper.tagTeacher(query.getTimeType().getCode(), query);

        Map<String, Map<String, List<TagTotalTeacher>>> tagTimeTypeGroup = tagList.stream()
                                                                         .collect(Collectors.groupingBy(
                                                                                 TagTotalTeacher::getTimeStr,
                                                                                 Collectors.groupingBy(
                                                                                         TagTotalTeacher::getTagType)));
        Map<String, Map<Long, List<TagTotalTeacher>>> tagTimeUserGroup = tagList.stream()
                                                                       .collect(Collectors.groupingBy(
                                                                               TagTotalTeacher::getTimeStr,
                                                                               Collectors.groupingBy(
                                                                                       TagTotalTeacher::getUserId)));

        Integer registerNum = 0;
        Integer entryNum = 0;
        Integer liveNum = 0;
        Integer musicianNum = 0;
        Integer tagNum  = tagList.stream().collect(Collectors.groupingBy(TagTotalTeacher::getUserId)).size();
        Integer styleTagNum = 0;
        Integer videoTagNum = 0;
        Integer liveTagNum = 0;
        Integer musicTagNum = 0;
        for (HomeTotalTeacher totalTeacher : totalList) {
            totalTeacher.setRegisterNum(null == totalTeacher.getRegisterNum() ? 0 : totalTeacher.getRegisterNum());
            totalTeacher.setEntryNum(null == totalTeacher.getEntryNum() ? 0 : totalTeacher.getEntryNum());
            totalTeacher.setLiveNum(null == totalTeacher.getLiveNum() ? 0 : totalTeacher.getLiveNum());
            totalTeacher.setMusicianNum(null == totalTeacher.getMusicianNum() ? 0 : totalTeacher.getMusicianNum());

            Map<String, List<TagTotalTeacher>> typeGroup = tagTimeTypeGroup.get(totalTeacher.getTimeStr());
            if (typeGroup != null) {
                List<TagTotalTeacher> liveTagList = typeGroup.get(TeacherTagEnum.LIVE.getCode());
                List<TagTotalTeacher> musicTagList = typeGroup.get(TeacherTagEnum.MUSIC.getCode());
                List<TagTotalTeacher> styleTagList = typeGroup.get(TeacherTagEnum.STYLE.getCode());
                List<TagTotalTeacher> videoTagList = typeGroup.get(TeacherTagEnum.VIDEO.getCode());
                totalTeacher.setLiveTagNum(CollectionUtils.isEmpty(liveTagList) ? 0:liveTagList.size());
                totalTeacher.setMusicTagNum(CollectionUtils.isEmpty(musicTagList) ? 0:musicTagList.size());
                totalTeacher.setStyleTagNum(CollectionUtils.isEmpty(styleTagList) ? 0:styleTagList.size());
                totalTeacher.setVideoTagNum(CollectionUtils.isEmpty(videoTagList) ? 0:videoTagList.size());
            } else {
                totalTeacher.setLiveTagNum(0);
                totalTeacher.setMusicTagNum(0);
                totalTeacher.setStyleTagNum(0);
                totalTeacher.setVideoTagNum(0);
            }


            Map<Long, List<TagTotalTeacher>> userGroup = tagTimeUserGroup.get(totalTeacher.getTimeStr());

            if (userGroup != null) {

                totalTeacher.setTagNum(userGroup.size());
            } else {
                totalTeacher.setTagNum(0);
            }


            registerNum += totalTeacher.getRegisterNum();
            entryNum += totalTeacher.getEntryNum();
            liveNum += totalTeacher.getLiveNum();
            musicianNum += totalTeacher.getMusicianNum();
            styleTagNum += totalTeacher.getStyleTagNum();
            videoTagNum += totalTeacher.getVideoTagNum();
            liveTagNum += totalTeacher.getLiveTagNum();
            musicTagNum += totalTeacher.getMusicTagNum();
        }
        HomeTotalTeacher total = new HomeTotalTeacher();
        total.setRegisterNum(registerNum);
        total.setEntryNum(entryNum);
        total.setLiveNum(liveNum);
        total.setMusicianNum(musicianNum);
        total.setTagNum(tagNum);
        total.setStyleTagNum(styleTagNum);
        total.setVideoTagNum(videoTagNum);
        total.setLiveTagNum(liveTagNum);
        total.setMusicTagNum(musicTagNum);
        total.setInfoList(totalList);
        return HttpResponseResult.succeed(total);
    }

    @Override
    public HttpResponseResult<HomeTotalStudent> totalStudent(TotalReq query) {
        List<HomeTotalStudent> totalList = baserMapper.totalStudent(query.getTimeType().getCode(), query);
        Integer registerNum = 0;
        Integer vipNum = 0;
        Integer practiceNum = 0;
        Integer videoNum = 0;
        Integer liveNum = 0;
        Integer musicNum = 0;
        Integer shoppingNum = 0;
        Integer payStudentNum = 0;

        for (HomeTotalStudent totalStudent : totalList) {
            totalStudent.setRegisterNum(null == totalStudent.getRegisterNum() ? 0 : totalStudent.getRegisterNum());
            totalStudent.setVipNum(null == totalStudent.getVipNum() ? 0 : totalStudent.getVipNum());
            totalStudent.setPracticeNum(null == totalStudent.getPracticeNum() ? 0 : totalStudent.getPracticeNum());
            totalStudent.setVideoNum(null == totalStudent.getVideoNum() ? 0 : totalStudent.getVideoNum());
            totalStudent.setLiveNum(null == totalStudent.getLiveNum() ? 0 : totalStudent.getLiveNum());
            totalStudent.setMusicNum(null == totalStudent.getMusicNum() ? 0 : totalStudent.getMusicNum());
            totalStudent.setShoppingNum(null == totalStudent.getShoppingNum() ? 0 : totalStudent.getShoppingNum());
            totalStudent.setPayStudentNum(null == totalStudent.getPayStudentNum() ? 0 : totalStudent.getPayStudentNum());

            registerNum += totalStudent.getRegisterNum();
            vipNum += totalStudent.getVipNum();
            practiceNum += totalStudent.getPracticeNum();
            videoNum += totalStudent.getVideoNum();
            liveNum += totalStudent.getLiveNum();
            musicNum += totalStudent.getMusicNum();
            shoppingNum += totalStudent.getShoppingNum();
            payStudentNum += totalStudent.getPayStudentNum();
        }
        HomeTotalStudent total = new HomeTotalStudent();
        total.setRegisterNum(registerNum);
        total.setVipNum(vipNum);
        total.setPracticeNum(practiceNum);
        total.setVideoNum(videoNum);
        total.setLiveNum(liveNum);
        total.setMusicNum(musicNum);
        total.setShoppingNum(shoppingNum);
        total.setPayStudentNum(payStudentNum);

        total.setInfoList(totalList);
        return HttpResponseResult.succeed(total);
    }

    /**
     * 获取首页课程数据
     * <p>未完成  未开始&进行中
     * <p>已完成  已完成课程
     *
     * @param param 传入参数
     *              <p> - dateTime  如果查询年数据 yyyy   如果查询月数据 yyyy-mm
     *              <p> - type 类型  PRACTICE陪练课  LIVE直播课
     *              <p> - timeType 时间类型 MONTH、月度 YEAR
     */
    public CourseHomeVo queryCourseHomeData(Map<String, Object> param) {
        CourseScheduleEnum.existCourseType(WrapperUtil.toStr(param, "type"), "课程类型参数错误");
        String dateTimeStr = WrapperUtil.toStr(param, "dateTime", "查询时间不能为空!");
        String timeType = WrapperUtil.toStr(param, "timeType", "查询时间不类型不能为空!");
        //按年查询true  按月查询false
        boolean isYear = timeType.equals("YEAR");
        //获取年
        String[] split = dateTimeStr.split("-");
        int year = Integer.parseInt(split[0]);
        //获取月
        int month = isYear ? 1 : Integer.parseInt(split[1]);
        LocalDate firstDate;
        LocalDate endDate;
        CourseHomeVo result = new CourseHomeVo();
        CourseScheduleDao courseScheduleServiceDao = courseScheduleService.getDao();
        firstDate = LocalDate.of(year, month, 1);
        //获取开始时间
        if (isYear) {
            //查询当年最后一天
            endDate = firstDate.with(TemporalAdjusters.lastDayOfYear());
        } else {
            //查询当月最后一天
            endDate = firstDate.with(TemporalAdjusters.lastDayOfMonth());
        }
        param.put("startDate", firstDate);
        param.put("endDate", endDate);

        //查询数据
        List<CourseHomeVo.CourseHomeInfoVo> courseYearInfoList;
        if (isYear) {
            courseYearInfoList = courseScheduleServiceDao.queryCourseHomeOfYear(param);
        } else {
            courseYearInfoList = courseScheduleServiceDao.queryCourseHomeOfMonth(param);
        }
        if (CollectionUtils.isEmpty(courseYearInfoList)) {
            courseYearInfoList = new ArrayList<>();
        }
        Map<String, CourseHomeVo.CourseHomeInfoVo> collect = courseYearInfoList.stream()
                .collect(Collectors.toMap(CourseHomeVo.CourseHomeInfoVo::getDate, Function.identity(), (key1, key2) -> key2));
        //补全数据
        while (firstDate.isBefore(endDate)) {
            CourseHomeVo.CourseHomeInfoVo infoVo = collect.get(firstDate.toString());
            if (Objects.isNull(infoVo)) {
                infoVo = new CourseHomeVo.CourseHomeInfoVo();
                if (isYear) {
                    infoVo.setDate(firstDate.toString().substring(0, 7));
                } else {
                    infoVo.setDate(firstDate.toString());
                }
                infoVo.setDoneCount(0);
                infoVo.setUndoneCount(0);
                courseYearInfoList.add(infoVo);
            } else {
                if (isYear) {
                    infoVo.setDate(firstDate.toString().substring(0, 7));
                }
            }
            if (isYear) {
                firstDate = firstDate.plusMonths(1L);
            } else {
                firstDate = firstDate.plusDays(1L);
            }
        }
        result.setCourseHomeInfoList(courseYearInfoList);
        //计算总数方法
        Function<Function<CourseHomeVo.CourseHomeInfoVo, Integer>, Integer> reduceFunc = (c) -> result.getCourseHomeInfoList().stream()
                .map(c)
                .reduce(0, Integer::sum);
        result.setTotalDoneCount(reduceFunc.apply(CourseHomeVo.CourseHomeInfoVo::getDoneCount));
        result.setTotalUndoneCount(reduceFunc.apply(CourseHomeVo.CourseHomeInfoVo::getUndoneCount));
        result.setTotalCount(result.getTotalDoneCount() + result.getTotalUndoneCount());
        result.getCourseHomeInfoList().sort(Comparator.comparing(CourseHomeVo.CourseHomeInfoVo::getDate));
        return result;
    }

    @Override
    public PageInfo<SubjectHomeVo> subjectHome(IPage<SubjectHomeVo> page, SubjectHomeSearch query) {
        PageInfo<SubjectHomeVo> subjectHomeVoPageInfo = PageUtil.pageInfo(baserMapper.selectSubjectHome(page, query));
        List<SubjectHomeVo> rows = subjectHomeVoPageInfo.getRows();
        for (int i = 0; i < rows.size(); i++) {
            rows.get(i).setIndex((subjectHomeVoPageInfo.getPageNo() -1) * subjectHomeVoPageInfo.getLimit() + i + 1);
        }
        return subjectHomeVoPageInfo;
    }

}
