package cn.qinys.platform.upms.api.service.impl;

import cn.qinys.platform.base.exceptions.BizException;
import cn.qinys.platform.base.utils.BeanExUtils;
import cn.qinys.platform.entity.upms.UpmsUser;
import cn.qinys.platform.entity.upms.UpmsUserRole;
import cn.qinys.platform.upms.api.mapper.UpmsUserMapper;
import cn.qinys.platform.upms.api.mapper.UpmsUserRoleMapper;
import cn.qinys.platform.upms.api.req.*;
import cn.qinys.platform.upms.api.resp.UserAccountInfoResp;
import cn.qinys.platform.upms.api.resp.UserDetailResp;
import cn.qinys.platform.upms.api.resp.UserPageResp;
import cn.qinys.platform.upms.api.service.ICurrentUserService;
import cn.qinys.platform.upms.api.service.IUserService;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import lombok.AllArgsConstructor;
import org.springframework.beans.BeanUtils;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.time.LocalDateTime;
import java.util.Arrays;
import java.util.List;

/**
 * Description:
 *
 * @author tanlie
 * Date: 2024/2/26 17:37
 */
@Service
@AllArgsConstructor
public class UserServiceImpl implements IUserService {

    private final UpmsUserMapper userMapper;
    private final UpmsUserRoleMapper userRoleMapper;
    private final PasswordEncoder passwordEncoder;
    private final ICurrentUserService currentUserService;


    @Override
    public Page<UserPageResp> getUserPage(UserPageReq req) {
        Page<UpmsUser> page = new Page<>(req.getCurrent(), req.getSize());
        QueryWrapper<UpmsUser> wrapper = new QueryWrapper<>();
        wrapper.eq("u.deleted", "0");
        wrapper.like(StringUtils.hasLength(req.getFullName()), "u.full_name", req.getFullName());
        wrapper.like(StringUtils.hasLength(req.getMobile()), "u.mobile", req.getMobile());
        return userMapper.selectUserPage(page, wrapper);
    }

    @Override
    public void createUser(UserCreateReq req) {
        // 账号校验
        UpmsUser exist = userMapper.selectByUsername(req.getUsername());
        if (exist != null) {
            throw new BizException("用户名已存在");
        }
        UpmsUser user = BeanExUtils.convert(req, UpmsUser.class);
        user.setCreateTime(LocalDateTime.now());
        user.setUpdateTime(LocalDateTime.now());
        userMapper.insert(user);
        for (String roleId : req.getRoleIds()) {
            UpmsUserRole role = new UpmsUserRole();
            role.setUserId(user.getId());
            role.setRoleId(roleId);
            userRoleMapper.insert(role);
        }
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void updateUser(UserUpdateReq req) {
        UpdateWrapper<UpmsUser> updateWrapper = new UpdateWrapper<>();
        updateWrapper.eq("id", req.getId());
        UpmsUser entity = new UpmsUser();
        entity.setAvatar(req.getAvatar());
        BeanUtils.copyProperties(req, entity);
        entity.setUpdateTime(LocalDateTime.now());
        userMapper.update(entity, updateWrapper);

    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void removeUser(UserRemoveReq req) {
        userMapper.deleteBatchIds(req.getIds());
        //删除用户角色
        //删除用户权限
        for (String id : req.getIds()) {
            userRoleMapper.deleteUserRole(id);
        }
    }

    @Override
    public UserAccountInfoResp getAccountInfo(String id) {
        UpmsUser user = userMapper.selectById(id);
        UserAccountInfoResp resp = new UserAccountInfoResp();
        BeanUtils.copyProperties(user, resp);
        resp.setRoleIds(userRoleMapper.selectRoleIds(id));
        return resp;
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void userRoleAdd(UserRoleOperationReq req) {
        for (String roleId : req.getRoleIds()) {
            QueryWrapper<UpmsUserRole> wrapper = new QueryWrapper<>();
            wrapper.eq("user_id", req.getId());
            wrapper.eq("role_id", roleId);
            wrapper.last("LIMIT 1");
            UpmsUserRole exist = userRoleMapper.selectOne(wrapper);
            if (exist != null) {
                continue;
            }
            UpmsUserRole role = new UpmsUserRole();
            role.setUserId(req.getId());
            role.setRoleId(roleId);
            userRoleMapper.insert(role);
        }
        currentUserService.refreshUserInfo(req.getId());
    }

    @Override
    public void userRoleDelete(UserRoleOperationReq req) {
        for (String roleId : req.getRoleIds()) {
            // 不能删最后一个
            List<String> roleIds = userRoleMapper.selectRoleIds(req.getId());
            if (roleIds == null || roleIds.size() <= 1) {
                throw new BizException("用户至少要要有一个角色");
            }
            QueryWrapper<UpmsUserRole> wrapper = new QueryWrapper<>();
            wrapper.eq("user_id", req.getId());
            wrapper.eq("role_id", roleId);
            userRoleMapper.delete(wrapper);
        }
        currentUserService.refreshUserInfo(req.getId());
    }

    @Override
    public void changeLock(UserChangeLockReq req) {
        List<String> status = Arrays.asList("1", "0");
        if (!status.contains(req.getLocked())) {
            throw new BizException("锁定状态不正确");
        }
        userMapper.updateLockStatus(req.getId(), req.getLocked());
    }

    @Override
    public void resetPassword(UserResetPasswordReq req) {
        String encodePassword = passwordEncoder.encode(req.getPassword());
        UpdateWrapper<UpmsUser> updateWrapper = new UpdateWrapper<>();
        updateWrapper.eq("id", req.getId());
        UpmsUser entity = new UpmsUser();
        entity.setPassword(encodePassword);
        entity.setExpired("0");
        entity.setPwdExpired(LocalDateTime.now().plusMonths(3));
        entity.setPwdChangeTime(LocalDateTime.now());
        userMapper.update(entity, updateWrapper);
    }

    @Override
    public UserDetailResp userDetailById(String userId) {
        UpmsUser user = userMapper.selectById(userId);
        UserDetailResp resp = new UserDetailResp();
        BeanUtils.copyProperties(user, resp);
        return resp;
    }


}
