package com.xjrsoft.module.courseTable.service.impl;

import cn.dev33.satoken.stp.StpUtil;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.github.yulichang.base.MPJBaseServiceImpl;
import com.xjrsoft.common.exception.MyException;
import com.xjrsoft.module.concat.service.IXjrUserService;
import com.xjrsoft.module.courseTable.dto.UserEnrollDto;
import com.xjrsoft.module.courseTable.dto.AddSecondCourseDto;
import com.xjrsoft.module.courseTable.dto.SecondCourseEnrollPageDto;
import com.xjrsoft.module.courseTable.dto.SecondCoursePageDto;
import com.xjrsoft.module.courseTable.dto.UpdateSecondCourseDto;
import com.xjrsoft.module.courseTable.entity.SecondCourse;
import com.xjrsoft.module.courseTable.entity.SecondCourseEnroll;
import com.xjrsoft.module.courseTable.entity.SecondCourseEnrollRange;
import com.xjrsoft.module.courseTable.entity.SecondCourseTime;
import com.xjrsoft.module.courseTable.mapper.SecondCourseEnrollMapper;
import com.xjrsoft.module.courseTable.mapper.SecondCourseEnrollRangeMapper;
import com.xjrsoft.module.courseTable.mapper.SecondCourseMapper;
import com.xjrsoft.module.courseTable.mapper.SecondCourseTimeMapper;
import com.xjrsoft.module.courseTable.service.ISecondCourseService;
import com.xjrsoft.module.courseTable.vo.SecondCourseEnrollVo;
import com.xjrsoft.module.courseTable.vo.SecondCoursePageVo;
import com.xjrsoft.module.teacher.entity.XjrUser;
import lombok.AllArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Date;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
* @title: 第二课堂
* @Author dzx
* @Date: 2024-07-29
* @Version 1.0
*/
@Service
@AllArgsConstructor
public class SecondCourseServiceImpl extends MPJBaseServiceImpl<SecondCourseMapper, SecondCourse> implements ISecondCourseService {
    private final SecondCourseMapper courseMapper;

    private final SecondCourseTimeMapper courseTimeMapper;
    private final SecondCourseEnrollRangeMapper enrollRangeMapper;
    private final SecondCourseEnrollMapper enrollMapper;
    private final IXjrUserService xjrUserService;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean add(AddSecondCourseDto dto) {
        SecondCourse secondCourse = BeanUtil.toBean(dto, SecondCourse.class);
        secondCourse.setEnrollRange(JSONUtil.toJsonStr(dto.getSecondCourseEnrollRangeList()));
        secondCourse.setCreateDate(new Date());
        courseMapper.insert(secondCourse);
        if(secondCourse.getSecondCourseTimeList() != null){
            for (SecondCourseTime secondCourseTime : secondCourse.getSecondCourseTimeList()) {
                secondCourseTime.setSecondCourseId(secondCourse.getId());
                secondCourseTime.setCreateDate(new Date());
                courseTimeMapper.insert(secondCourseTime);
            }
        }
        if(secondCourse.getSecondCourseEnrollRangeList() != null){
            for (SecondCourseEnrollRange secondCourseEnrollRange : secondCourse.getSecondCourseEnrollRangeList()) {
                secondCourseEnrollRange.setSecondCourseId(secondCourse.getId());
                secondCourseEnrollRange.setCreateDate(new Date());
                enrollRangeMapper.insert(secondCourseEnrollRange);
            }
        }

        return true;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean update(UpdateSecondCourseDto dto) {
        SecondCourse secondCourse = BeanUtil.toBean(dto, SecondCourse.class);
        secondCourse.setEnrollRange(JSONUtil.toJsonStr(dto.getSecondCourseEnrollRangeList()));
        secondCourse.setModifyDate(new Date());
        courseMapper.updateById(secondCourse);
        //********************************* SecondCourseTime  增删改  开始 *******************************************/
        {
            // 查出所有子级的id
            List<SecondCourseTime> secondCourseTimeList = courseTimeMapper.selectList(Wrappers.lambdaQuery(SecondCourseTime.class).eq(SecondCourseTime::getSecondCourseId, secondCourse.getId()).select(SecondCourseTime::getId));
            List<Long> secondCourseTimeIds = secondCourseTimeList.stream().map(SecondCourseTime::getId).collect(Collectors.toList());
            //原有子表单 没有被删除的主键
            List<Long> secondCourseTimeOldIds = secondCourse.getSecondCourseTimeList().stream().map(SecondCourseTime::getId).filter(Objects::nonNull).collect(Collectors.toList());
            //找到需要删除的id
            List<Long> secondCourseTimeRemoveIds = secondCourseTimeIds.stream().filter(item -> !secondCourseTimeOldIds.contains(item)).collect(Collectors.toList());

            for (SecondCourseTime secondCourseTime : secondCourse.getSecondCourseTimeList()) {
                //如果不等于空则修改
                if (secondCourseTime.getId() != null) {
                    secondCourseTime.setModifyDate(new Date());
                    courseTimeMapper.updateById(secondCourseTime);
                }
                //如果等于空 则新增
                else {
                    //已经不存在的id 删除
                    secondCourseTime.setSecondCourseId(secondCourse.getId());
                    secondCourseTime.setCreateDate(new Date());
                    courseTimeMapper.insert(secondCourseTime);
                }
            }
            //已经不存在的id 删除
            if(!secondCourseTimeRemoveIds.isEmpty()){
                courseTimeMapper.deleteBatchIds(secondCourseTimeRemoveIds);
            }
        }
        //********************************* SecondCourseTime  增删改  结束 *******************************************/

        //********************************* SecondCourseEnrollRange  增删改  开始 *******************************************/
        {
            // 查出所有子级的id
            List<SecondCourseEnrollRange> secondCourseEnrollRangeList = enrollRangeMapper.selectList(Wrappers.lambdaQuery(SecondCourseEnrollRange.class).eq(SecondCourseEnrollRange::getSecondCourseId, secondCourse.getId()).select(SecondCourseEnrollRange::getId));
            List<Long> secondCourseEnrollRangeIds = secondCourseEnrollRangeList.stream().map(SecondCourseEnrollRange::getId).collect(Collectors.toList());
            //原有子表单 没有被删除的主键
            List<Long> secondCourseEnrollRangeOldIds = secondCourse.getSecondCourseEnrollRangeList().stream().map(SecondCourseEnrollRange::getId).filter(Objects::nonNull).collect(Collectors.toList());
            //找到需要删除的id
            List<Long> secondCourseEnrollRangeRemoveIds = secondCourseEnrollRangeIds.stream().filter(item -> !secondCourseEnrollRangeOldIds.contains(item)).collect(Collectors.toList());

            for (SecondCourseEnrollRange secondCourseEnrollRange : secondCourse.getSecondCourseEnrollRangeList()) {
                //如果不等于空则修改
                if (secondCourseEnrollRange.getId() != null) {
                    secondCourseEnrollRange.setModifyDate(new Date());
                    enrollRangeMapper.updateById(secondCourseEnrollRange);
                }
                //如果等于空 则新增
                else {
                    //已经不存在的id 删除
                    secondCourseEnrollRange.setSecondCourseId(secondCourse.getId());
                    secondCourseEnrollRange.setCreateDate(new Date());
                    enrollRangeMapper.insert(secondCourseEnrollRange);
                }
            }
            //已经不存在的id 删除
            if(!secondCourseEnrollRangeRemoveIds.isEmpty()){
                enrollRangeMapper.deleteBatchIds(secondCourseEnrollRangeRemoveIds);
            }
        }
        //********************************* SecondCourseEnrollRange  增删改  结束 *******************************************/
        return true;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean delete(List<Long> ids) {
        courseMapper.deleteBatchIds(ids);
        courseTimeMapper.delete(Wrappers.lambdaQuery(SecondCourseTime.class).in(SecondCourseTime::getSecondCourseId, ids));
        enrollRangeMapper.delete(Wrappers.lambdaQuery(SecondCourseEnrollRange.class).in(SecondCourseEnrollRange::getSecondCourseId, ids));
        enrollMapper.delete(Wrappers.lambdaQuery(SecondCourseEnroll.class).in(SecondCourseEnroll::getSecondCourseId, ids));

        return true;
    }

    @Override
    public Page<SecondCoursePageVo> getPage(Page<SecondCoursePageVo> page, SecondCoursePageDto dto) {
        return this.baseMapper.getPage(page, dto);
    }

    @Override
    public Integer getEnrollCount(Long secondCourseId) {
        Long count = enrollMapper.selectCount(
                new QueryWrapper<SecondCourseEnroll>().lambda()
                        .eq(SecondCourseEnroll::getSecondCourseId, secondCourseId)
        );
        return count.intValue();
    }

    @Override
    public Page<SecondCourseEnrollVo> getEnrollPage(Page<SecondCourseEnrollVo> page, SecondCourseEnrollPageDto dto) {
        return this.baseMapper.getEnrollPage(page, dto);
    }

    @Override
    public List<SecondCourseEnrollVo> getEnrollList(SecondCourseEnrollPageDto dto) {
        return this.baseMapper.getEnrollList(dto);
    }

    @Override
    public Boolean enroll(UserEnrollDto dto) {
        List<SecondCourseEnroll> enrollList = enrollMapper.selectList(
                new QueryWrapper<SecondCourseEnroll>().lambda()
                        .eq(SecondCourseEnroll::getUserId, StpUtil.getLoginIdAsLong())
                        .eq(SecondCourseEnroll::getSecondCourseId, dto.getId())
        );
        if(!enrollList.isEmpty()){
            throw  new MyException("已报名，无需重复报名");
        }
        SecondCourseEnroll enroll = new SecondCourseEnroll() {{
            setUserId(StpUtil.getLoginIdAsLong());
            setSecondCourseId(dto.getId());
        }};
        enrollMapper.insert(enroll);

        XjrUser xjrUser = xjrUserService.getById(StpUtil.getLoginIdAsLong());
        if(StrUtil.isNotEmpty(dto.getMobile()) && !dto.getMobile().equals(xjrUser.getMobile())){
            xjrUser.setMobile(dto.getMobile());
            xjrUserService.updateById(xjrUser);
        }
        return true;
    }

    @Override
    public Page<SecondCoursePageVo> getMyPage(Page<SecondCoursePageVo> page, SecondCoursePageDto dto) {
        return this.baseMapper.getMyPage(page, dto);
    }
}
