package org.dromara.system.service.impl;

import cn.dev33.satoken.secure.BCrypt;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.util.RandomUtil;
import lombok.SneakyThrows;
import org.dromara.common.core.constant.TenantConstants;
import org.dromara.common.core.domain.model.LoginUser;
import org.dromara.common.core.exception.ServiceException;
import org.dromara.common.core.utils.ClassUtils;
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.common.satoken.utils.LoginHelper;
import org.dromara.system.domain.*;
import org.dromara.system.domain.bo.*;
import org.dromara.system.domain.vo.*;
import org.dromara.system.mapper.*;
import org.dromara.system.service.*;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;

/**
 * 智慧校园_审核意见Service业务层处理
 *
 * @author boman
 * @date 2023-08-21
 */
@RequiredArgsConstructor
@Service
public class ZhxyShyjServiceImpl implements IZhxyShyjService {

    private final ZhxyShyjMapper baseMapper;

    private final IRegisterSchoolService registerSchoolService;
    private final RegisterSchoolMapper registerSchoolMapper;

    private final IRegisterSchoolFileService registerSchoolFileService;

    private final RegisterSchoolFileMapper registerSchoolFileMapper;

    private final RegisterTeacherMapper registerTeacherMapper;
    private final RegisterParentsMapper registerParentsMapper;

    private final IRegisterTeacherClassService registerTeacherClassService;
    private final RegisterTeacherClassMapper registerTeacherClassMapper;

    private final FormalTeacherClassMapper formalTeacherClassMapper;

    private final IRegisterParentsStudentService registerParentsStudentService;
    private final RegisterParentsStudentMapper registerParentsStudentMapper;

    private final FormalParentsStudentMapper formalParentsStudentMapper;
    private final IFormalParentsStudentService formalParentsStudentService;

    private final SysTenantMapper sysTenantMapper;

    private final SysDeptMapper sysDeptMapper;

    private final SysUserMapper userMapper;
    private final SysUserServiceImpl sysUserServiceImpl;
    private final SysDictTypeMapper dictTypeMapper;
    private final SysDictDataMapper dictDataMapper;
    private final SysConfigMapper configMapper;
    private final SysRoleMapper sysRoleMapper;
    private final ISysRoleService sysRoleService;
    private final SysMenuMapper sysMenuMapper;
    private final SysRoleMenuMapper roleMenuMapper;

    private final SysUserRoleMapper userRoleMapper;

    /**
     * 查询智慧校园_审核意见
     */
    @Override
    public ZhxyShyjVo queryById(Long id){
        return baseMapper.selectVoById(id);
    }

    /**
     * 查询智慧校园_审核意见列表
     */
    @Override
    public TableDataInfo<ZhxyShyjVo> queryPageList(ZhxyShyjBo bo, PageQuery pageQuery) {
        LambdaQueryWrapper<ZhxyShyj> lqw = buildQueryWrapper(bo);
        Page<ZhxyShyjVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
        return TableDataInfo.build(result);
    }

    /**
     * 查询智慧校园_审核意见列表
     */
    @Override
    public List<ZhxyShyjVo> queryList(ZhxyShyjBo bo) {
        LambdaQueryWrapper<ZhxyShyj> lqw = buildQueryWrapper(bo);
        return baseMapper.selectVoList(lqw);
    }

    private LambdaQueryWrapper<ZhxyShyj> buildQueryWrapper(ZhxyShyjBo bo) {
        Map<String, Object> params = bo.getParams();
        LambdaQueryWrapper<ZhxyShyj> lqw = Wrappers.lambdaQuery();
        lqw.eq(bo.getDataId() != null, ZhxyShyj::getDataId, bo.getDataId());
        lqw.eq(StringUtils.isNotBlank(bo.getType()), ZhxyShyj::getType, bo.getType());
        lqw.eq(bo.getAuditId() != null, ZhxyShyj::getAuditId, bo.getAuditId());
        lqw.eq(StringUtils.isNotBlank(bo.getAuditUser()), ZhxyShyj::getAuditUser, bo.getAuditUser());
        lqw.eq(StringUtils.isNotBlank(bo.getShjg()), ZhxyShyj::getShjg, bo.getShjg());
        lqw.eq(StringUtils.isNotBlank(bo.getShyj()), ZhxyShyj::getShyj, bo.getShyj());
        lqw.eq(bo.getShsj() != null, ZhxyShyj::getShsj, bo.getShsj());
        return lqw;
    }

    /**
     * 新增智慧校园_审核意见
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean insertByBo(ZhxyShyjBo bo) {
        LoginUser loginUser = LoginHelper.getLoginUser();
        bo.setAuditId(loginUser.getUserId());
        bo.setAuditUser(loginUser.getNickname());
        bo.setShsj(DateUtils.getNowDate());
        bo.setCreateTime(DateUtils.getNowDate());
        bo.setCreateTime(DateUtils.getNowDate());
        //int index = zhxyShyjMapper.insertZhxyShyj(zhxyShyj);
        //审核类型（1：学校注册，2：老师注册，3：家长注册，4：调课）
        //审核结果（是否通过  1：待审核，2：通过 3:不通过)
        if("1".equals(bo.getType())){
            //学校注册
            if("2".equals(bo.getShjg())){
                //通过  修改注册表审核结果，生成账号，部门表生成学校， 新增用户与角色管理
                //查询数据信息
                RegisterSchoolVo registerSchool = registerSchoolService.queryById(bo.getDataId());
                //修改注册表审核结果
                registerSchool.setAuditId(loginUser.getUserId());
                registerSchool.setAuditUser(loginUser.getNickname());
                registerSchool.setOpinion(bo.getShyj());
                registerSchool.setIsPass(bo.getShjg());
                registerSchool.setUpdateTime(DateUtils.getNowDate());

                RegisterSchool schoolu = MapstructUtils.convert(registerSchool, RegisterSchool.class);
                registerSchoolMapper.updateById(schoolu);
                //生成租户信息
                SysTenantBo tenantBo = new SysTenantBo();
                tenantBo.setCompanyName(registerSchool.getSchoolName());
                tenantBo.setContactUserName(registerSchool.getUserName());
                tenantBo.setContactPhone(registerSchool.getUserPhone());
                tenantBo.setUsername(registerSchool.getUserPhone());
                //Todo 租户套餐id
                tenantBo.setPackageId(1693453896833552386L);
                SysTenant sysTenant = MapstructUtils.convert(tenantBo, SysTenant.class);
                // 获取所有租户编号
                List<String> tenantIds = sysTenantMapper.selectObjs(
                    new LambdaQueryWrapper<SysTenant>().select(SysTenant::getTenantId), Convert::toStr);
                String tenantId = generateTenantId(tenantIds);
                sysTenant.setTenantId(tenantId);
                boolean flag = sysTenantMapper.insert(sysTenant) > 0;
                if (!flag) {
                    throw new ServiceException("创建租户失败");
                }
                tenantBo.setId(sysTenant.getId());

                copyDict(tenantId);
                List<SysRole> roleList = copyRole(tenantId);
                //部门表生成学校
                SysDept dept = new SysDept();
                dept.setParentId(0L);
                dept.setAncestors("0");
                dept.setDeptName(registerSchool.getSchoolName());
                //查询最新的ParentId为100的数据
                SysDeptVo sysDept = sysDeptMapper.selectDeptByParentId(0L);
                dept.setOrderNum(sysDept.getOrderNum()+1);
                dept.setPhone(registerSchool.getUserPhone());
                dept.setCreateTime(DateUtils.getNowDate());
                dept.setTenantId(tenantId);
                sysDeptMapper.insert(dept);
                //判断是否存在账号
                SysUserVo use = userMapper.selectUserByUserName(registerSchool.getUserPhone());
                if(use==null){
                    use = new SysUserVo();
                    //生成账号
                    use.setOpenId(registerSchool.getOpenId());
                    use.setDeptId(dept.getDeptId());
                    use.setUserName(registerSchool.getUserPhone());
                    use.setNickName(registerSchool.getSchoolName());
                    use.setPhonenumber(registerSchool.getUserPhone());
                    use.setPassword(BCrypt.hashpw("1qaz!QAZ"));
                    use.setCreateTime(DateUtils.getNowDate());
                    use.setTenantId(sysTenant.getTenantId());
                    SysUser sysUser = MapstructUtils.convert(use, SysUser.class);
                    userMapper.insert(sysUser);
                    use.setUserId(sysUser.getUserId());
                }else{
                    use.setDeptId(dept.getDeptId());
                    use.setTenantId(sysTenant.getTenantId());
                    SysUser sysUser = MapstructUtils.convert(use, SysUser.class);
                    userMapper.insert(sysUser);
                }
                //新增用户与角色管理
                //查询当前租户下的学校角色
                Long roleId = 0L;
                for (SysRole sysRole : roleList) {
                    if("school".equals(sysRole.getRoleKey())){
                        roleId = sysRole.getRoleId();
                        break;
                    }
                }
                Long[] roleIds = {roleId};
                sysUserServiceImpl.insertUserRoleNoTenantId(use.getUserId(), roleIds,false);
            }else{
                //不通过  修改注册表审核结果
                //修改注册表审核结果
                RegisterSchool registerSchool = new RegisterSchool();
                registerSchool.setId(bo.getDataId());
                registerSchool.setAuditId(loginUser.getUserId());
                registerSchool.setAuditUser(loginUser.getNickname());
                registerSchool.setOpinion(bo.getShyj());
                registerSchool.setIsPass(bo.getShjg());
                registerSchool.setUpdateTime(DateUtils.getNowDate());
                registerSchoolMapper.updateById(registerSchool);
            }
        }else if("2".equals(bo.getType())){
            //老师注册
            if("2".equals(bo.getShjg())){
                //通过  修改注册表审核结果，生成账号， 新增用户与角色管理，老师-班级（学科）数据
                //查询数据信息
                RegisterTeacherVo registerTeacher = registerTeacherMapper.selectVoById(bo.getDataId());
                RegisterTeacherClassBo registerTeacherClass = new RegisterTeacherClassBo();
                registerTeacherClass.setTeacherId(registerTeacher.getId());
                List<RegisterTeacherClassVo> registerTeacherClassList = registerTeacherClassService.queryList(registerTeacherClass);
                //修改注册表审核结果
                registerTeacher.setAuditId(loginUser.getUserId());
                registerTeacher.setAuditUser(loginUser.getNickname());
                registerTeacher.setOpinion(bo.getShyj());
                registerTeacher.setIsPass(bo.getShjg());
                registerTeacher.setUpdateTime(DateUtils.getNowDate());
                RegisterTeacher teacher = MapstructUtils.convert(registerTeacher, RegisterTeacher.class);
                registerTeacherMapper.updateById(teacher);
                //生成账号
                //判断是否存在账号
                SysUserVo use = userMapper.selectUserByUserName(registerTeacher.getUserPhone());
                //查询dept数据
                SysDeptVo sysDept = sysDeptMapper.selectDeptByIdNoTenantId(registerTeacher.getSchoolId());
                if(use==null){

                    use = new SysUserVo();
                    use.setOpenId(registerTeacher.getOpenId());
                    use.setDeptId(registerTeacher.getSchoolId());
                    use.setUserName(registerTeacher.getUserPhone());
                    use.setNickName(registerTeacher.getUserName());
                    use.setPhonenumber(registerTeacher.getUserPhone());
                    use.setPassword(BCrypt.hashpw("1qaz!QAZ"));
                    use.setCreateTime(DateUtils.getNowDate());
                    use.setTenantId(registerTeacher.getTenantId());
                    SysUser sysUser = MapstructUtils.convert(use, SysUser.class);
                    userMapper.insert(sysUser);
                    use.setUserId(sysUser.getUserId());
                }else{
                    use.setDeptId(registerTeacher.getSchoolId());
                    use.setTenantId(sysDept.getTenantId());
                    SysUser sysUser = MapstructUtils.convert(use, SysUser.class);
                    userMapper.updateById(sysUser);
                }

                //新增用户与角色管理
                Long roleId = sysRoleMapper.selectRoleIdBytenantId(sysDept.getTenantId(),"teacher");
                Long[] roleIds = {roleId};
                sysUserServiceImpl.insertUserRoleNoTenantId(use.getUserId(), roleIds,false);
                //老师-班级（学科）数据
                for (RegisterTeacherClassVo teacherClass : registerTeacherClassList) {
                    FormalTeacherClass formalTeacherClass = new FormalTeacherClass();
                    formalTeacherClass.setTenantId(registerTeacher.getTenantId());
                    formalTeacherClass.setTeacherId(use.getUserId());
                    formalTeacherClass.setTeacherName(use.getNickName());
                    formalTeacherClass.setSchoolId(registerTeacher.getSchoolId());
                    formalTeacherClass.setSchoolName(registerTeacher.getSchoolName());
                    formalTeacherClass.setClassId(teacherClass.getClassId());
                    formalTeacherClass.setClassName(teacherClass.getClassName());
                    formalTeacherClass.setPeriod(teacherClass.getPeriod());
                    formalTeacherClass.setDiscipline(teacherClass.getDiscipline());
                    formalTeacherClass.setCreateTime(DateUtils.getNowDate());
                    formalTeacherClassMapper.insert(formalTeacherClass);
                }

            }else{
                //不通过  修改注册表审核结果
                //修改注册表审核结果
                RegisterTeacher registerTeacher = new RegisterTeacher();
                registerTeacher.setId(bo.getDataId());
                registerTeacher.setAuditId(loginUser.getUserId());
                registerTeacher.setAuditUser(loginUser.getNickname());
                registerTeacher.setOpinion(bo.getShyj());
                registerTeacher.setIsPass(bo.getShjg());
                registerTeacher.setUpdateTime(DateUtils.getNowDate());
                registerTeacherMapper.updateById(registerTeacher);
            }
        }else if("3".equals(bo.getType())) {
            //审核类型（1：学校注册，2：老师注册，3：家长注册，4：调课）
            //家长注册
            //查询数据信息
            RegisterParentsStudentVo registerParentsStudent = registerParentsStudentMapper.selectVoById(bo.getDataId());
            RegisterParentsVo registerParents = registerParentsMapper.selectMapperById(registerParentsStudent.getParentsId());
            if ("2".equals(bo.getShjg())) {

                //通过  修改注册表审核结果，生成账号， 新增用户与角色管理，家长-学生(审核通过之后数据)
                //查询是否存在账号
                SysUserVo sysUser = userMapper.selectUserByUserName(registerParents.getUserPhone());

                //修改注册表审核结果
                registerParentsStudent.setAuditId(loginUser.getUserId());
                registerParentsStudent.setAuditUser(loginUser.getNickname());
                registerParentsStudent.setOpinion(bo.getShyj());
                registerParentsStudent.setIsPass(bo.getShjg());
                registerParentsStudent.setUpdateTime(DateUtils.getNowDate());

                RegisterParentsStudent student = MapstructUtils.convert(registerParentsStudent, RegisterParentsStudent.class);
                registerParentsStudentMapper.updateById(student);

                if (sysUser == null) {
                    //账号不存在
                    registerParents.setIsPass(bo.getShjg());
                    RegisterParents parents = MapstructUtils.convert(registerParents, RegisterParents.class);
                    registerParentsMapper.updateById(parents);
                    //生成账号
                    sysUser = new SysUserVo();
                    sysUser.setOpenId(registerParents.getOpenId());
                    //use.setDeptId(dept.getDeptId());
                    sysUser.setUserName(registerParents.getUserPhone());
                    sysUser.setNickName(registerParents.getUserName());
                    sysUser.setPhonenumber(registerParents.getUserPhone());
                    sysUser.setPassword(BCrypt.hashpw("1qaz!QAZ"));
                    sysUser.setCreateTime(DateUtils.getNowDate());
                    SysUser use = MapstructUtils.convert(sysUser, SysUser.class);
                    userMapper.insert(use);
                    sysUser.setUserId(use.getUserId());
                    //新增用户与角色管理
                    Long[] roleIds = {5L};
                    sysUserServiceImpl.insertUserRoleNoTenantId(sysUser.getUserId(), roleIds,false);
                } else {
                    //账号存在
                    SysUserRole userRole = userRoleMapper.selectUserRole(sysUser.getUserId(),5);
                    if(userRole==null){
                        //新增用户与角色管理
                        Long[] roleIds = {5L};
                        sysUserServiceImpl.insertUserRoleNoTenantId(sysUser.getUserId(), roleIds,false);
                    }
                }

                //新增家长-学生(审核通过之后数据)
                FormalParentsStudent formalParentsStudent = new FormalParentsStudent();
                formalParentsStudent.setParentsId(sysUser.getUserId());
                formalParentsStudent.setSchoolId(registerParentsStudent.getSchoolId());
                formalParentsStudent.setSchoolName(registerParentsStudent.getSchoolName());
                formalParentsStudent.setTenantId(registerParentsStudent.getTenantId());
                formalParentsStudent.setClassId(registerParentsStudent.getClassId());
                formalParentsStudent.setClassName(registerParentsStudent.getClassName());
                formalParentsStudent.setPeriod(registerParentsStudent.getPeriod());
                formalParentsStudent.setStudentName(registerParentsStudent.getStudentName());
                formalParentsStudent.setStudentNumber(registerParentsStudent.getStudentNumber());
                formalParentsStudent.setCreateTime(DateUtils.getNowDate());
                formalParentsStudent.setCreateBy(loginUser.getUserId());
                formalParentsStudentMapper.insertFormalParentsStudent(formalParentsStudent);

            } else {
                //不通过  修改注册表审核结果
                //修改注册表审核结果
                RegisterParentsStudent registerParentsStudentNo = new RegisterParentsStudent();
                registerParentsStudentNo.setId(bo.getDataId());
                registerParentsStudentNo.setAuditId(loginUser.getUserId());
                registerParentsStudentNo.setAuditUser(loginUser.getNickname());
                registerParentsStudentNo.setOpinion(bo.getShyj());
                registerParentsStudentNo.setIsPass(bo.getShjg());
                registerParentsStudentNo.setUpdateTime(DateUtils.getNowDate());
                registerParentsStudentMapper.updateById(registerParentsStudentNo);
                //判断是否所有的都不通过（查询是否存在待审核和审核通过的数据）
                RegisterParentsStudentBo parentsStudent = new RegisterParentsStudentBo();
                parentsStudent.setParentsId(registerParents.getId());
                List<RegisterParentsStudentVo> registerParentsStudentList = registerParentsStudentService.queryList(parentsStudent);
                Boolean bl = true;
                for (RegisterParentsStudentVo student : registerParentsStudentList) {
                    if (!"3".equals(student.getIsPass())) {
                        bl = false;
                        break;
                    }
                }
                //全部都不通过才改家长表状态
                if (bl) {
                    registerParents.setIsPass(bo.getShjg());
                    RegisterParents parents = MapstructUtils.convert(registerParents, RegisterParents.class);
                    registerParentsMapper.updateById(parents);
                }

            }
        }

        ZhxyShyj add = MapstructUtils.convert(bo, ZhxyShyj.class);
        validEntityBeforeSave(add);
        boolean flag = baseMapper.insert(add) > 0;
        if (flag) {
            bo.setId(add.getId());
        }
        return flag;
    }

    @SneakyThrows
    private List<SysRole> copyRole(String tenantId) {
        String defaultTenantId = TenantConstants.DEFAULT_TENANT_ID;
        List<SysRole> roleList = sysRoleMapper.selectList(
            new LambdaQueryWrapper<SysRole>().eq(SysRole::getTenantId, defaultTenantId));
        for (SysRole sysRole : roleList) {
            Set<Long> menuIdList = sysMenuMapper.getMenuIdListByRoleId(sysRole.getRoleId());
            sysRole.setRoleId(null);
            sysRole.setTenantId(tenantId);
            SysRoleBo role = new SysRoleBo();
            ClassUtils.copyProperties(sysRole, role);
            Long[] menuIds = menuIdList.toArray(new Long[0]);
            role.setMenuIds(menuIds);
            sysRoleService.insertRole(role);
            sysRole.setRoleId(role.getRoleId());
        }

        return roleList;
    }

    /***
     *复制公用字典值
     * @param tenantId
     */
    private void copyDict(String tenantId){

        String defaultTenantId = TenantConstants.DEFAULT_TENANT_ID;
        List<SysDictType> dictTypeList = dictTypeMapper.selectList(
            new LambdaQueryWrapper<SysDictType>().eq(SysDictType::getTenantId, defaultTenantId));
        List<SysDictData> dictDataList = dictDataMapper.selectList(
            new LambdaQueryWrapper<SysDictData>().eq(SysDictData::getTenantId, defaultTenantId));
        for (SysDictType dictType : dictTypeList) {
            dictType.setDictId(null);
            dictType.setTenantId(tenantId);
        }
        for (SysDictData dictData : dictDataList) {
            dictData.setDictCode(null);
            dictData.setTenantId(tenantId);
        }
        dictTypeMapper.insertBatch(dictTypeList);
        dictDataMapper.insertBatch(dictDataList);

        List<SysConfig> sysConfigList = configMapper.selectList(
            new LambdaQueryWrapper<SysConfig>().eq(SysConfig::getTenantId, defaultTenantId));
        for (SysConfig config : sysConfigList) {
            config.setConfigId(null);
            config.setTenantId(tenantId);
        }
        configMapper.insertBatch(sysConfigList);
    }

    /**
     * 修改智慧校园_审核意见
     */
    @Override
    public Boolean updateByBo(ZhxyShyjBo bo) {
        ZhxyShyj update = MapstructUtils.convert(bo, ZhxyShyj.class);
        validEntityBeforeSave(update);
        return baseMapper.updateById(update) > 0;
    }

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

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

    /**
     * 生成租户id
     *
     * @param tenantIds 已有租户id列表
     * @return 租户id
     */
    private String generateTenantId(List<String> tenantIds) {
        // 随机生成6位
        String numbers = RandomUtil.randomNumbers(6);
        // 判断是否存在，如果存在则重新生成
        if (tenantIds.contains(numbers)) {
            generateTenantId(tenantIds);
        }
        return numbers;
    }
}
