package com.qmth.exam.reserve.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
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.qmth.boot.core.collection.PageResult;
import com.qmth.boot.core.exception.StatusException;
import com.qmth.exam.reserve.bean.Constants;
import com.qmth.exam.reserve.bean.login.LoginUser;
import com.qmth.exam.reserve.bean.user.UserReq;
import com.qmth.exam.reserve.bean.user.UserSaveReq;
import com.qmth.exam.reserve.bean.user.UserVO;
import com.qmth.exam.reserve.dao.UserDao;
import com.qmth.exam.reserve.entity.UserEntity;
import com.qmth.exam.reserve.enums.Role;
import com.qmth.exam.reserve.service.UserService;
import com.qmth.exam.reserve.util.PageUtil;
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

@Service
public class UserServiceImpl extends ServiceImpl<UserDao, UserEntity> implements UserService {

    private static final Logger log = LoggerFactory.getLogger(UserServiceImpl.class);

    @Override
    public UserEntity findUserByLoginName(Long orgId, String loginName) {
        LambdaQueryWrapper<UserEntity> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(UserEntity::getOrgId, orgId);
        wrapper.eq(UserEntity::getLoginName, loginName);
        return baseMapper.selectOne(wrapper);
    }

    @Override
    public PageResult<UserVO> pageUser(UserReq req) {
        IPage<UserVO> page = baseMapper.pageUser(new Page<>(req.getPageNumber(), req.getPageSize()), req);
        page.getRecords().forEach(user -> {
            user.setRoleName(Role.getRoleName(user.getRoleCode()));
        });
        return PageUtil.of(page);
    }

    @Override
    public UserVO info(Long id) {
        UserEntity user = this.getById(id);
        if (user == null) {
            log.warn("当前用户不存在！userId:{}", id);
            throw new StatusException("当前用户不存在");
        }

        UserVO vo = new UserVO();
        vo.setId(user.getId());
        vo.setLoginName(user.getLoginName());
        vo.setName(user.getName());
        vo.setMobile(user.getMobile());
        vo.setEnable(user.getEnable());
        vo.setRoleCode(user.getRole().name());
        vo.setRoleName(user.getRole().getTitle());
        vo.setCategoryId(user.getCategoryId());
        return vo;
    }

    @Transactional
    @Override
    public void saveUser(LoginUser loginUser, UserSaveReq req) {
        if (StringUtils.isBlank(req.getLoginName())) {
            throw new StatusException("账号不能为空");
        }
        if (StringUtils.length(req.getLoginName()) > 50) {
            throw new StatusException("账号限制50字以内");
        }
        if (StringUtils.isBlank(req.getName())) {
            throw new StatusException("用户名不能为空");
        }
        if (StringUtils.length(req.getName()) > 50) {
            throw new StatusException("用户名限制50字以内");
        }
        if (StringUtils.length(req.getMobile()) > 20) {
            throw new StatusException("联系方式限制20字以内");
        }
        if (req.getRoleCode() == null) {
            throw new StatusException("请选择角色");
        }
        if (Role.TEACHING == req.getRoleCode() && req.getCategoryId() == null) {
            throw new StatusException("请选择所属教学点");
        }

        if (req.getId() != null) {
            UserEntity existUser = this.getById(req.getId());
            if (existUser == null) {
                log.warn("当前用户不存在！userId:{}", req.getId());
                throw new StatusException("当前用户不存在");
            }

            // if (!req.getLoginName().equals(existUser.getLoginName())) {
            //     UserEntity uu = this.findUserByLoginName(loginUser.getOrgId(), req.getLoginName());
            //     if (uu != null) {
            //         throw new StatusException("登录账号已存在");
            //     }
            //
            //     existUser.setLoginName(req.getLoginName());
            // }

            existUser.setRole(req.getRoleCode());
            existUser.setName(req.getName());
            existUser.setMobile(req.getMobile());
            existUser.setCategoryId(req.getCategoryId());
            existUser.setUpdateTime(System.currentTimeMillis());

            this.saveOrUpdate(existUser);
            log.warn("修改用户！userId:{}", existUser.getId());
            return;
        }

        UserEntity existUser = this.findUserByLoginName(loginUser.getOrgId(), req.getLoginName());
        if (existUser != null) {
            throw new StatusException("登录账号已存在");
        }

        UserEntity newUser = new UserEntity();
        newUser.setOrgId(loginUser.getOrgId());
        newUser.setRole(req.getRoleCode());
        newUser.setLoginName(req.getLoginName());
        newUser.setName(req.getName());
        newUser.setMobile(req.getMobile());
        newUser.setCategoryId(req.getCategoryId());
        newUser.setEnable(Boolean.TRUE);
        newUser.setFirstLogin(Boolean.TRUE);
        newUser.setCreateTime(System.currentTimeMillis());
        newUser.setUpdateTime(System.currentTimeMillis());
        newUser.setPassword(DigestUtils.sha256Hex(Constants.DEFAULT_PASSWORD).toUpperCase());
        this.save(newUser);
        log.warn("新增用户！userId:{}", newUser.getId());
    }

    @Override
    public void resetPassword(Long id) {
        LambdaUpdateWrapper<UserEntity> updateWrapper = new LambdaUpdateWrapper<>();
        updateWrapper.set(UserEntity::getPassword, DigestUtils.sha256Hex(Constants.DEFAULT_PASSWORD).toUpperCase());
        updateWrapper.set(UserEntity::getFirstLogin, true);
        updateWrapper.set(UserEntity::getUpdateTime, System.currentTimeMillis());
        updateWrapper.eq(UserEntity::getId, id);

        this.update(updateWrapper);
        log.warn("重置用户密码！userId:{}", id);
    }

    @Override
    public void enable(Long id, Boolean enable) {
        LambdaUpdateWrapper<UserEntity> updateWrapper = new LambdaUpdateWrapper<>();
        updateWrapper.set(UserEntity::getEnable, enable);
        updateWrapper.set(UserEntity::getUpdateTime, System.currentTimeMillis());
        updateWrapper.eq(UserEntity::getId, id);

        this.update(updateWrapper);
        log.warn("更新用户状态！userId:{} enable:{}", id, enable);
    }

}
