package com.qmth.teachcloud.report.business.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.google.common.collect.Lists;
import com.qmth.teachcloud.common.bean.params.UserSaveParams;
import com.qmth.teachcloud.common.contant.SystemConstant;
import com.qmth.teachcloud.common.entity.SysOrg;
import com.qmth.teachcloud.common.entity.SysRole;
import com.qmth.teachcloud.common.entity.SysUser;
import com.qmth.teachcloud.common.entity.SysUserRole;
import com.qmth.teachcloud.common.enums.ExceptionResultEnum;
import com.qmth.teachcloud.common.enums.RoleTypeEnum;
import com.qmth.teachcloud.common.service.SysOrgService;
import com.qmth.teachcloud.common.service.SysRoleService;
import com.qmth.teachcloud.common.service.SysUserRoleService;
import com.qmth.teachcloud.common.service.SysUserService;
import com.qmth.teachcloud.common.util.ExcelUtil;
import com.qmth.teachcloud.report.business.bean.dto.excel.TeacherDto;
import com.qmth.teachcloud.report.business.entity.TBTeacher;
import com.qmth.teachcloud.report.business.mapper.TBTeacherMapper;
import com.qmth.teachcloud.report.business.service.TBTeacherService;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.web.multipart.MultipartFile;

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

/**
 * @Description: 基础教师服务实现类
 * @Author: CaoZixuan
 * @Date: 2021-09-21
 */
@Service
public class TBTeacherServiceImpl extends ServiceImpl<TBTeacherMapper, TBTeacher> implements TBTeacherService {
    @Resource
    private SysUserService sysUserService;
    @Resource
    private SysUserRoleService sysUserRoleService;
    @Resource
    private SysOrgService sysOrgService;
    @Resource
    private SysRoleService sysRoleService;

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void deleteSysUserByIdSet(Set<Long> idSet) {
        if (CollectionUtils.isEmpty(idSet)){
            throw ExceptionResultEnum.ERROR.exception("请选择要删除的用户id");
        }
        sysUserRoleService.remove(new QueryWrapper<SysUserRole>().lambda().in(SysUserRole::getUserId,idSet));
        sysUserService.remove(new QueryWrapper<SysUser>().lambda().in(SysUser::getId,idSet));
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public String importBasicTeacherInfo(MultipartFile file, Long schoolId) throws Exception {
        if (Objects.isNull(file)) {
            throw ExceptionResultEnum.ERROR.exception("附件不存在");
        }
        if (Objects.isNull(schoolId) || schoolId == 0) {
            throw ExceptionResultEnum.ERROR.exception("参数缺失");
        }
        List<LinkedMultiValueMap<Integer, Object>> finalList = ExcelUtil.excelReader(file.getInputStream(), Lists.newArrayList(TeacherDto.class), (finalExcelList, finalColumnNameList, finalExcelErrorList) -> {
            if (finalExcelErrorList.size() > 0) {
                throw ExceptionResultEnum.ERROR.exception(JSONObject.toJSONString(finalExcelErrorList));
            }
            return finalExcelList;
        });

        Map<String,String> checkCode = new HashMap<>();
        List<TBTeacher> tbTeacherList = new ArrayList<>();
        if (Objects.nonNull(finalList) && finalList.size() > 0) {
            for (int i = 0; i < finalList.size(); i++) {
                LinkedMultiValueMap<Integer, Object> map = finalList.get(i);
                List<Object> teacherList = map.get(i);
                for (int y = 0; y < Objects.requireNonNull(teacherList).size(); y++) {
                    if (teacherList.get(y) instanceof TeacherDto) {
                        // excel 数据解析
                        TeacherDto teacherDto = (TeacherDto) teacherList.get(y);
                        String teacherName = teacherDto.getTeacherName();
                        String teacherCode = teacherDto.getTeacherCode();
                        if (checkCode.containsKey(teacherCode)){
                            throw ExceptionResultEnum.ERROR.exception("excel中存在重复的教师编号 ： " + teacherCode);
                        }
                        checkCode.put(teacherCode,teacherName);

                        String orgName = teacherDto.getOrgName();
                        SysOrg sysOrg = sysOrgService.getOne(new QueryWrapper<SysOrg>().lambda()
                                .eq(SysOrg::getSchoolId,schoolId)
                                .eq(SysOrg::getName,orgName));
                        if (Objects.isNull(sysOrg)){
                            System.out.println(JSON.toJSONString(teacherDto));
                            throw ExceptionResultEnum.ERROR.exception("机构不存在");
                        }
                        String roleName = teacherDto.getRoleName();
                        RoleTypeEnum roleType = RoleTypeEnum.convertDescToEnum(roleName);
                        if (roleType == null){
                            throw ExceptionResultEnum.ERROR.exception("枚举类型不存在");
                        }

                        TBTeacher tbTeacher = new TBTeacher();
                        tbTeacher.setId(SystemConstant.getDbUuid());
                        tbTeacher.setSchoolId(schoolId);
                        tbTeacher.setOrgId(sysOrg.getId());
                        tbTeacher.setTeacherCode(teacherCode);
                        tbTeacher.setTeacherName(teacherName);
                        tbTeacher.setRoleType(roleType);
                        tbTeacherList.add(tbTeacher);
                    }
                }
            }
        }
        // 删除该学校原有数据
        this.remove(new QueryWrapper<TBTeacher>().lambda().eq(TBTeacher::getSchoolId,schoolId));
        // 添加数据
        this.saveBatch(tbTeacherList);
        return "处理数据 " + tbTeacherList.size() + "条";
    }

    @Override
    public void syncTeacherInfoToSysUser(Long schoolId) {
        // 基础教师表
        List<TBTeacher> teacherList = this.list(new QueryWrapper<TBTeacher>().lambda().eq(TBTeacher::getSchoolId,schoolId));
        List<SysUser> dbUserList = sysUserService.list(new QueryWrapper<SysUser>().lambda().eq(SysUser::getSchoolId,schoolId));
        for (TBTeacher tbTeacher : teacherList) {
            List<SysUser> dbFilter = dbUserList.stream().filter(e -> tbTeacher.getTeacherName().equals(e.getRealName())).collect(Collectors.toList());
            SysRole teacherRole = sysRoleService.list(new QueryWrapper<SysRole>().lambda().eq(SysRole::getType, tbTeacher.getRoleType())).get(0);
            List<Long> roleIds = new ArrayList<>();
            roleIds.add(teacherRole.getId());
            if (dbFilter.size() > 1){
                throw ExceptionResultEnum.ERROR.exception("找到相同名称用户警告");
            }else if (dbFilter.size() == 1){
                // 更新教师账号
                SysUser dbUser = dbFilter.get(0);
                UserSaveParams userSaveParams = new UserSaveParams();
                userSaveParams.setId(dbUser.getId());
                userSaveParams.setSchoolId(tbTeacher.getSchoolId());
                userSaveParams.setLoginName(tbTeacher.getTeacherCode());
                userSaveParams.setRealName(tbTeacher.getTeacherName());
                userSaveParams.setPassword(SystemConstant.DEFAULT_PASSWORD);
                userSaveParams.setOrgId(tbTeacher.getOrgId());
                userSaveParams.setEnable(true);
                userSaveParams.setRoleIds(roleIds.toArray(new Long[0]));
                sysUserService.saveUserNoAuth(userSaveParams);
            }else {
                // 新增教师
                UserSaveParams userSaveParams = new UserSaveParams();
                userSaveParams.setSchoolId(tbTeacher.getSchoolId());
                userSaveParams.setLoginName(tbTeacher.getTeacherCode());
                userSaveParams.setRealName(tbTeacher.getTeacherName());
                userSaveParams.setPassword(SystemConstant.DEFAULT_PASSWORD);
                userSaveParams.setOrgId(tbTeacher.getOrgId());
                userSaveParams.setEnable(true);
                userSaveParams.setRoleIds(roleIds.toArray(new Long[0]));
                sysUserService.saveUserNoAuth(userSaveParams);
            }
        }
    }
}
