package com.qmth.distributed.print.business.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.google.common.collect.Lists;
import com.qmth.distributed.print.business.bean.dto.excel.TeachStudentImportDto;
import com.qmth.distributed.print.business.bean.result.TeachStudentResult;
import com.qmth.distributed.print.business.entity.TeachClazz;
import com.qmth.distributed.print.business.entity.TeachStudent;
import com.qmth.distributed.print.business.mapper.TeachStudentMapper;
import com.qmth.distributed.print.business.service.TeachClazzService;
import com.qmth.distributed.print.business.service.TeachStudentService;
import com.qmth.teachcloud.common.contant.SystemConstant;
import com.qmth.teachcloud.common.entity.BasicStudent;
import com.qmth.teachcloud.common.entity.SysUser;
import com.qmth.teachcloud.common.enums.ExceptionResultEnum;
import com.qmth.teachcloud.common.service.BasicStudentService;
import com.qmth.teachcloud.common.util.ExcelUtil;
import com.qmth.teachcloud.common.util.ServletUtil;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import java.io.IOException;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @Description: 教学学生服务实现类
 * @Author: CaoZixuan
 * @Date: 2022-02-09
 */
@Service
public class TeachStudentServiceImpl extends ServiceImpl<TeachStudentMapper, TeachStudent> implements TeachStudentService {
    @Resource
    private BasicStudentService basicStudentService;
    @Resource
    private TeachClazzService teachClazzService;

    @Override
    public IPage<TeachStudentResult> teachStudentPage(Long teachClazzId, String studentInfo, int pageNumber, int pageSize) {
        studentInfo = SystemConstant.translateSpecificSign(studentInfo);
        Long schoolId = SystemConstant.convertIdToLong(ServletUtil.getRequestHeaderSchoolId().toString());
        return this.baseMapper.findTeachStudentPage(new Page<>(pageNumber, pageSize), teachClazzId, studentInfo, schoolId);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public Boolean createTeachStudent(String studentName, String studentCode, Long teachClazzId, SysUser requestUser) {
        if (SystemConstant.isOneNull(studentName, studentCode, teachClazzId)) {
            throw ExceptionResultEnum.ERROR.exception("参数不完整");
        }
        Long schoolId = SystemConstant.convertIdToLong(ServletUtil.getRequestHeaderSchoolId().toString());
        BasicStudent basicStudent = basicStudentService.getOne(new QueryWrapper<BasicStudent>()
                .lambda()
                .eq(BasicStudent::getSchoolId, schoolId)
                .eq(BasicStudent::getStudentCode, studentCode)
                .eq(BasicStudent::getStudentName, studentName));
        if (Objects.isNull(basicStudent)) {
            throw ExceptionResultEnum.ERROR.exception("学生姓名为【" + studentName + "】学号为【" + studentCode + "】的学生在学生字典中不存在，请先创建该学生字典");
        }
        if (this.checkTeachStudentRepeat(basicStudent.getId(), teachClazzId, schoolId)) {
            throw ExceptionResultEnum.ERROR.exception("学生姓名为【" + studentName + "】学号为【" + studentCode + "】的学生在该班级已存在");
        }
        List<BasicStudent> basicStudentList = new ArrayList<>();
        basicStudentList.add(basicStudent);
        return this.createTeachStudentBatch(basicStudentList, teachClazzId, schoolId, requestUser);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void createTeachStudentBatch(Set<Long> basicStudentIdSet, Long teachClazzId, Long schoolId, SysUser requestUser) {
        List<BasicStudent> basicStudentList = basicStudentService.listByIds(basicStudentIdSet);
        if (basicStudentList.size() > 0){
            this.createTeachStudentBatch(basicStudentList, teachClazzId, schoolId, requestUser);
        }
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public String importTeachStudent(MultipartFile file, Long teachClazzId, Long schoolId, SysUser requestUser) throws IOException, NoSuchFieldException {
        if (SystemConstant.isOneNull(file, teachClazzId, schoolId)) {
            throw ExceptionResultEnum.ERROR.exception("参数缺失");
        }

        List<LinkedMultiValueMap<Integer, Object>> finalList = ExcelUtil.excelReader(file.getInputStream(), Lists.newArrayList(TeachStudentImportDto.class), (finalExcelList, finalColumnNameList, finalExcelErrorList) -> {
            if (finalExcelErrorList.size() > 0) {
                throw ExceptionResultEnum.ERROR.exception(JSONObject.toJSONString(finalExcelErrorList));
            }
            return finalExcelList;
        });

        List<BasicStudent> basicStudentDatasource = basicStudentService.list(new QueryWrapper<BasicStudent>().lambda().eq(BasicStudent::getSchoolId, schoolId));
        Set<String> studentCodeSet = new HashSet<>();

        if (Objects.nonNull(finalList) && finalList.size() > 0) {
            for (int i = 0; i < finalList.size(); i++) {
                LinkedMultiValueMap<Integer, Object> map = finalList.get(i);
                List<Object> teachStudentImportDtoList = map.get(i);
                for (int y = 0; y < Objects.requireNonNull(teachStudentImportDtoList).size(); y++) {
                    if (teachStudentImportDtoList.get(y) instanceof TeachStudentImportDto) {
                        TeachStudentImportDto teachStudentImportDto = (TeachStudentImportDto) teachStudentImportDtoList.get(y);
                        String studentCode = teachStudentImportDto.getStudentCode();
                        studentCodeSet.add(studentCode);
                    }
                }
            }
        }

        // 要导入操作的基础学生数据集合
        List<BasicStudent> basicStudentList = basicStudentDatasource.stream()
                .filter(e -> studentCodeSet.contains(e.getStudentCode()))
                .collect(Collectors.toList());

        // 学号不存在
        String basicStudentNotFoundStr = studentCodeSet.stream()
                .filter(e -> !basicStudentList.stream().map(BasicStudent::getStudentCode).collect(Collectors.toList()).contains(e))
                .collect(Collectors.joining(","));

        this.createTeachStudentBatch(basicStudentList, teachClazzId, schoolId, requestUser);
        String success = "【" + basicStudentList.size() + "】个学生导入成功";
        if (SystemConstant.strNotNull(basicStudentNotFoundStr)){
            success = success + "，且学号为【" + basicStudentNotFoundStr + "】的学生在字典中不存在没有导入";
        }
        return success;
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public Boolean deleteTeachStudentBatch(List<Long> idList) {
        // TODO: 2022/2/10 不确定删除逻辑目前直接做删除操作 （直接删除教学学生）
        return this.removeByIds(idList);
    }

    /**
     * 批量创建教学学生
     *
     * @param basicStudentList 要创建教学学生的基础学生集合
     * @param teachClazzId     教学班级id
     * @param schoolId         学校id
     * @param requestUser      请求用户
     * @return 创建结果
     */
    private Boolean createTeachStudentBatch(List<BasicStudent> basicStudentList, Long teachClazzId, Long schoolId, SysUser requestUser) {
        TeachClazz teachClazz = teachClazzService.getById(teachClazzId);
        if (Objects.isNull(teachClazz)) {
            throw ExceptionResultEnum.ERROR.exception("教学班级不存在");
        }
        if (!Objects.equals(teachClazz.getUserId(), requestUser.getId())) {
            throw ExceptionResultEnum.ERROR.exception("用户信息异常");
        }

        List<TeachStudent> teachStudentList = new ArrayList<>();
        if (basicStudentList != null && basicStudentList.size() > 0) {
            for (BasicStudent basicStudent : basicStudentList) {
//                if (!SystemConstant.longNotNull(basicStudent.getCampusId())){
//                    throw ExceptionResultEnum.ERROR.exception("学号为【" + basicStudent.getStudentCode() + "】，名称为【" + basicStudent.getStudentName() + "】的学生缺失'校区信息',请联系管理员创建");
//                }
                Long basicStudentId = basicStudent.getId();
                // 批量新增重复的课程跳过
                if (this.checkTeachStudentRepeat(basicStudentId, teachClazzId, schoolId)) {
                    continue;
                }

                TeachStudent teachStudent = new TeachStudent();
                teachStudent.setSchoolId(basicStudent.getSchoolId());
                teachStudent.setStudentId(basicStudent.getId());
                teachStudent.setTeachClazzId(teachClazzId);
                teachStudent.setTeachCourseId(teachClazz.getTeachCourseId());
                teachStudent.setUserId(teachClazz.getUserId());
                teachStudent.insertInfo(requestUser.getId());
                teachStudentList.add(teachStudent);
            }
        }
        return this.saveBatch(teachStudentList);
    }

    /**
     * 检验教学学生已存在
     *
     * @param basicStudentId 基础学生id
     * @param teachClazzId   教学班级id
     * @param schoolId       学校id
     * @return true-已存在不能新增、false-不存在可以新增
     */
    private Boolean checkTeachStudentRepeat(Long basicStudentId, Long teachClazzId, Long schoolId) {
        TeachStudent teachStudent = this.getOne(new QueryWrapper<TeachStudent>()
                .lambda()
                .eq(TeachStudent::getStudentId, basicStudentId)
                .eq(TeachStudent::getTeachClazzId, teachClazzId)
                .eq(TeachStudent::getSchoolId, schoolId));
        return Objects.nonNull(teachStudent);
    }
}
