package com.zhongzheng.modules.inform.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.zhongzheng.common.utils.DateUtils;
import com.zhongzheng.common.utils.SecurityUtils;
import com.zhongzheng.modules.bank.bo.QuestionChapterExamQueryBo;
import com.zhongzheng.modules.bank.bo.QuestionModuleChapterQueryBo;
import com.zhongzheng.modules.bank.mapper.QuestionChapterExamMapper;
import com.zhongzheng.modules.bank.mapper.QuestionModuleChapterMapper;
import com.zhongzheng.modules.bank.vo.ExamVo;
import com.zhongzheng.modules.bank.vo.QuestionChapterVo;
import com.zhongzheng.modules.course.bo.CourseMenuQueryBo;
import com.zhongzheng.modules.course.mapper.CourseChapterSectionMapper;
import com.zhongzheng.modules.course.mapper.CourseModuleChapterMapper;
import com.zhongzheng.modules.course.service.ICourseMenuService;
import com.zhongzheng.modules.course.vo.CourseMenuVo;
import com.zhongzheng.modules.course.vo.CourseModuleChapterVo;
import com.zhongzheng.modules.goods.bo.GoodsAttachedQueryBo;
import com.zhongzheng.modules.goods.bo.GoodsQueryBo;
import com.zhongzheng.modules.goods.mapper.GoodsAttachedMapper;
import com.zhongzheng.modules.goods.vo.GoodsAttachedVo;
import com.zhongzheng.modules.inform.bo.*;
import com.zhongzheng.modules.inform.domain.InformCourse;
import com.zhongzheng.modules.inform.domain.InformExam;
import com.zhongzheng.modules.inform.domain.InformUser;
import com.zhongzheng.modules.inform.service.IInformCourseService;
import com.zhongzheng.modules.inform.service.IInformExamService;
import com.zhongzheng.modules.inform.service.IInformUserService;
import com.zhongzheng.modules.inform.vo.CourseInformVo;
import com.zhongzheng.modules.inform.vo.GoodsInformAttachedVo;
import com.zhongzheng.modules.inform.vo.InformUserVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.github.pagehelper.Page;
import com.zhongzheng.modules.inform.domain.Inform;
import com.zhongzheng.modules.inform.mapper.InformMapper;
import com.zhongzheng.modules.inform.vo.InformVo;
import com.zhongzheng.modules.inform.service.IInformService;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 【请填写功能名称】Service业务层处理
 *
 * @author ruoyi
 * @date 2021-11-23
 */
@Service
public class InformServiceImpl extends ServiceImpl<InformMapper, Inform> implements IInformService {

    @Autowired
    private IInformCourseService iInformCourseService;

    @Autowired
    private IInformExamService iInformExamService;

    @Autowired
    private IInformUserService iInformUserService;

    @Autowired
    private ICourseMenuService iCourseMenuService;

    @Autowired
    private CourseChapterSectionMapper courseChapterSectionMapper;

    @Autowired
    private CourseModuleChapterMapper courseModuleChapterMapper;

    @Autowired
    private GoodsAttachedMapper goodsAttachedMapper;

    @Autowired
    private QuestionModuleChapterMapper questionModuleChapterMapper;

    @Autowired
    private QuestionChapterExamMapper questionChapterExamMapper;



    @Override
    public InformVo queryById(Long informId){
        Inform db = this.baseMapper.selectById(informId);
        return BeanUtil.toBean(db, InformVo.class);
    }

    @Override
    public List<InformVo> queryList(InformQueryBo bo) {
        LambdaQueryWrapper<Inform> lqw = Wrappers.lambdaQuery();
        lqw.eq(bo.getInformType() != null, Inform::getInformType, bo.getInformType());
        lqw.like(StrUtil.isNotBlank(bo.getInformName()), Inform::getInformName, bo.getInformName());
        lqw.eq(bo.getInformWay() != null, Inform::getInformWay, bo.getInformWay());
        lqw.eq(bo.getClassifyId() != null, Inform::getClassifyId, bo.getClassifyId());
        lqw.eq(bo.getIssueStatus() != null, Inform::getIssueStatus, bo.getIssueStatus());
        lqw.eq(bo.getIssueTime() != null, Inform::getIssueTime, bo.getIssueTime());
        lqw.eq(bo.getReceiptStatus() != null, Inform::getReceiptStatus, bo.getReceiptStatus());
        lqw.eq(StrUtil.isNotBlank(bo.getAffiche()), Inform::getAffiche, bo.getAffiche());
        lqw.eq(bo.getStatus() != null, Inform::getStatus, bo.getStatus());
        return entity2Vo(this.list(lqw));
    }

    /**
    * 实体类转化成视图对象
    *
    * @param collection 实体类集合
    * @return
    */
    private List<InformVo> entity2Vo(Collection<Inform> collection) {
        List<InformVo> voList = collection.stream()
                .map(any -> BeanUtil.toBean(any, InformVo.class))
                .collect(Collectors.toList());
        if (collection instanceof Page) {
            Page<Inform> page = (Page<Inform>)collection;
            Page<InformVo> pageVo = new Page<>();
            BeanUtil.copyProperties(page,pageVo);
            pageVo.addAll(voList);
            voList = pageVo;
        }
        return voList;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean insertByAddBo(InformAddBo bo) {
        Inform add = BeanUtil.toBean(bo, Inform.class);
        validEntityBeforeSave(add);
        add.setCreateTime(DateUtils.getNowTime());
        add.setUpdateTime(DateUtils.getNowTime());
        add.setCreateBy(SecurityUtils.getUsername());
        boolean save = this.save(add);
        for (InformExamAddBo informExamAddBo : bo.getInformExamAddBo()) {
            informExamAddBo.setInformId(add.getInformId());
            iInformExamService.insertByAddBo(informExamAddBo);
        }
        for (InformCourseAddBo informCourseAddBo : bo.getInformCourseAddBo()) {
            informCourseAddBo.setInformId(add.getInformId());
            iInformCourseService.insertByAddBo(informCourseAddBo);
        }
        for (Long userId : bo.getUserId()) {
            if (bo.getOrderStatus().equals(2)) {
                Integer integer = selectNumList(userId, bo.getInformExamAddBo(), bo.getInformCourseAddBo());
                if (integer.equals(0)){
                    continue;
                }
            }
            InformUserAddBo informUserAddBo = new InformUserAddBo();
            informUserAddBo.setInformId(add.getInformId());
            informUserAddBo.setUserId(userId);
            informUserAddBo.setCreateTime(DateUtils.getNowTime());
            informUserAddBo.setUpdateTime(DateUtils.getNowTime());
            iInformUserService.insertByAddBo(informUserAddBo);
        }
        return save;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean updateByEditBo(InformEditBo bo) {
        if (bo.getStatus() == -1){
            for (Long informId : bo.getInformIds()) {
                Inform update = new Inform();
                update.setInformId(informId);
                update.setStatus(-1);
                return  this.updateById(update);
            }
        }
        Inform update = BeanUtil.toBean(bo, Inform.class);
        validEntityBeforeSave(update);
        update.setUpdateTime(DateUtils.getNowTime());
        LambdaQueryWrapper<InformExam> lqw = Wrappers.lambdaQuery();
        lqw.eq( InformExam::getInformId, update.getInformId());
        iInformExamService.remove(lqw);
        LambdaQueryWrapper<InformCourse> informCount = Wrappers.lambdaQuery();
        informCount.eq(InformCourse::getInformId, update.getInformId());
        iInformCourseService.remove(informCount);
        LambdaQueryWrapper<InformUser> informUser = Wrappers.lambdaQuery();
        informUser.eq(InformUser::getInformId, update.getInformId());
        iInformUserService.remove(informUser);
        if (CollectionUtils.isNotEmpty(bo.getInformExamAddBo())) {
            for (InformExamAddBo informExamAddBo : bo.getInformExamAddBo()) {
                informExamAddBo.setInformId(update.getInformId());
                iInformExamService.insertByAddBo(informExamAddBo);
            }
        }
        if (CollectionUtils.isNotEmpty(bo.getInformCourseAddBo())) {
            for (InformCourseAddBo informCourseAddBo : bo.getInformCourseAddBo()) {
                informCourseAddBo.setInformId(update.getInformId());
                iInformCourseService.insertByAddBo(informCourseAddBo);
            }
        }
        if (bo.getUserId() != null) {
            for (Long userId : bo.getUserId()) {
                if (bo.getOrderStatus().equals(2)) {
                    Integer integer = selectNumList(userId, bo.getInformExamAddBo(), bo.getInformCourseAddBo());
                    if (integer.equals(0)) {
                        continue;
                    }
                }
                InformUserAddBo informUserAddBo = new InformUserAddBo();
                informUserAddBo.setInformId(update.getInformId());
                informUserAddBo.setUserId(userId);
                informUserAddBo.setCreateTime(DateUtils.getNowTime());
                informUserAddBo.setUpdateTime(DateUtils.getNowTime());
                iInformUserService.insertByAddBo(informUserAddBo);
            }
        }
        return this.updateById(update);
    }

    /**
     * 保存前的数据校验
     *
     * @param entity 实体类数据
     */
    private void validEntityBeforeSave(Inform entity){
        //TODO 做一些数据校验,如唯一约束
    }

    @Override
    public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
        if(isValid){
            //TODO 做一些业务上的校验,判断是否需要校验
        }
        return this.removeByIds(ids);
    }

    @Override
    public List<InformVo> listInform(InformQueryBo bo) {
        List<InformVo> informVos = baseMapper.listInform(bo);
        for (InformVo informVo : informVos) {
            informVo.setInformExamVo(iInformExamService.queryExam(informVo.getInformId()));
            informVo.setInformCourseVo(iInformCourseService.queryCourse(informVo.getInformId()));
            InformUserQueryBo informUserQueryBo = new InformUserQueryBo();
            informUserQueryBo.setInformId(informVo.getInformId());
            List<Long> userId = new ArrayList<>();
            for (InformUserVo informUserVo : iInformUserService.queryUserList(informUserQueryBo)) {
                userId.add(informUserVo.getUserId());
            }
            //初始化需要得到的数组
            Long[] array = new Long[userId.size()];

            //使用for循环得到数组
            for(int i = 0; i < userId.size();i++){
                array[i] = userId.get(i);
            }
            informVo.setUserId(array);

        }
        return informVos;
    }

    @Override
    public Integer selectNum(InformAddBo bo) {
        Integer number = 0;
        for (Long userId : bo.getUserId()) {
            Integer num = 0;
            for (InformExamAddBo informExamAddBo : bo.getInformExamAddBo()) {
                Integer integer = baseMapper.selectOrder(informExamAddBo.getGoodsId(),userId);
                if (integer >0){
                    num++;
                }
            }
            for (InformCourseAddBo informCourseAddBo : bo.getInformCourseAddBo()) {
                Integer integer = baseMapper.selectOrder(informCourseAddBo.getGoodsId(),userId);
                if (integer >0){
                    num++;
                }
            }
            if (num==0){
                number++;
            }
        }
        return number;
    }

    @Override
    public List<CourseInformVo> listGoodsCourse(GoodsQueryBo bo) {
        List<CourseInformVo> courseInformVos = baseMapper.listGoodsCourse(bo);
        for (CourseInformVo courseInformVo : courseInformVos) {
            CourseMenuQueryBo courseMenuQueryBo = new CourseMenuQueryBo();
            courseMenuQueryBo.setCourseId(courseInformVo.getCourseId());
            List<CourseMenuVo> list = iCourseMenuService.selectList(courseMenuQueryBo);
            for (CourseMenuVo courseMenuVo : list) {
                if (courseMenuVo.getType().equals(1)){
                    List<CourseModuleChapterVo> listById = courseModuleChapterMapper.getListById(courseMenuVo.getMenuId());
                    for (CourseModuleChapterVo courseModuleChapterVo : listById) {
                        courseModuleChapterVo.setCourseChapterSectionList(courseChapterSectionMapper.getInformById(courseModuleChapterVo.getChapterId()));
                    }
                    courseMenuVo.setCourseModuleChapterVos(listById);
                }
                if (courseMenuVo.getType().equals(2)){
                    courseMenuVo.setCourseChapterSectionList(courseChapterSectionMapper.getInformById(courseMenuVo.getMenuId()));
                }
            }
            courseInformVo.setCourseMenuList(list);
        }
        return courseInformVos;
    }

    @Override
    public List<GoodsInformAttachedVo> bankList(GoodsAttachedQueryBo bo) {
        List<GoodsInformAttachedVo> goodsInformAttachedVos = entity2BankVo(goodsAttachedMapper.selectList(bo));
        for (GoodsInformAttachedVo goodsInformAttachedVo : goodsInformAttachedVos) {
            if (goodsInformAttachedVo.getType().equals(1)){
                QuestionModuleChapterQueryBo questionModuleChapterQueryBo = new QuestionModuleChapterQueryBo();
                questionModuleChapterQueryBo.setModuleExamId(goodsInformAttachedVo.getMajorId());
                List<QuestionChapterVo> list = questionModuleChapterMapper.getList(questionModuleChapterQueryBo);
                for (QuestionChapterVo questionChapterVo : list) {
                    QuestionChapterExamQueryBo questionChapterExamQueryBo = new QuestionChapterExamQueryBo();
                    questionChapterExamQueryBo.setChapterExamId(questionChapterVo.getChapterExamId());
                    List<ExamVo> list1 = questionChapterExamMapper.getList(questionChapterExamQueryBo);
                    questionChapterVo.setExamVos(list1);
                }
                goodsInformAttachedVo.setQuestionChapterVos(list);
            }
            if (goodsInformAttachedVo.getType().equals(2)){
                QuestionChapterExamQueryBo questionChapterExamQueryBo = new QuestionChapterExamQueryBo();
                questionChapterExamQueryBo.setChapterExamId(goodsInformAttachedVo.getMajorId());
                List<ExamVo> list1 = questionChapterExamMapper.getList(questionChapterExamQueryBo);
                goodsInformAttachedVo.setExamVos(list1);
            }
        }
        return goodsInformAttachedVos;
    }

    @Override
    public boolean editClassifyId(InformEditBo bo) {
        Inform update = BeanUtil.toBean(bo, Inform.class);
        validEntityBeforeSave(update);
        update.setUpdateTime(DateUtils.getNowTime());
        return this.updateById(update);
    }


    /**
     * 实体类转化成视图对象
     *
     * @param collection 实体类集合
     * @return
     */
    private List<GoodsInformAttachedVo> entity2BankVo(Collection<GoodsAttachedVo> collection) {
        List<GoodsInformAttachedVo> voList = collection.stream()
                .map(any -> BeanUtil.toBean(any, GoodsInformAttachedVo.class))
                .collect(Collectors.toList());

        return voList;
    }
    public Integer selectNumList(Long userId, List<InformExamAddBo> informExamAddBos,List<InformCourseAddBo> informCourseAddBos) {
        Integer number = 0;
            for (InformExamAddBo informExamAddBo : informExamAddBos) {
                Integer integer = baseMapper.selectOrder(informExamAddBo.getGoodsId(),userId);
                if (integer >0){
                    number++;
                }
            }
            for (InformCourseAddBo informCourseAddBo : informCourseAddBos) {
                Integer integer = baseMapper.selectOrder(informCourseAddBo.getGoodsId(),userId);
                if (integer >0){
                    number++;
                }
            }
        return number;
    }
}
