package com.mx.cneeds.server.user.service.impl;

import com.mx.cneeds.common.annotation.DataFilter;
import com.mx.cneeds.common.dto.DataFilterDto;
import com.mx.cneeds.common.pager.PageUtils;
import com.mx.cneeds.common.pager.Query;
import com.mx.cneeds.server.dao.SysUserDao;
import com.mx.cneeds.server.entity.SysFuncEntity;
import com.mx.cneeds.server.entity.SysUserEntity;
import com.mx.cneeds.server.user.service.*;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.transaction.annotation.Transactional;


@Service("sysUserService")
public class SysUserServiceImpl extends ServiceImpl<SysUserDao, SysUserEntity> implements SysUserService {

    @Autowired
    private SysUserFuncService sysUserFuncService;

    @Autowired
    private SysUserDeptService sysUserDeptService;

    @Autowired
    private SysUserRoleService sysUserRoleService;

    @Autowired
    private SysDeptService sysDeptService;

    @Autowired
    private SysRoleDeptService sysRoleDeptService;

    @Autowired
    private SysRoleFuncService sysRoleFuncService;

    @Autowired
    private SysFuncService sysFuncService;


    @Override
    public PageUtils queryPage(Map<String, Object> params) {
        IPage<SysUserEntity> page = this.page(
                new Query<SysUserEntity>().getPage(params),
                new QueryWrapper<SysUserEntity>()
        );

        return new PageUtils(page);
    }

    @Override
    public SysUserEntity queryUserByUsername(String username) {
        return getBaseMapper().selectOne(
                new QueryWrapper<SysUserEntity>()
                .eq("username",username));
    }


    @Override
    @Transactional(rollbackFor = Exception.class)
    public void deleteBatch(Long[] userIds) {
        //删除角色
        this.removeByIds(Arrays.asList(userIds));

        //删除用户与菜单关联
        sysUserFuncService.deleteBatch(userIds);

        //删除用户与部门关联
        sysUserDeptService.deleteBatch(userIds);

    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void saveUser(SysUserEntity user, List<Long> funcIdList, List<Long> deptIdList, Long roleId) {
        user.setCreateTime(new Date());
        this.save(user);


        //保存用户与角色关系
        sysUserRoleService.saveOrUpdate(user.getUserId(), roleId);
        //保存角色与菜单关系
        sysUserFuncService.saveOrUpdate(user.getUserId(), funcIdList);

        //保存角色与部门关系
        sysUserDeptService.saveOrUpdate(user.getUserId(), deptIdList);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void update(SysUserEntity user, List<Long> funcIdList, List<Long> deptIdList) {
        this.updateById(user);
        if (funcIdList!=null && funcIdList.size()!=0){
            //更新用户与菜单关系
            sysUserFuncService.saveOrUpdate(user.getUserId(), funcIdList);
        }

        if (deptIdList!=null && deptIdList.size()!=0){
            //保存用户与部门关系
            sysUserDeptService.saveOrUpdate(user.getUserId(), deptIdList);
        }
    }

    @Override
    public List<String> getUserPerms(String username){
        SysUserEntity sysUserEntity = queryUserByUsername(username);

        // 模块Id
        Set<Long> funcIdList = new HashSet<>();
        // 模块权限字段
        List<String> funcPermsList = new ArrayList<>();

        //用户角色对应的模块区权限
        Long roleId = sysUserRoleService.queryRoleId(sysUserEntity.getUserId());

        List<Long> funcList = sysRoleFuncService.queryFuncId(roleId);
        funcIdList.addAll(funcList);

        List<Long> userFuncList = sysUserFuncService.queryFuncIdList(sysUserEntity.getUserId());
        userFuncList.forEach(funcId -> {
            funcIdList.add(funcId);
        });

        if (funcIdList.size() !=0){
            List<SysFuncEntity> sysFuncEntities = sysFuncService.queryFuncByIds(funcIdList);
            sysFuncEntities.forEach(entity -> {
                funcPermsList.add(entity.getPerms());
            });
            return funcPermsList;
        }else {
            return null;
        }

    }

    @Override
    public String genDataFilter(DataFilterDto dataFilterDto) {

        //获取表的别名
        String tableAlias = dataFilterDto.getTableAlias();
        if(StringUtils.isNotBlank(tableAlias)){
            tableAlias +=  ".";
        }

        StringBuilder sqlFilter = new StringBuilder();
        sqlFilter.append(" (");

        //部门ID列表
        Set<Long> deptIdList = new HashSet<>();

        SysUserEntity sysUserEntity = queryUserByUsername(dataFilterDto.getUsername());

        //用户角色对应的部门ID列表
        Long roleId = sysUserRoleService.queryRoleId(sysUserEntity.getUserId());

        // 查询用户关联的部门权限表
        List<Long> userDeptIdList = sysUserDeptService.queryDeptId(sysUserEntity.getUserId());
        deptIdList.addAll(userDeptIdList);
        if(roleId != null){
            List<Long> roleDeptIdList = sysRoleDeptService.queryDeptId(roleId);
            deptIdList.addAll(roleDeptIdList);
        }

        //用户子部门ID列表
        if(dataFilterDto.isSubDept()){
            List<Long> subDeptIdList = sysDeptService.getSubDeptIdList(sysUserEntity.getUserId());
            deptIdList.addAll(subDeptIdList);
        }
        if(deptIdList.size() > 0){
            sqlFilter.append(tableAlias).append(dataFilterDto.getDeptId()).append(" in(").append(StringUtils.join(deptIdList, ",")).append(")");
        }

        //没有本部门数据权限，也能查询本人数据
        if(dataFilterDto.isUser()){
            if(deptIdList.size() > 0){
                sqlFilter.append(" or ");
            }
            sqlFilter.append(tableAlias).append(dataFilterDto.getUserId()).append("=").append(sysUserEntity.getUserId());
        }

        sqlFilter.append(")");

        if(sqlFilter.toString().trim().equals("()")){
            return null;
        }

        return sqlFilter.toString();
    }

}
