package org.dromara.system.service.impl;

import cn.hutool.core.util.ObjectUtil;
import org.dromara.common.core.exception.ServiceException;
import org.dromara.common.core.utils.DateUtils;
import org.dromara.common.core.utils.MapstructUtils;
import org.dromara.common.core.utils.StringUtils;
import org.dromara.common.mybatis.core.page.TableDataInfo;
import org.dromara.common.mybatis.core.page.PageQuery;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import lombok.RequiredArgsConstructor;
import org.dromara.system.domain.AskLeaveCourse;
import org.dromara.system.domain.AskLeaveFj;
import org.dromara.system.domain.SysUser;
import org.dromara.system.domain.bo.AskLeaveCourseBo;
import org.dromara.system.domain.bo.AskLeaveFjBo;
import org.dromara.system.domain.vo.AskLeaveCourseVo;
import org.dromara.system.domain.vo.AskLeaveFjVo;
import org.dromara.system.domain.vo.CourseTableVo;
import org.dromara.system.mapper.AskLeaveCourseMapper;
import org.dromara.system.mapper.AskLeaveFjMapper;
import org.springframework.stereotype.Service;
import org.dromara.system.domain.bo.AskLeaveBo;
import org.dromara.system.domain.vo.AskLeaveVo;
import org.dromara.system.domain.AskLeave;
import org.dromara.system.mapper.AskLeaveMapper;
import org.dromara.system.service.IAskLeaveService;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.stream.Collectors;

/**
 * 请假Service业务层处理
 *
 * @author boman
 * @date 2024-11-04
 */
@RequiredArgsConstructor
@Service
public class AskLeaveServiceImpl implements IAskLeaveService {

    private final AskLeaveMapper baseMapper;

    private final AskLeaveCourseMapper askLeaveCourseMapper;

    private final AskLeaveFjMapper askLeaveFjMapper;

    /**
     * 查询请假
     */
    @Override
    public AskLeaveVo queryById(Long id){
        AskLeaveVo askLeaveVo = baseMapper.selectVoById(id);
        //查询请假课程信息
        List<AskLeaveCourseVo> askLeaveCourseList = askLeaveCourseMapper.selectVoList(new LambdaQueryWrapper<AskLeaveCourse>()
            .eq(AskLeaveCourse::getLeaveId,askLeaveVo.getId()));
        askLeaveVo.setAskLeaveCourseBoList(askLeaveCourseList);
        //查询请假课附件信息
        List<AskLeaveFjVo> askLeaveFjVoList = askLeaveFjMapper.selectVoList(new LambdaQueryWrapper<AskLeaveFj>()
            .eq(AskLeaveFj::getLeaveId,askLeaveVo.getId()));

        askLeaveVo.setAskLeaveFjBoList(askLeaveFjVoList);
        return askLeaveVo;
    }

    /**
     * 查询请假列表
     */
    @Override
    public TableDataInfo<AskLeaveVo> queryPageList(AskLeaveBo bo, PageQuery pageQuery) {
        LambdaQueryWrapper<AskLeave> lqw = buildQueryWrapper(bo);
        Page<AskLeaveVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);

        List<AskLeaveVo> askLeaveVoList = result.getRecords();
        for (AskLeaveVo askLeaveVo : askLeaveVoList) {
            List<AskLeaveFjVo> askLeaveFjVoList = askLeaveFjMapper.selectVoList(new LambdaQueryWrapper<AskLeaveFj>()
                .eq(AskLeaveFj::getLeaveId,askLeaveVo.getId()));

            askLeaveVo.setAskLeaveFjBoList(askLeaveFjVoList);

            //查询请假课程信息
            List<AskLeaveCourseVo> askLeaveCourseList = askLeaveCourseMapper.selectVoList(new LambdaQueryWrapper<AskLeaveCourse>()
                .eq(AskLeaveCourse::getLeaveId,askLeaveVo.getId()));

            askLeaveVo.setAskLeaveCourseBoList(askLeaveCourseList);
        }

        return TableDataInfo.build(result);
    }

    /**
     * 查询请假列表
     */
    @Override
    public List<AskLeaveVo> queryList(AskLeaveBo bo) {
        LambdaQueryWrapper<AskLeave> lqw = buildQueryWrapper(bo);
        return baseMapper.selectVoList(lqw);
    }

    private LambdaQueryWrapper<AskLeave> buildQueryWrapper(AskLeaveBo bo) {
        Map<String, Object> params = bo.getParams();
        LambdaQueryWrapper<AskLeave> lqw = Wrappers.lambdaQuery();
        lqw.eq(StringUtils.isNotBlank(bo.getSchoolId()), AskLeave::getSchoolId, bo.getSchoolId());
        lqw.like(StringUtils.isNotBlank(bo.getSchoolName()), AskLeave::getSchoolName, bo.getSchoolName());
        lqw.eq(StringUtils.isNotBlank(bo.getClassId()), AskLeave::getClassId, bo.getClassId());
        lqw.like(StringUtils.isNotBlank(bo.getClassName()), AskLeave::getClassName, bo.getClassName());
        lqw.like(StringUtils.isNotBlank(bo.getLeaveName()), AskLeave::getLeaveName, bo.getLeaveName());
        lqw.eq(bo.getLeaveType() != null, AskLeave::getLeaveType, bo.getLeaveType());
        lqw.eq(StringUtils.isNotBlank(bo.getDescription()), AskLeave::getDescription, bo.getDescription());
        lqw.eq(StringUtils.isNotBlank(bo.getLeaveDuration()), AskLeave::getLeaveDuration, bo.getLeaveDuration());
        lqw.eq(StringUtils.isNotBlank(bo.getLeaveFrame()), AskLeave::getLeaveFrame, bo.getLeaveFrame());
        lqw.eq(StringUtils.isNotBlank(bo.getExamineId()), AskLeave::getExamineId, bo.getExamineId());
        lqw.eq(StringUtils.isNotBlank(bo.getExamineResult()), AskLeave::getExamineResult, bo.getExamineResult());
        lqw.eq(StringUtils.isNotBlank(bo.getOpinion()), AskLeave::getOpinion, bo.getOpinion());
        lqw.like(StringUtils.isNotBlank(bo.getExamineName()), AskLeave::getExamineName, bo.getExamineName());
        lqw.orderByDesc(AskLeave::getCreateTime);
        return lqw;
    }

    /**
     * 新增请假
     */
    @Override
    @Transactional
    public Boolean insertByBo(AskLeaveBo bo) {
        bo.setCreateTime(DateUtils.getNowDate());
        bo.setUpdateTime(DateUtils.getNowDate());
        AskLeave add = MapstructUtils.convert(bo, AskLeave.class);
        validEntityBeforeSave(add);
        boolean flag = baseMapper.insert(add) > 0;
        if (flag) {
            bo.setId(add.getId());
        }
        //请假课程信息
        List<AskLeaveCourseBo> askLeaveCourseBoList = bo.getAskLeaveCourseBoList();
        for (AskLeaveCourseBo askLeaveCourseBo : askLeaveCourseBoList) {
            askLeaveCourseBo.setLeaveId(bo.getId());
            askLeaveCourseBo.setCreateTime(DateUtils.getNowDate());
            askLeaveCourseBo.setUpdateTime(DateUtils.getNowDate());
            AskLeaveCourse askLeaveCourse = MapstructUtils.convert(askLeaveCourseBo, AskLeaveCourse.class);
            askLeaveCourseMapper.insert(askLeaveCourse);
        }
        //附件信息
        List<AskLeaveFjBo> askLeaveFjBoList = bo.getAskLeaveFjBoList();
        if(askLeaveFjBoList!=null && askLeaveFjBoList.size()>0){
            for (AskLeaveFjBo askLeaveFjBo : askLeaveFjBoList) {
                askLeaveFjBo.setLeaveId(bo.getId());
                askLeaveFjBo.setCreateTime(DateUtils.getNowDate());
                askLeaveFjBo.setUpdateTime(DateUtils.getNowDate());
                AskLeaveFj askLeaveFj = MapstructUtils.convert(askLeaveFjBo, AskLeaveFj.class);
                askLeaveFjMapper.insert(askLeaveFj);
            }

        }

        return flag;
    }

    /**
     * 修改请假
     */
    @Override
    @Transactional
    public Boolean updateByBo(AskLeaveBo bo) {

        if("1".equals(bo.getExamineResult())){
            throw new ServiceException("不能修改审核通过的数据");
        }
        int index = 0;
        bo.setExamineResult("0");
        bo.setOpinion("");
        bo.setUpdateTime(DateUtils.getNowDate());
        AskLeave update = MapstructUtils.convert(bo, AskLeave.class);
        validEntityBeforeSave(update);
        index = baseMapper.updateById(update);
        //删除原来的请假课程信息
        askLeaveCourseMapper.delete(new LambdaQueryWrapper<AskLeaveCourse>()
          .eq(AskLeaveCourse::getLeaveId,bo.getId()));
        //请假课程信息
        List<AskLeaveCourseBo> askLeaveCourseBoList = bo.getAskLeaveCourseBoList();
        for (AskLeaveCourseBo askLeaveCourseBo : askLeaveCourseBoList) {
            askLeaveCourseBo.setLeaveId(bo.getId());
            askLeaveCourseBo.setCreateTime(DateUtils.getNowDate());
            askLeaveCourseBo.setUpdateTime(DateUtils.getNowDate());
            AskLeaveCourse askLeaveCourse = MapstructUtils.convert(askLeaveCourseBo, AskLeaveCourse.class);
            askLeaveCourseMapper.insert(askLeaveCourse);
        }
        //删除附件
        askLeaveFjMapper.delete(new LambdaQueryWrapper<AskLeaveFj>()
            .eq(AskLeaveFj::getLeaveId,bo.getId()));
        //附件信息
        List<AskLeaveFjBo> askLeaveFjBoList = bo.getAskLeaveFjBoList();
        if(askLeaveFjBoList!=null && askLeaveFjBoList.size()>0){
            for (AskLeaveFjBo askLeaveFjBo : askLeaveFjBoList) {
                askLeaveFjBo.setLeaveId(bo.getId());
                askLeaveFjBo.setCreateTime(DateUtils.getNowDate());
                askLeaveFjBo.setUpdateTime(DateUtils.getNowDate());
                AskLeaveFj askLeaveFj = MapstructUtils.convert(askLeaveFjBo, AskLeaveFj.class);
                askLeaveFjMapper.insert(askLeaveFj);
            }
        }
        return  index> 0;
    }

    /**
     * 保存前的数据校验
     */
    private void validEntityBeforeSave(AskLeave entity){
        //TODO 做一些数据校验,如唯一约束
    }

    /**
     * 批量删除请假
     */
    @Override
    public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
        if(isValid){
            //TODO 做一些业务上的校验,判断是否需要校验
        }
        return baseMapper.deleteBatchIds(ids) > 0;
    }

    @Override
    public int deleteWithValidById(Long id, Boolean isValid) {
        if(isValid){
            //TODO 做一些业务上的校验,判断是否需要校验
        }
        //查询信息
        AskLeaveVo askLeaveFjVo = baseMapper.selectVoById(id);
        //删除请假课程信息
        askLeaveCourseMapper.delete(new LambdaQueryWrapper<AskLeaveCourse>()
            .eq(AskLeaveCourse::getLeaveId,askLeaveFjVo.getId()));
        //删除附件
        askLeaveFjMapper.delete(new LambdaQueryWrapper<AskLeaveFj>()
            .eq(AskLeaveFj::getLeaveId,askLeaveFjVo.getId()));

        return baseMapper.deleteById(id);
    }

    @Override
    public int sh(AskLeaveBo bo) {
        AskLeave update = MapstructUtils.convert(bo, AskLeave.class);
        validEntityBeforeSave(update);
        return baseMapper.updateById(update);
    }




}
