package com.sy.coinage.sys.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
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.sy.coinage.core.constants.Constants;
import com.sy.coinage.core.exception.RetException;
import com.sy.coinage.core.util.MD5Util;
import com.sy.coinage.core.util.RandomUtil;
import com.sy.coinage.core.util.TreeUtil;
import com.sy.coinage.core.util.TreeUtil.TreeNode;
import com.sy.coinage.core.vo.CacheUserVO;
import com.sy.coinage.core.vo.OptVO;
import com.sy.coinage.sys.dao.UserDao;
import com.sy.coinage.sys.model.*;
import com.sy.coinage.sys.req.*;
import com.sy.coinage.sys.service.*;
import com.sy.coinage.sys.vo.*;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Date;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

/**
 * 用户ServiceImpl
 */
@Service
public class UserServiceImpl extends ServiceImpl<UserDao, User> implements IUserService {

    @Autowired
    private IUserRoleService userRoleService;

    @Autowired
    private IUserExtService userExtService;

    @Autowired
    private IRoleMenuService roleMenuService;

    @Autowired
    private IMenuService menuService;

    @Override
    public IPage<UserListVO> queryPageList(UserListReq req, CacheUserVO user) {
        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("tenant_id", user.getTenantId());
        queryWrapper.eq("del_flag", Constants.STATUS_USABLE);
        queryWrapper.eq((req.getStatus() != null && req.getStatus() > 0), "status", req.getStatus());
        queryWrapper.eq((req.getDeptId() != null && req.getDeptId() > 0), "dept_id", req.getDeptId());
        queryWrapper.like(StringUtils.isNotBlank(req.getRealName()), "real_name", req.getRealName());
        Page<UserListVO> page = new Page<>(req.getPage(), req.getRows());
        IPage<UserListVO> resp = this.baseMapper.queryPageList(page, queryWrapper);
        return resp;
    }

    /**
     * 根据用户id获取用户的角色id集合
     */
    @Override
    public List<Integer> listRoleIds(Integer userId) {
        return this.userRoleService.selectRoleIdsByUserId(userId);
    }

    @Override
    public List<UserMenusVO> menusTree(Integer id) {
        // 根据用户id获取全部菜单
        List<UserMenusVO> list = this.listMenus(id);
        Collection<? extends TreeNode<Integer>> resp = TreeUtil.buildTree(list, 0);
        return (List<UserMenusVO>) resp;
    }

    /**
     * 根据用户id获取全部菜单
     */
    private List<UserMenusVO> listMenus(Integer userId) {
        List<UserMenusVO> list = this.menuService.queryUserMenusList(userId);
        if (list == null || list.size() == 0) {
            return new ArrayList<>();
        }
        return list;
    }

    /**
     * 添加用户
     */
    @Override
    @Transactional
    public void add(UserReq req, CacheUserVO user) {
        User model = new User();
        BeanUtils.copyProperties(req, model);
        model.setTenantId(user.getTenantId());
        model.setId(null);
        model.setStatus(Constants.STATUS_USABLE);
        model.setDelFlag(Constants.STATUS_USABLE);
        model.setPwdInit(Constants.STATUS_USABLE);
        model.setType(Constants.STATUS_USABLE);
        // 生成六位随机盐
        model.setSalt(RandomUtil.randomStr(6));
        // 密码加盐MD5加密
        model.setPassword(MD5Util.MD5(req.getPassword() + model.getSalt()));
        model.setCreateBy(user.getRealName());
        this.save(model);
        // 添加用户扩展信息
        this.addUserExt(model.getId(), req);
        // 添加用户角色
        this.addRole(model.getId(), req.getRoleIds());
    }

    /**
     * 添加用户扩展信息
     */
    private void addUserExt(Integer id, UserReq req) {
        UserExt model = new UserExt();
        model.setId(id);
        model.setCode(req.getCode());
        model.setCardNumber(req.getCardNumber());
        model.setLoginNum(0);
        userExtService.save(model);
    }

    @Override
    public List<OptVO> opt(Integer orgId, Integer deptId, Integer tenantId) {
        // TODO Auto-generated method stub
        return null;
    }

    /**
     * 添加用户角色
     */
    private void addRole(Integer userId, List<Integer> roleIds) {
        if (roleIds != null && roleIds.size() > 0) {
            // 删除原有的
            LambdaUpdateWrapper<UserRole> queryWrapper = new LambdaUpdateWrapper<>();
            queryWrapper.eq(UserRole::getUserId, userId);
            this.userRoleService.remove(queryWrapper);
            for (int i = 0; i < roleIds.size(); i++) {
                UserRole model = new UserRole();
                model.setUserId(userId);
                model.setRoleId(roleIds.get(i));
                this.userRoleService.save(model);
            }
        }
    }

    /**
     * 根据角色id获取按钮权限
     */
    @Override
    public List<String> getPermission(List<Integer> roleIds) {
        List<String> resp = new ArrayList<>();
        if (roleIds != null && roleIds.size() > 0) {
            QueryWrapper<RoleMenu> queryWrapper = new QueryWrapper<>();
            queryWrapper.in("role_id", roleIds).isNotNull("sys_role_menu.permission");
            List<PermissionVO> list = this.roleMenuService.queryPermissionList(queryWrapper);
            if (null != list && list.size() > 0) {
                Set<String> s = new HashSet<>();
                for (int i = 0; i < list.size(); i++) {
                    if (StringUtils.isNotBlank(list.get(i).getPermission())) {
                        String[] str = list.get(i).getPermission().split(",");
                        s.addAll(Arrays.asList(str));
                    }
                }
                resp.addAll(s.stream().collect(Collectors.toList()));
            }
        }
        return resp;
    }

    @Override
    public List<OptVO> byRoleId(Integer roleId) {
        List<OptVO> resp = null;
        // 当前用户也在
        resp = this.baseMapper.selectByRoleId(roleId);
        return resp;
    }

    @Override
    @Transactional
    public void update(UserReq req, CacheUserVO user) {
        User model = this.getById(req.getId());
        BeanUtils.copyProperties(req, model);
        model.setUpdateBy(user.getRealName());
        model.setPassword(null);
        model.setUsername(null);
        if (null != req.getStatus() && req.getStatus().intValue() == Constants.STATUS_FORBIDDEN) {
            model.setStatus(req.getStatus());
        }
        this.updateById(model);
        UserExt ext = this.userExtService.getById(req.getId());
        if (ext == null) {
            ext = new UserExt();
            ext.setId(model.getId());
            ext.setCode(req.getCode());
            ext.setCardNumber(req.getCardNumber());
            ext.setLoginNum(0);
            this.userExtService.save(ext);
        } else {
            ext.setCardNumber(req.getCardNumber());
            ext.setCode(req.getCode());
            this.userExtService.updateById(ext);
        }
        // 添加用户角色
        this.addRole(model.getId(), req.getRoleIds());
    }

    // =========================租户管理员

    @Override
    public IPage<UserListVO> adminQueryPageList(AdminUserListReq req) {
        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
        if (req.getTenantId() != null && req.getTenantId() > 0) {
            queryWrapper.eq("tenant_id", req.getTenantId());
        } else {
            queryWrapper.isNotNull("tenant_id");
        }
        queryWrapper.eq("del_flag", Constants.STATUS_USABLE);
        queryWrapper.eq((req.getStatus() != null && req.getStatus() > 0), "status", req.getStatus());
        Page<UserListVO> page = new Page<>(req.getPage(), req.getRows());
        IPage<UserListVO> resp = this.baseMapper.queryPageList(page, queryWrapper);
        return resp;
    }

    /**
     * 租户管理员-添加用户
     */
    @Override
    @Transactional
    public void adminAdd(AdminUserReq req, CacheUserVO user) {
        User model = new User();
        BeanUtils.copyProperties(req, model);
        model.setId(null);
        model.setStatus(Constants.STATUS_USABLE);
        model.setDelFlag(Constants.STATUS_USABLE);
        model.setPwdInit(Constants.STATUS_USABLE);
        model.setType(Constants.STATUS_USABLE);
        // 生成六位随机盐
        model.setSalt(RandomUtil.randomStr(6));
        // 密码加盐MD5加密
        model.setPassword(MD5Util.MD5(req.getPassword() + model.getSalt()));
        model.setCreateBy(user.getRealName());
        this.save(model);
        // 添加用户角色
        this.addRole(model.getId(), req.getRoleIds());
    }

    @Override
    public void validUsername(Integer id, String username) {
        LambdaQueryWrapper<User> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(User::getUsername, username);
        if (null != id) {
            queryWrapper.ne(User::getId, id);
        }
        long count = this.count(queryWrapper);
        if (count > 0) {
            throw new RetException(username + "已存在");
        }
    }

}
