package com.qmth.jkserver.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.qmth.jkserver.common.Constants;
import com.qmth.jkserver.constant.SystemConstant;
import com.qmth.jkserver.core.AesEncryptUtil;
import com.qmth.jkserver.core.cache.JkCacheService;
import com.qmth.jkserver.core.exception.JkServerException;
import com.qmth.jkserver.dao.UserDao;
import com.qmth.jkserver.enums.UserRole;
import com.qmth.jkserver.model.BasicSchool;
import com.qmth.jkserver.model.User;
import com.qmth.jkserver.model.UserLog;
import com.qmth.jkserver.service.CommonCacheService;
import com.qmth.jkserver.service.JkUserLogService;
import com.qmth.jkserver.service.UserService;
import com.qmth.jkserver.util.Base64Util;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
import org.springframework.context.annotation.ScopedProxyMode;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.PageRequest;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.nio.charset.StandardCharsets;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;

@Service
@Scope(proxyMode = ScopedProxyMode.INTERFACES)
public class UserServiceImpl extends ServiceImpl<UserDao, User> implements UserService {

    @Resource
    UserDao userDao;

    @Resource
    UserService userService;

    @Autowired
    JkCacheService cacheService;

    @Resource
    JkUserLogService jkUserLogService;

//    @Autowired
//    private MongoOperations mongoTemplate;

    @Resource
    CommonCacheService commonCacheService;

    @Override
    public User saveService(User user) throws Exception {
        if (Objects.isNull(user.getId())) {//新增用户，密码默认1234556
            //判断用户名是否重复
//            List<User> users = userDao.findByUserName(user.getUserName());
            user.setId(SystemConstant.getDbUuid());
//            Long schoolId = user.getSchoolId();
            QueryWrapper<User> userQueryWrapper = new QueryWrapper<>();
//            if (Objects.nonNull(schoolId)) {
//                userQueryWrapper.lambda().eq(User::getUserName, user.getUserName()).eq(User::getSchoolId, schoolId);
//            } else {
            userQueryWrapper.lambda().eq(User::getUserName, user.getUserName());
//            }
            List<User> users = userService.list(userQueryWrapper);
            if (users.size() > 0) {
                throw JkServerException.withFieldValidateError("用户名:" + user.getUserName() + "已经存在");
            }
            BasicSchool basicSchool = commonCacheService.schoolCache(user.getSchoolId());
            if (Objects.nonNull(basicSchool)) {
                user.setBasicSchool(basicSchool);
            }
            user.setCreateTime(System.currentTimeMillis());
            if (StringUtils.isEmpty(user.getPassword())) {
                user.setPassword("123456");
            }
            user.setPassword(Base64Util.encode(user.getPassword().getBytes(StandardCharsets.UTF_8)));
        }
        this.saveOrUpdate(user);
        return user;
    }

    @Override
    public void deleteById(Long id) {
//        userDao.delete(id);
        this.removeById(id);
    }

    @Override
    public User findById(Long id) {
//        return userDao.findOne(id);
        return this.getById(id);
    }

    @Override
    public Page<User> findAll(User searchCondition, int curPage, int pageSize) {
//        Query query = new Query();
        QueryWrapper<User> userQueryWrapper = new QueryWrapper<>();
        if (StringUtils.isNotEmpty(searchCondition.getUserName())) {
//            Criteria cr = new Criteria();
//            cr.orOperator(
//                    Criteria.where("userName").regex(searchCondition.getUserName()),
//                    Criteria.where("realName").regex(searchCondition.getUserName()));
//            query.addCriteria(cr);
            userQueryWrapper.lambda().and(wrapper -> wrapper.like(User::getUserName, searchCondition.getUserName()).or().like(User::getRealName, searchCondition.getUserName()));
        }
//        long count = this.mongoTemplate.count(query, User.class);
//        long count = this.count(userQueryWrapper);
//        query.limit(pageSize);
//        query.skip((curPage - 1) * pageSize);
//        List<User> examStudentList = this.mongoTemplate.find(query, User.class);
        IPage<User> examStudentList = userDao.findByUserNameByPage(new com.baomidou.mybatisplus.extension.plugins.pagination.Page<>(curPage, pageSize), searchCondition.getUserName());
        return new PageImpl<User>(examStudentList.getRecords(), PageRequest.of(curPage - 1, pageSize), examStudentList.getTotal());
    }

    @Override
    public Map<String, Object> login(String userName, String password) throws Exception {
        List<User> users = userDao.findByUserName(userName);
        if (users.size() == 0) {
            throw new JkServerException(JkServerException.FILED_VALIDATE_ERROR.getCode(), "用户名或者密码错误");
        }
        User user = users.get(0);
        String encodePwd = Base64Util.encode(password.getBytes(StandardCharsets.UTF_8));
        if (Objects.nonNull(encodePwd) && !encodePwd.trim().equals(user.getPassword())) {
            throw new JkServerException(JkServerException.FILED_VALIDATE_ERROR.getCode(), "用户名或者密码错误");
        }
        String token = AesEncryptUtil.encrypt(user.getId() + "_" + System.currentTimeMillis());
        BasicSchool basicSchool = commonCacheService.schoolCache(user.getSchoolId());
        user.setBasicSchool(basicSchool);
        user.setToken(token);
        cacheService.setObj(Constants.CACHE_USER + user.getId(), user, 480 * 60);//用户token缓存 8小时
        UserLog ul = new UserLog();
        ul.setId(SystemConstant.getDbUuid());
        ul.setLoginTime(System.currentTimeMillis());
        ul.setUserId(user.getId());
        jkUserLogService.saveOrUpdate(ul);
//        userLogDao.save(ul);
        Map<String, Object> map = new HashMap<>();
        map.put("user", user);
        map.put("accessToken", token);
        map.put("version", SystemConstant.VERSION);
        return map;
    }

    @Override
    public void logout(HttpServletRequest request) {
        String token = request.getHeader(Constants.REQUEST_HEADER_TOKEN);
        if (StringUtils.isNotEmpty(token)) {
            User user = SystemConstant.tokenGetUser(token);
            cacheService.delObj(Constants.CACHE_USER + user.getId());
        }
    }

    @Override
    public void superResetPwd(HttpServletRequest request, String userName, String password, Long schoolId) {
        SystemConstant.superOper();
//        List<User> users = userDao.findByUserName(userName);
        QueryWrapper<User> userQueryWrapper = new QueryWrapper<>();
//        if (Objects.nonNull(schoolId)) {
//            userQueryWrapper.lambda().eq(User::getUserName, userName).eq(User::getSchoolId, schoolId);
//        } else {
        userQueryWrapper.lambda().eq(User::getUserName, userName);
//        }
        List<User> users = userService.list(userQueryWrapper);
        if (users.size() == 0) {
            throw new JkServerException(JkServerException.FILED_VALIDATE_ERROR.getCode(), "用户名不存在:" + userName);
        }
        User my = users.get(0);
        my.setPassword(Base64Util.encode(password.getBytes(StandardCharsets.UTF_8)));
//        userDao.save(my);
        this.saveOrUpdate(my);
    }

    @Override
    public User resetPwd(HttpServletRequest request, String oldPwd, String newPwd) throws Exception {
        String token = request.getHeader(Constants.REQUEST_HEADER_TOKEN);
        User user = SystemConstant.tokenGetUser(token);
        if (user == null) {
            throw new JkServerException(JkServerException.FILED_VALIDATE_ERROR.getCode(), "获取用户信息失败");
        }
        if (user.getRole() == UserRole.SUPER_ADMIN) {
            throw new JkServerException(JkServerException.FILED_VALIDATE_ERROR.getCode(), "超级用户不允许修改密码");
        }
        if (!Base64Util.encode(oldPwd.getBytes(StandardCharsets.UTF_8)).equals(user.getPassword())) {
            throw new JkServerException(JkServerException.FILED_VALIDATE_ERROR.getCode(), "旧密码不正确");
        } else {
            user.setPassword(Base64Util.encode(newPwd.getBytes(StandardCharsets.UTF_8)));
        }
        this.saveOrUpdate(user);
        return user;
    }

    @Override
    public UserLog queryLastTimeLoginUser(HttpServletRequest request) {
        String token = request.getHeader(Constants.REQUEST_HEADER_TOKEN);
        User user = SystemConstant.tokenGetUser(token);
//        Query query = new Query();
//        query.addCriteria(Criteria.where("userId").is(user.getId()));
//        query.with(new Sort(Direction.DESC, "loginTime"));
//        List<UserLog> ulList = mongoTemplate.find(query, UserLog.class);
        QueryWrapper<UserLog> userLogQueryWrapper = new QueryWrapper<>();
        userLogQueryWrapper.lambda().eq(UserLog::getUserId, user.getId())
                .orderByDesc(UserLog::getLoginTime);
        List<UserLog> ulList = jkUserLogService.list(userLogQueryWrapper);
        UserLog userLog = new UserLog();
        if (ulList != null && ulList.size() > 2) {
            userLog = ulList.get(0);
        } else {//第一次登录
            userLog.setLoginTime(System.currentTimeMillis());
        }
        userLog.setUser(user);
        userLog.setUserId(user.getId());
        return userLog;
    }

    @Override
    public User findByUserName(String userName) {
        List<User> users = userDao.findByUserName(userName);
        return users.size() > 0 ? users.get(0) : null;
    }
}
