package com.zhongzheng.modules.exam.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.ServletUtils;
import com.zhongzheng.modules.course.domain.MajorCategory;
import com.zhongzheng.modules.exam.bo.*;
import com.zhongzheng.modules.exam.domain.ExamNumberGoods;
import com.zhongzheng.modules.exam.mapper.ExamApplyMapper;
import com.zhongzheng.modules.exam.service.IExamNumberGoodsService;
import com.zhongzheng.modules.exam.vo.ExamNumberGoodsVo;
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.exam.domain.ExamNumber;
import com.zhongzheng.modules.exam.mapper.ExamNumberMapper;
import com.zhongzheng.modules.exam.vo.ExamNumberVo;
import com.zhongzheng.modules.exam.service.IExamNumberService;
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-12-06
 */
@Service
public class ExamNumberServiceImpl extends ServiceImpl<ExamNumberMapper, ExamNumber> implements IExamNumberService {

    @Autowired
    private IExamNumberGoodsService examNumberGoodsService;

    @Autowired
    private ExamApplyMapper examApplyMapper;


    @Override
    public ExamNumberVo queryById(Long examNumberId){
        ExamNumberQueryBo examNumberQueryBo = new ExamNumberQueryBo();
        examNumberQueryBo.setExamNumberId(examNumberId);
        List<ExamNumberVo> examNumberVos = baseMapper.ListExamNumber(examNumberQueryBo);
        if (CollectionUtils.isEmpty(examNumberVos)){
            throw new IllegalArgumentException("参数有误");
        }
        ExamNumberVo examNumberVo = examNumberVos.get(0);
        List<ExamNumberGoodsVo> examNumberGoodsVos = examNumberGoodsService.ListExamNumber(examNumberVo.getExamNumberId());
            examNumberVo.setExamNumberGoodsVos(examNumberGoodsVos);

        //初始化需要得到的数组
        Long[] array = new Long[examNumberGoodsVos.size()];

        //使用for循环得到数组
        for(int i = 0; i < examNumberGoodsVos.size();i++){
            array[i] = examNumberGoodsVos.get(i).getGoodsId();
        }
        examNumberVo.setGoodsId(array);
        return examNumberVo;
    }

    @Override
    public List<ExamNumberVo> queryList(ExamNumberQueryBo bo) {
        LambdaQueryWrapper<ExamNumber> lqw = Wrappers.lambdaQuery();
        lqw.eq(StrUtil.isNotBlank(bo.getCode()), ExamNumber::getCode, bo.getCode());
        lqw.eq(bo.getExamNumber() != null, ExamNumber::getExamNumber, bo.getExamNumber());
        lqw.eq(bo.getDoNumber() != null, ExamNumber::getDoNumber, bo.getDoNumber());
        lqw.eq(bo.getStatus() != null, ExamNumber::getStatus, bo.getStatus());
        lqw.eq(bo.getGoodsType() != null, ExamNumber::getGoodsType, bo.getGoodsType());
        lqw.eq(bo.getEducationTypeId() != null, ExamNumber::getEducationTypeId, bo.getEducationTypeId());
        lqw.eq(bo.getBusinessId() != null, ExamNumber::getBusinessId, bo.getBusinessId());
        lqw.eq(bo.getProjectId() != null, ExamNumber::getProjectId, bo.getProjectId());
        return entity2Vo(this.list(lqw));
    }

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

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean insertByAddBo(ExamNumberAddBo bo) {
        ExamNumber add = BeanUtil.toBean(bo, ExamNumber.class);
        validEntityBeforeSave(add);
        add.setCode(ServletUtils.getEncoded("KC"));
        add.setCreateTime(DateUtils.getNowTime());
        add.setUpdateTime(DateUtils.getNowTime());
        boolean save = this.save(add);
        for (Long goodsId : bo.getGoodsId()) {
            ExamNumberGoodsAddBo examNumberGoodsAddBo = new ExamNumberGoodsAddBo();
            examNumberGoodsAddBo.setGoodsId(goodsId);
            examNumberGoodsAddBo.setExamNumberId(add.getExamNumberId());
            examNumberGoodsAddBo.setCreateTime(DateUtils.getNowTime());
            examNumberGoodsAddBo.setUpdateTime(DateUtils.getNowTime());
            examNumberGoodsService.insertByAddBo(examNumberGoodsAddBo);
        }
        return save;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean updateByEditBo(ExamNumberEditBo bo) {
        ExamNumber update = BeanUtil.toBean(bo, ExamNumber.class);
        validEntityBeforeSave(update);
        update.setUpdateTime(DateUtils.getNowTime());
        ExamNumber info = getOne(new LambdaQueryWrapper<ExamNumber>()
                .eq(ExamNumber::getExamNumberId,bo.getExamNumberId())
                .last("limit 1"));
        if (null != bo.getExamNumber()  && info.getExamNumber() > bo.getExamNumber()){
            throw new IllegalArgumentException("考试次数不能小于更改前");
        }

        if (null != bo.getDoNumber()  &&info.getDoNumber() > bo.getDoNumber()){
            throw new IllegalArgumentException("前培次数不能小于更改前");
        }
        if (bo.getGoodsId() != null){
            LambdaQueryWrapper<ExamNumberGoods> lqw = Wrappers.lambdaQuery();
            lqw.eq(ExamNumberGoods::getExamNumberId, bo.getExamNumberId());
            List<ExamNumberGoods> list = examNumberGoodsService.list(lqw);
            if (!CollectionUtils.isEmpty(list)) {
                for (ExamNumberGoods examNumberGoods : list) {
                    if (bo.getStatus() == -1) {
                        Integer apply = baseMapper.selectApply(examNumberGoods.getGoodsId());
                        if (apply > 0) {
                            throw new IllegalArgumentException("当前商品已启用考试安排，不可删除");
                        }

                        Integer applyBefore = baseMapper.selectApplyBefore(examNumberGoods.getGoodsId());
                        if (applyBefore > 0) {
                            throw new IllegalArgumentException("当前商品已启用前培安排，不可删除");
                        }
                    }
                    Integer integer = baseMapper.selectExam(examNumberGoods.getGoodsId(), update.getExamNumberId());
                    if (bo.getStatus() == 1 && integer > 0) {
                        throw new IllegalArgumentException("当前商品已启用考次配置，不可开启,请重新创建新的配置考试次数和前培次数商品");
                    }
                    if (bo.getStatus() == 0) {
                        Integer apply = baseMapper.selectApply(examNumberGoods.getGoodsId());
                        if (apply > 0) {
                            throw new IllegalArgumentException("当前商品已启用考试安排，不可关闭");
                        }
                    }
                }
            }
            LambdaQueryWrapper<ExamNumberGoods> example = Wrappers.lambdaQuery();
            example.eq(ExamNumberGoods::getExamNumberId, bo.getExamNumberId());
            examNumberGoodsService.remove(example);
            for (Long goodsId : bo.getGoodsId()) {
                ExamNumberGoodsAddBo examNumberGoodsAddBo = new ExamNumberGoodsAddBo();
                examNumberGoodsAddBo.setGoodsId(goodsId);
                examNumberGoodsAddBo.setExamNumberId(update.getExamNumberId());
                examNumberGoodsAddBo.setCreateTime(DateUtils.getNowTime());
                examNumberGoodsAddBo.setUpdateTime(DateUtils.getNowTime());
                examNumberGoodsService.insertByAddBo(examNumberGoodsAddBo);
            }
        }
        LambdaQueryWrapper<ExamNumberGoods> example = Wrappers.lambdaQuery();
        example.eq(ExamNumberGoods::getExamNumberId, bo.getExamNumberId());
        List<ExamNumberGoods> list = examNumberGoodsService.list(example);
        if (bo.getStatus() == -1) {
            for (ExamNumberGoods examNumberGoods : list) {
                Integer apply = baseMapper.selectApply(examNumberGoods.getGoodsId());
                if (apply > 0) {
                    throw new IllegalArgumentException("当前商品已启用考试安排，不可删除");
                }
                Integer applyBefore = baseMapper.selectApplyBefore(examNumberGoods.getGoodsId());
                if (applyBefore > 0) {
                    throw new IllegalArgumentException("当前商品已启用前培安排，不可删除");
                }
            }
        }
        return this.updateById(update);
    }

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

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

    @Override
    public List<ExamNumberVo> ListExamNumber(ExamNumberQueryBo bo) {
        List<ExamNumberVo> examNumberVos = baseMapper.ListExamNumber(bo);
        for (ExamNumberVo examNumberVo : examNumberVos) {
            List<ExamNumberGoodsVo> examNumberGoodsVos = examNumberGoodsService.ListExamNumber(examNumberVo.getExamNumberId());
            examNumberVo.setExamNumberGoodsVos(examNumberGoodsVos);
        }
        return examNumberVos;
    }
}
