package com.cmeeting.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.IdUtil;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.cmeeting.ad.entity.RobotSecurityUser;
import com.cmeeting.ad.entity.SysUserSync;
import com.cmeeting.ad.util.SecurityUtil;
import com.cmeeting.constant.AuthTypeConstant;
import com.cmeeting.constant.MeetingTypeConstant;
import com.cmeeting.constant.PermissionPruposeType;
import com.cmeeting.constant.RecordTemplateConstant;
import com.cmeeting.dto.MeetTypeDto;
import com.cmeeting.dto.RecordTemplateDto;
import com.cmeeting.dto.UserDTO;
import com.cmeeting.exception.RobotBaseException;
import com.cmeeting.mapper.primary.*;
import com.cmeeting.mapper.primary.SysUserSyncMapper;
import com.cmeeting.pojo.*;
import com.cmeeting.service.MeetTemplateEnableService;
import com.cmeeting.service.MeetingRecordTemplateService;
import com.cmeeting.service.ModulePermissionService;
import com.cmeeting.service.SysUserSyncService;
import com.cmeeting.util.MinioUtils;
import com.cmeeting.vo.EditRecordTemplateVo;
import com.cmeeting.vo.RecordTemplateVO;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ObjectUtils;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import java.io.InputStream;
import java.util.*;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.stream.Collectors;

@Service
@Slf4j
public class MeetingRecordTemplateServiceImpl extends ServiceImpl<MeetingRecordTemplateMapper, MeetingRecordTemplate> implements MeetingRecordTemplateService {

    @Autowired
    private MinioUtils minioUtils;
    @Resource
    private RecordTemplatePermissionMapper permissionMapper;
    @Resource
    private SysUserSyncMapper sysUserSysMapper;
    @Autowired
    private MeetTypeMapper meetTypeMapper;
    @Resource
    private MeetTemplateEnableMapper meetTemplateEnableMapper;
    @Resource
    private ModulePermissionService modulePermissionService;
    @Resource
    private SysUserSyncService sysUserSyncService;
    @Value(value = "${permission.tenantId}")
    private String permissionTenantId;
    @Value(value = "${record-template-path-default}")
    private String defaultTemplatePath;
    @Resource
    private MeetTemplateEnableService meetTemplateEnableService;

    @Override
    public List<RecordTemplateDto> getRecordTemplateDtoList(RecordTemplateVO vo) {

        return baseMapper.selectRecordTemplateDtoList(vo.getType(), vo.getName(), vo.getMeetingType(), vo.getCreateUser(), vo.getStartTime(), vo.getEndTime());
    }

    @Override
    public IPage<MeetingRecordTemplate> getPersonalPage(RecordTemplateVO vo) {
        RobotSecurityUser user = SecurityUtil.getUser();
        Integer current = vo.getCurrent();
        Integer size = vo.getSize();
        //查出所有系统模板
        LambdaQueryWrapper<MeetingRecordTemplate> systemQueryWrapper = new LambdaQueryWrapper<>();
        systemQueryWrapper.eq(MeetingRecordTemplate::getIsDel, Boolean.FALSE);
        systemQueryWrapper.eq(MeetingRecordTemplate::getType, RecordTemplateConstant.TEMPLATE_TYPE_SYSTEM);
        systemQueryWrapper.like(vo.getName() != null, MeetingRecordTemplate::getName, vo.getName());
        systemQueryWrapper.like(vo.getMeetingType() != null, MeetingRecordTemplate::getMeetingType, vo.getMeetingType());
        systemQueryWrapper.like(StringUtils.isNotEmpty(vo.getCreateUser()), MeetingRecordTemplate::getCreateUserName, vo.getCreateUser());
        systemQueryWrapper.between(vo.getStartTime() != null && vo.getEndTime() != null, MeetingRecordTemplate::getUpdateTime, vo.getStartTime(), vo.getEndTime());
        systemQueryWrapper.orderByDesc(MeetingRecordTemplate::getId);
        List<MeetingRecordTemplate> systemTemplateList = baseMapper.selectList(systemQueryWrapper);
        //用户可见的系统模板权限
        List<MeetingRecordTemplate> authorizedSystemTemplateList = new ArrayList<>();
        Map<Integer, List<String>> authorizedUserMap = selectAuthorizedUsers().stream().collect(Collectors.toMap(item -> item.getRecordTemplateId(), item -> item.getUserIdList()));
        for (MeetingRecordTemplate systemTemplate : systemTemplateList) {
            if (authorizedUserMap.containsKey(systemTemplate.getId())) {
                List<String> authorizedUserIds = authorizedUserMap.get(systemTemplate.getId());
                if (authorizedUserIds.contains(user.getId()))
                    authorizedSystemTemplateList.add(systemTemplate);
            }
        }

        //查出用户个人的自定义模板
        LambdaQueryWrapper<MeetingRecordTemplate> customQueryWrapper = new LambdaQueryWrapper<>();
        customQueryWrapper.eq(MeetingRecordTemplate::getIsDel, Boolean.FALSE);
        customQueryWrapper.eq(MeetingRecordTemplate::getType, RecordTemplateConstant.TEMPLATE_TYPE_CUSTOM);
        customQueryWrapper.eq(MeetingRecordTemplate::getCreateUser, user.getId());
        customQueryWrapper.like(vo.getName() != null, MeetingRecordTemplate::getName, vo.getName());
        customQueryWrapper.like(vo.getMeetingType() != null, MeetingRecordTemplate::getMeetingType, vo.getMeetingType());
        customQueryWrapper.like(StringUtils.isNotEmpty(vo.getCreateUser()), MeetingRecordTemplate::getCreateUserName, vo.getCreateUser());
        customQueryWrapper.between(vo.getStartTime() != null && vo.getEndTime() != null, MeetingRecordTemplate::getUpdateTime, vo.getStartTime(), vo.getEndTime());
        customQueryWrapper.orderByDesc(MeetingRecordTemplate::getId);
        List<MeetingRecordTemplate> customTemplateList = baseMapper.selectList(customQueryWrapper);

        List<MeetingRecordTemplate> resultList = new ArrayList<>();
        resultList.addAll(authorizedSystemTemplateList);
        resultList.addAll(customTemplateList);
        List<MeetingRecordTemplate> records = getUsersByOffset(resultList, current, size);
        if (!CollectionUtils.isEmpty(records)) {
            List<SysUserSync> simpleUserList = sysUserSysMapper.getSimpleUserList();
            Map<String, String> simpleUserMap = CollectionUtils.isEmpty(simpleUserList)
                    ? new HashMap<>() : simpleUserList.stream().collect(Collectors.toMap(SysUserSync::getUserId, SysUserSync::getName));
            for (MeetingRecordTemplate record : records) {
                String createUser = record.getCreateUser();
                String createUserName = simpleUserMap.containsKey(createUser) ? simpleUserMap.get(createUser) : "1".equals(createUser) ? "集团" : createUser;
                record.setCreateUser(createUserName);
            }
        }
        IPage<MeetingRecordTemplate> resultPage = new Page<>(current, size);
        resultPage.setTotal(resultList.size());
        resultPage.setRecords(records);
        resultPage.setPages((resultList.size() + size - 1) / size);
        return resultPage;
    }

    /**
     * 上传附件模板到minio
     *
     * @param file
     * @param id
     * @return
     */
    @Override
    public String templateUpload(MultipartFile file, Integer id) {
        MeetingRecordTemplate detail = getById(id);
        String separator = "/";
        String point = ".";
        // 获取文件名
        String originalFilename = file.getOriginalFilename();
        // 获取文件后缀
        String originalSuffix = FileUtil.getSuffix(originalFilename);
        // 生成文件名
        String nowDate = DateUtil.format(new Date(), "yyyy-MM-dd");
        String uuid = IdUtil.fastSimpleUUID();
        String originalFilePath = separator + nowDate + separator + uuid + point + originalSuffix;
        // 获取文件流
        try (InputStream is = file.getInputStream()) {
            minioUtils.upload(originalFilePath, is);
        } catch (Exception e) {
            throw new RuntimeException(e.getMessage());
        }
        detail.setTemplate(originalFilePath);
        updateById(detail);
        return originalFilePath;
    }

    /**
     * 获取模板授权的人员
     *
     * @return
     */
    @Override
    public List<UserDTO.TemplateAuthorizedUserDTO> selectAuthorizedUsers() {
        List<UserDTO.TemplateAuthorizedUserDTO> result = new ArrayList<>();
        //查出所有系统模板(暂定)
        List<MeetingRecordTemplate> meetingRecordTemplates = baseMapper.selectList(new LambdaQueryWrapper<MeetingRecordTemplate>().eq(MeetingRecordTemplate::getType, RecordTemplateConstant.TEMPLATE_TYPE_SYSTEM));
        //查出所有系统模板授权信息
        List<RecordTemplatePermission> permissions = permissionMapper.selectList(new LambdaQueryWrapper<RecordTemplatePermission>().eq(RecordTemplatePermission::getTemplateType, RecordTemplateConstant.TEMPLATE_TYPE_SYSTEM));
        //所有授权模板的人员
        for (MeetingRecordTemplate template : meetingRecordTemplates) {
            UserDTO.TemplateAuthorizedUserDTO resultItem = new UserDTO.TemplateAuthorizedUserDTO();
            resultItem.setRecordTemplate(template);
            resultItem.setRecordTemplateId(template.getId().intValue());
            //该系统模板授权部门
            List<RecordTemplatePermission> deptPermissions = permissions.stream().filter(item -> "1".equals(item.getRelType()) && template.getId().equals(item.getTemplateId())).collect(Collectors.toList());
            //该系统模板授权人员
            List<RecordTemplatePermission> userPermissions = permissions.stream().filter(item -> "2".equals(item.getRelType()) && template.getId().equals(item.getTemplateId())).collect(Collectors.toList());

            List<String> authorizedUsers = new ArrayList<>();
            if (!CollectionUtils.isEmpty(userPermissions)) {
                for (RecordTemplatePermission userPermission : userPermissions) {
                    authorizedUsers.add(userPermission.getRelId());
                }
            }
            if (!CollectionUtils.isEmpty(deptPermissions)) {
                List<String> deptPath = new ArrayList<>();
                for (RecordTemplatePermission deptPermission : deptPermissions) {
                    String deptId = deptPermission.getRelId();
                    getDeptPath(deptPath, deptId);
                }
                List<String> usersByDept = sysUserSysMapper.getUsersByDept(deptPath);
                if (!CollectionUtils.isEmpty(usersByDept))
                    authorizedUsers.addAll(usersByDept);
            }
            resultItem.setUserIdList(authorizedUsers);
            result.add(resultItem);
        }
        return result;
    }

    @Override
    public List<MeetingRecordTemplate> getSelectList(RecordTemplateVO vo) {
        RobotSecurityUser user = SecurityUtil.getUser();
        //查出所有系统模板
        LambdaQueryWrapper<MeetingRecordTemplate> systemQueryWrapper = new LambdaQueryWrapper<>();
        systemQueryWrapper.eq(MeetingRecordTemplate::getIsDel, Boolean.FALSE);
        systemQueryWrapper.eq(MeetingRecordTemplate::getType, RecordTemplateConstant.TEMPLATE_TYPE_SYSTEM);
        systemQueryWrapper.like(vo.getName() != null, MeetingRecordTemplate::getName, vo.getName());
        systemQueryWrapper.like(vo.getMeetingType() != null, MeetingRecordTemplate::getMeetingType, vo.getMeetingType());
        systemQueryWrapper.orderByDesc(MeetingRecordTemplate::getId);
        List<MeetingRecordTemplate> systemTemplateList = baseMapper.selectList(systemQueryWrapper);
        if (CollectionUtils.isEmpty(systemTemplateList)) return new ArrayList<>();
        //用户可见的系统模板权限
        List<MeetingRecordTemplate> records = new ArrayList<>();

        //查出所有系统模板授权人员信息
        List<RecordTemplatePermission> userPermissions = permissionMapper.selectList(new LambdaQueryWrapper<RecordTemplatePermission>()
                .eq(RecordTemplatePermission::getTemplateType, RecordTemplateConstant.TEMPLATE_TYPE_SYSTEM)
                .eq(RecordTemplatePermission::getRelId, user.getId())
                .eq(RecordTemplatePermission::getRelType, RecordTemplateConstant.REL_TYPE_USER)
        );
        //当前登录人员被直接授权的模板
        List<Integer> templateIdsAccepted = CollectionUtils.isEmpty(userPermissions)
                ? new ArrayList<>() : userPermissions.stream().map(RecordTemplatePermission::getTemplateId).collect(Collectors.toList());

        //查出所有系统模板授权部门信息
        List<RecordTemplatePermission> deptPermissions = permissionMapper.selectList(new LambdaQueryWrapper<RecordTemplatePermission>()
                .eq(RecordTemplatePermission::getTemplateType, RecordTemplateConstant.TEMPLATE_TYPE_SYSTEM)
                .eq(RecordTemplatePermission::getRelId, user.getId())
                .eq(RecordTemplatePermission::getRelType, RecordTemplateConstant.REL_TYPE_DEPT));
        //查出当前登录人的部门向上路径
        String deptPathByUser = sysUserSyncService.getDeptPathByUserId(user.getId());
        if (StringUtils.isNotEmpty(deptPathByUser) && !CollectionUtils.isEmpty(deptPermissions)) {
            List<Integer> templateIdsDeptAccepted = deptPermissions.stream().filter(item -> deptPathByUser.contains(item.getRelId()))
                    .map(RecordTemplatePermission::getTemplateId).collect(Collectors.toList());
            if (!CollectionUtils.isEmpty(templateIdsDeptAccepted)) templateIdsAccepted.addAll(templateIdsDeptAccepted);
        }
        for (MeetingRecordTemplate template : systemTemplateList) {
            if (templateIdsAccepted.contains(template.getId())) {
                records.add(template);
            }
        }
        return records;
    }

    /**
     * 保存模板
     *
     * @param recordTemplateVo 请求参数
     */
    @Override
    public Long save(EditRecordTemplateVo recordTemplateVo) {
        RobotSecurityUser loginUser = SecurityUtil.getUser();
        String role = loginUser.getRole();
        String userId = String.format("%08d", loginUser.getUserId());

        MeetType meetType = meetTypeMapper.selectById(recordTemplateVo.getMeetingTypeId());
        if (MeetingTypeConstant.PERSONAL_PERMISSION_NO == meetType.getPersonalPermission() && !MeetingTypeConstant.TYPE_SYSTEM.equals(role)) {
            throw new RobotBaseException("当前会议类型下不允许新建纪要模板");
        }

        Integer count = baseMapper.selectCount(new LambdaQueryWrapper<MeetingRecordTemplate>()
                .eq(MeetingRecordTemplate::getName, recordTemplateVo.getName())
                .eq(MeetingRecordTemplate::getType, SecurityUtil.getUser().getRole())
                .eq(role.equals(MeetingTypeConstant.TYPE_CUSTOM), MeetingRecordTemplate::getCreateUser, userId));
        if (count > 0) {
            throw new RobotBaseException("添加失败。当前纪要模板名称已存在。");
        }
        MeetingRecordTemplate template = baseMapper.selectOne(new LambdaQueryWrapper<MeetingRecordTemplate>().eq(MeetingRecordTemplate::getId, recordTemplateVo.getReferTemplateId()));
        Date now = new Date();
        MeetingRecordTemplate recordTemplate = new MeetingRecordTemplate();
        recordTemplate.setName(recordTemplateVo.getName());
        recordTemplate.setType(role);
        recordTemplate.setMeetingType(recordTemplateVo.getMeetingTypeId());
        recordTemplate.setTypeDetail(recordTemplateVo.getTypeDetail());
        recordTemplate.setPrompt(recordTemplateVo.getPrompt());
        recordTemplate.setReferTemplateId(recordTemplateVo.getReferTemplateId());
        recordTemplate.setTemplate(template != null ? template.getTemplate() : defaultTemplatePath);
        recordTemplate.setEnable(true);
        if (MeetingTypeConstant.TYPE_SYSTEM.equals(role) && RecordTemplateConstant.COMMON_MEET_TYPE.equals(meetType.getId())) {
            // 超管在系统通用会议类型下创建模板
            recordTemplate.setEnable(false);
        }
        recordTemplate.setCreateTime(now);
        recordTemplate.setUpdateTime(now);
        recordTemplate.setCreateUser(userId);
        recordTemplate.setUpdateUser(userId);
        recordTemplate.setCreateUserName(loginUser.getUsername());
        recordTemplate.setUpdateUserName(loginUser.getUsername());
        baseMapper.insert(recordTemplate);
        return recordTemplate.getId();
        // 没有保存到启用表中，默认是不启用的。
    }


    /**
     * 更新模板
     *
     * @param recordTemplateVo 模板参数
     */
    @Override
    public void updateById(EditRecordTemplateVo recordTemplateVo) {
        Date now = new Date();
        RobotSecurityUser loginUser = SecurityUtil.getUser();
        String userId = String.format("%08d", loginUser.getUserId());

        MeetingRecordTemplate template = baseMapper.selectById(recordTemplateVo.getId());
        if (MeetingTypeConstant.TYPE_CUSTOM.equals(loginUser.getRole()) && !template.getCreateUser().equals(userId)) {
            // 当前是普通用户，不允许修改非自己创建的模板
            throw new RobotBaseException("当前用户没有权限修改该模板");
        }
        Integer count = baseMapper.selectCount(new LambdaQueryWrapper<MeetingRecordTemplate>().eq(MeetingRecordTemplate::getName, recordTemplateVo.getName()).eq(MeetingRecordTemplate::getCreateUser, userId).ne(MeetingRecordTemplate::getId, recordTemplateVo.getId()));
        if (count > 0) {
            throw new RobotBaseException("编辑失败。当前纪要模板名称已存在。");
        }

        MeetingRecordTemplate recordTemplate = new MeetingRecordTemplate();
        recordTemplate.setId(recordTemplateVo.getId());
        recordTemplate.setName(recordTemplateVo.getName());
        recordTemplate.setTypeDetail(recordTemplateVo.getTypeDetail());
        recordTemplate.setPrompt(recordTemplateVo.getPrompt());
        recordTemplate.setReferTemplateId(recordTemplateVo.getReferTemplateId());
        recordTemplate.setUpdateTime(now);
        recordTemplate.setUpdateUser(loginUser.getId());
        recordTemplate.setUpdateUserName(loginUser.getUsername());
        baseMapper.updateById(recordTemplate);
    }

    /**
     * 启用模板
     *
     * @param id 模板id
     */
    @Transactional
    @Override
    public Boolean enable(Long id) {
        MeetingRecordTemplate recordTemplate = baseMapper.selectById(id);
        if (ObjectUtils.isEmpty(recordTemplate)) {
            throw new RobotBaseException("当前纪要模板不存在");
        }
        Long meetTypeId = recordTemplate.getMeetingType();
        RobotSecurityUser loginUser = SecurityUtil.getUser();
        if (loginUser.getRole().equals(RecordTemplateConstant.TEMPLATE_TYPE_SYSTEM)) {
            // 对模板的enable进行停用
            recordTemplate.setEnable(true);
            if (baseMapper.updateById(recordTemplate) != 0) {
                // 删除个人启用其他系统模板的记录
                List<Long> ids = baseMapper.selectList(new LambdaQueryWrapper<MeetingRecordTemplate>()
                        .eq(MeetingRecordTemplate::getMeetingType, 1)
                        .eq(MeetingRecordTemplate::getType, RecordTemplateConstant.TEMPLATE_TYPE_SYSTEM)
                        .ne(MeetingRecordTemplate::getId, id).select(MeetingRecordTemplate::getId)).stream().map(MeetingRecordTemplate::getId).collect(Collectors.toList());
                if (CollUtil.isNotEmpty(ids)) {
                    meetTemplateEnableService.remove(new LambdaQueryWrapper<MeetTemplateEnable>().eq(MeetTemplateEnable::getMeetTypeId, 1)
                            .in(MeetTemplateEnable::getRelId, ids));
                }
                // 将其他模板的enable字段置为0
                return baseMapper.disableSystemExceptId(id) != 0;
            }
        }
        String userId = String.format("%08d", loginUser.getUserId());

        // 根据会议类型和用户id删除已开启的模板
        meetTemplateEnableMapper.delete(new QueryWrapper<MeetTemplateEnable>()
                .eq("meet_type_id", meetTypeId)
                .eq("user_id", userId));

        // 开启模板
        MeetTemplateEnable meetTemplateEnable = new MeetTemplateEnable();
        meetTemplateEnable.setRelId(id);
        meetTemplateEnable.setMeetTypeId(recordTemplate.getMeetingType());
        meetTemplateEnable.setUserId(userId);
        return meetTemplateEnableMapper.insert(meetTemplateEnable) != 0;
    }

    /**
     * 根据id删除会议模板
     *
     * @param id 模板id
     */
    @Transactional
    @Override
    public void delete(Long id) {
        // 删除模板
        baseMapper.deleteById(id);
        // 删除模板启用表
        meetTemplateEnableMapper.delete(new LambdaQueryWrapper<MeetTemplateEnable>().eq(MeetTemplateEnable::getRelId, id));
        // 重置参考该模板的其他纪要模板的referTemplateId为null
        LambdaUpdateWrapper<MeetingRecordTemplate> lambdaUpdate = Wrappers.lambdaUpdate();
        update(lambdaUpdate.eq(MeetingRecordTemplate::getReferTemplateId, id).eq(MeetingRecordTemplate::getIsDel, false).set(MeetingRecordTemplate::getReferTemplateId, null));
    }

    /**
     * 获取模板下拉列表，有权限控制
     *
     * @return
     */
    @Override
    public List<RecordTemplateDto> getTemplateSelect() {
        // 获取当前用户向上的的部门集合
        RobotSecurityUser loginUser = SecurityUtil.getUser();
        List<SysUserSyncCategory> categoryList = sysUserSyncService.getCategoryListByUserId(String.format("%08d", loginUser.getUserId()));
        List<String> parentDeptIdList = categoryList.stream().map(SysUserSyncCategory::getDeptId).collect(Collectors.toList());

        List<MeetTypeDto> meetTypeList = getMeetTypeList(String.format("%08d", loginUser.getUserId()), parentDeptIdList, loginUser.getRole());
        List<RecordTemplateDto> allRecordTemplates = meetTypeList.stream()
                .map(MeetTypeDto::getRecordTemplateDTOList)
                .filter(Objects::nonNull)
                .flatMap(List::stream)
                .filter(template -> !ObjectUtils.isEmpty(template.getId()))
                .collect(Collectors.toList());
        return allRecordTemplates;
    }

    /**
     * 根据会议类型和userId获取开启的模板
     * 如果当前会议类型中没有开启的模板，则返回系统通用的已开启的模板
     *
     * @param meetType 会议类型id
     * @param userId   userId
     */
    @Override
    public MeetingRecordTemplate getEnabledRecordTemplate(List<Long> meetType, String userId) {
        log.info("查询用户可用模板, meetType: {}, userId: {}", meetType, userId);
        MeetingRecordTemplate template = null;
        String deptPathByUserId = sysUserSyncService.getDeptPathByUserId(userId);
        List<String> parentDeptIdList = Arrays.asList(deptPathByUserId.split("/"));
        List<MeetTypeDto> list = this.getMeetTypeList(userId, parentDeptIdList, "custom");
//        System.out.println("用户拥有的模板：" + JSON.toJSONString(list));
        // 获取制定会议类型下的模板
        for (MeetTypeDto meetTypeDto : list) {
            for (Long aLong : meetType) {
                if (meetTypeDto.getId().equals(aLong)) {
                    if (CollUtil.isNotEmpty(meetTypeDto.getRecordTemplateDTOList())) {
                        for (RecordTemplateDto templateDto : meetTypeDto.getRecordTemplateDTOList()) {
                            if (templateDto.getEnable()) {
                                template = BeanUtil.copyProperties(templateDto, MeetingRecordTemplate.class);
                                break;
                            }
                        }
                    }
                }

            }
        }
        // 获取通用会议类型下的模板
        if (template == null) {
            for (MeetTypeDto meetTypeDto : list.stream().filter(e -> e.getId().equals(1L)).collect(Collectors.toList())) {
                if (CollUtil.isNotEmpty(meetTypeDto.getRecordTemplateDTOList())) {
                    for (RecordTemplateDto templateDto : meetTypeDto.getRecordTemplateDTOList()) {
                        if (templateDto.getEnable()) {
                            template = BeanUtil.copyProperties(templateDto, MeetingRecordTemplate.class);
                            break;
                        }
                    }
                }
            }
        }
        return template;
    }

    /**
     * 获取模板列表
     *
     * @param userId           用户id
     * @param parentDeptIdList 部门id列表
     * @param role
     * @return
     */
    @Override
    public List<MeetTypeDto> getMeetTypeList(String userId, List<String> parentDeptIdList, String role) {
        List<MeetTypeDto> meetTypeDtos;
        if (role.equals(RecordTemplateConstant.TEMPLATE_TYPE_SYSTEM)) {
            meetTypeDtos = baseMapper.selectTemplate(RecordTemplateConstant.TEMPLATE_TYPE_SYSTEM);
        } else {
            meetTypeDtos = baseMapper.selectCustomTemplate(userId);
            List<ModulePermission> permissions = modulePermissionService.list(new LambdaQueryWrapper<ModulePermission>()
                    .and(e -> e.eq(ModulePermission::getPurpose, PermissionPruposeType.TEMPLATE_TYPE_PERMISSION)
                            .or().eq(ModulePermission::getPurpose, PermissionPruposeType.TEMPLATE_PERMISSION)
                    ).and(e -> e.eq(ModulePermission::getType, RecordTemplateConstant.REL_TYPE_USER).eq(ModulePermission::getRelId, userId)
                            .or().eq(ModulePermission::getType, RecordTemplateConstant.REL_TYPE_DEPT).in(ModulePermission::getRelId, parentDeptIdList))
                    .select(ModulePermission::getTargetId, ModulePermission::getPurpose)
            );
            Set<Long> typeIds = permissions.stream().filter(e -> e.getPurpose().equals(PermissionPruposeType.TEMPLATE_TYPE_PERMISSION)).map(ModulePermission::getTargetId).collect(Collectors.toSet());
            Set<Long> ids = permissions.stream().filter(e -> e.getPurpose().equals(PermissionPruposeType.TEMPLATE_PERMISSION)).map(ModulePermission::getTargetId).collect(Collectors.toSet());

            meetTypeDtos.forEach(meetTypeDto -> {
                meetTypeDto.getRecordTemplateDTOList().removeIf(template -> template.getId() == null);
                if (meetTypeDto.getId() != 1) {
                    Integer authType = meetTypeDto.getAuthType();
                    if (AuthTypeConstant.NO_AUTH.equals(authType)) {
                        if (CollUtil.isNotEmpty(meetTypeDto.getRecordTemplateDTOList())) {
                            meetTypeDto.getRecordTemplateDTOList().removeIf(template -> template.getType().equals(RecordTemplateConstant.TEMPLATE_TYPE_SYSTEM) && !ids.contains(template.getId()));
                        }
                    } else if (AuthTypeConstant.SELECT.equals(authType)) {
                        if (CollUtil.isNotEmpty(meetTypeDto.getRecordTemplateDTOList())) {
                            meetTypeDto.getRecordTemplateDTOList().removeIf(template ->
                                    template.getType().equals(RecordTemplateConstant.TEMPLATE_TYPE_SYSTEM) && !typeIds.contains(meetTypeDto.getId()) && !ids.contains(template.getId()));
                        }
                    }
                }
            });

            // 通用类型(meetType=1)单独处理停启用状态-之前的sql没有办法一次性解决
            List<MeetTemplateEnable> list = meetTemplateEnableService.list(new LambdaQueryWrapper<MeetTemplateEnable>()
                    .eq(MeetTemplateEnable::getMeetTypeId, 1)
                    .eq(MeetTemplateEnable::getUserId, userId).select(MeetTemplateEnable::getRelId));
            if (CollUtil.isNotEmpty(list)) {
                Set<Long> collect = list.stream().map(MeetTemplateEnable::getRelId).collect(Collectors.toSet());
                meetTypeDtos.forEach(meetTypeDto -> {
                    if (meetTypeDto.getId() == 1) {
                        meetTypeDto.getRecordTemplateDTOList().forEach(template -> {
                            if (!collect.contains(template.getId())) {
                                template.setEnable(false);
                            }
                        });
                    }
                });
            }
        }
        // 每个会议类型下有一个兜底启用的模板
        if (role.equals(RecordTemplateConstant.TEMPLATE_TYPE_CUSTOM)) {
            meetTypeDtos.forEach(meetTypeDto -> {
                AtomicBoolean exist = new AtomicBoolean(false);
                if (CollUtil.isNotEmpty(meetTypeDto.getRecordTemplateDTOList())) {
                    for (RecordTemplateDto template : meetTypeDto.getRecordTemplateDTOList()) {
                        if (template.getEnable()) {
                            exist.set(true);
                            break;
                        }
                    }
                    if (!exist.get()) {
                        meetTypeDto.getRecordTemplateDTOList().get(0).setEnable(true);
                    }
                }
            });
        }
        return meetTypeDtos;
    }

    @Override
    public Boolean enableSysTemplate(Long id) {
        MeetingRecordTemplate template = baseMapper.selectById(id);
        if (template == null) {
            throw new RobotBaseException("模板不存在！");
        }
        template.setEnable(!template.getEnable());
        return baseMapper.updateById(template) != 0;
    }

    /**
     * 获取部门的路径
     *
     * @param deptPath
     * @param deptId
     */
    private void getDeptPath(List<String> deptPath, String deptId) {
        if (!deptPath.contains(deptId)) deptPath.add(deptId);
        List<String> subDeptIds = sysUserSysMapper.getSubDeptId(deptId);
        if (CollectionUtils.isEmpty(subDeptIds)) return;

        for (String subDeptId : subDeptIds) {
            //部门id去重
            if (!deptPath.contains(subDeptId)) {
                deptPath.add(subDeptId);
                getDeptPath(deptPath, subDeptId);
            }
        }

    }

    /**
     * 手动分页，偏移取每一页数据
     *
     * @param list
     * @param current
     * @param size
     * @return
     */
    public List<MeetingRecordTemplate> getUsersByOffset(List<MeetingRecordTemplate> list, int current, int size) {
        int offset = (current - 1) * size;
        int endIndex = Math.min(offset + size, list.size());

        // 防止偏移量越界
        if (offset >= list.size()) {
            return Collections.emptyList();
        }

        return list.subList(offset, endIndex);
    }
}