package com.koobietech.eas.service.impl;

import com.anji.captcha.model.common.ResponseModel;
import com.koobietech.eas.dao.constant.UserType;
import com.koobietech.eas.common.exception.EasException;
import com.koobietech.eas.common.pojo.JwtUserPojo;
import com.koobietech.eas.common.result.JsonResult;
import com.koobietech.eas.common.utils.JwtManager;
import com.koobietech.eas.common.utils.PasswordManager;
import com.koobietech.eas.dao.pojo.UserDetailPojo;
import com.koobietech.eas.dao.dto.LoginTokenDto;
import com.koobietech.eas.dao.mapper.AdminLoginMapper;
import com.koobietech.eas.mbg.mapper.EasSysUserinfoMapper;
import com.koobietech.eas.mbg.model.EasSysUserinfo;
import com.koobietech.eas.mbg.model.EasSysUserinfoExample;
import com.koobietech.eas.service.EasSysAdminLoginService;
import com.koobietech.eas.service.EasSysUserLoginRedisService;
import com.koobietech.eas.dao.pojo.AdminPojo;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.List;
import java.util.Optional;

@Service
public class EasSysAdminLoginServiceImpl implements EasSysAdminLoginService {

    @Resource
    private PasswordEncoder passwordEncoder;
    @Resource
    private PasswordManager passwordManager;
    @Resource
    private AdminLoginMapper adminLoginMapper;
    @Resource
    private EasSysUserinfoMapper easSysUserinfoMapper;
    @Resource
    private EasSysUserLoginRedisService loginRedisService;
    @Resource
    private JwtManager jwtManager;

    // token过期时间 单位：s
    private final Integer token_expires = 24 * 60 * 60;
    private final Integer refreshToken_expires = 48 * 60 * 60;

    @Override
    public LoginTokenDto adminLogin(AdminPojo adminPojo) {
        if (adminPojo.getUsername() == null || adminPojo.getPasswd() == null || adminPojo.getUsername().isEmpty() || adminPojo.getPasswd().isEmpty()) {
            throw new EasException("用户不存在", 412);
        }

        EasSysUserinfo easSysUserinfo = findAdminByUsername(adminPojo.getUsername(), adminPojo.getPasswd());

        // 接收到对象，根据这个信息去查询数据库，然后自定义sql查用户信息，存在redis里面当做token
        System.out.println(easSysUserinfo);
        //先获取id，进行枚举判断
        Long id = easSysUserinfo.getId();
        //先调用自定义sql查询detail类中的数据 最后把这个类封装到redis里面
        UserDetailPojo userDetailPojoInRedis = adminLoginMapper.getUserDetailById(id);
        System.out.println("接收前" + userDetailPojoInRedis);
        userDetailPojoInRedis.setDepartments(adminLoginMapper.getUserDepartmentsById(id));
        userDetailPojoInRedis.setPermissionPojos(adminLoginMapper.getUserPermissionsById(id));
        System.out.println("接收后" + userDetailPojoInRedis);

        // 先调用自定义sql查询用户详细信息、部门信息 和 权限信息
        UserType userType = UserType.TEACHER;
        if (userDetailPojoInRedis.getUsername().equals("admin")) {
            userType = UserType.ADMIN;
        }
        userDetailPojoInRedis.setUserType(userType);
        // 生成token
        JwtUserPojo jwtUserPojo = new JwtUserPojo(userDetailPojoInRedis.getUsername(), userDetailPojoInRedis.getId(), userType);
        String token = jwtManager.createJwt(jwtUserPojo, token_expires);
        String refreshToken = jwtManager.createJwt(jwtUserPojo, refreshToken_expires);
        System.out.println("token:" + token);
        System.out.println("refreshToken:" + refreshToken);

        // 生成redis key
        String redisTokenKey = loginRedisService.createJwtTokenKey(jwtUserPojo);
        String redisRefreshTokenKey = loginRedisService.createJwtRefreshTokenKey(jwtUserPojo);

        // 将token存入redis
        loginRedisService.loginSaveCache(redisTokenKey, userDetailPojoInRedis, token_expires);
        loginRedisService.loginSaveCache(redisRefreshTokenKey, userDetailPojoInRedis, refreshToken_expires);

        // 登录成功
        return new LoginTokenDto(token, refreshToken);
    }

    @Override
    public LoginTokenDto refreshToken(String refreshToken) {
        // 解析refresh token
        JwtUserPojo jwtUserPojo = jwtManager.decodeJwt(refreshToken);

        //生成新的 刷新k值 （refresh_token）
        String newRedisRefreshTokenKey = loginRedisService.createJwtRefreshTokenKey(jwtUserPojo);

        //查询redis里面有没有这个k值
        UserDetailPojo userDetailPojoInRedis = loginRedisService.loginGetCache(newRedisRefreshTokenKey);
        if (userDetailPojoInRedis == null) {
            throw new EasException("refresh token已过期", 412);
        }
        //如果不为空 那UserDetail里面就封装了用户的信息 生成新的token和refresh token
        String newToken = jwtManager.createJwt(jwtUserPojo, token_expires);
        String newRefreshToken = jwtManager.createJwt(jwtUserPojo, refreshToken_expires);

        //生成新的k值 （token）
        String newRedisTokenKey = loginRedisService.createJwtTokenKey(jwtUserPojo);

        // 更新Redis中的token和refresh token
        loginRedisService.loginSaveCache(newRedisTokenKey, userDetailPojoInRedis, token_expires);
        loginRedisService.loginSaveCache(newRedisRefreshTokenKey, userDetailPojoInRedis, refreshToken_expires);
        return new LoginTokenDto(newToken, newRefreshToken);
    }


    @Override
    public JsonResult verifyToJsonResult(ResponseModel response) {
        JsonResult result = new JsonResult();

        if (response != null) {
            result.setMsg(response.getRepMsg());
            result.setStatus(response.isSuccess());
            result.setData(response.getRepData());
            result.setCode( Integer.parseInt(response.getRepCode()) );
        }
        else {
            throw new EasException("ResponseModel参数为空！",9000);
        }

        return result;
    }

    @Override
    public UserDetailPojo getUserInfo(String token) {

        try {
            // 解析token
            JwtUserPojo jwtUserPojo = jwtManager.decodeJwt(token);
            // 封装成字符以便在redis中查找
            String tokenToRedisKey = loginRedisService.createJwtTokenKey(jwtUserPojo);
            return loginRedisService.loginGetCache(tokenToRedisKey);
        } catch (Exception e) {
            // 处理异常情况
            throw new EasException("Token获取用户信息失败", e);
        }}


    private EasSysUserinfo findAdminByUsername(String username, String password)  {
        EasSysUserinfoExample easSysUserinfoExample = new EasSysUserinfoExample();
        easSysUserinfoExample.createCriteria().andUsernameEqualTo(username);
        List<EasSysUserinfo> adminList = easSysUserinfoMapper.selectByExample(easSysUserinfoExample);

        // 使用Optional简化判断
        Optional<EasSysUserinfo> optionalAdmin = adminList.stream().findFirst();

        if (optionalAdmin.isEmpty()) {
            throw new EasException("用户不存在", 9902);
        }
        if (adminList.size() > 1) {
            throw new EasException("用户数据异常", 9902);
        }

        EasSysUserinfo easSysUserinfo = optionalAdmin.get();

        // 验证密码 这个方法里面有解密 如果解密失败会抛出异常
        validatePassword(password, easSysUserinfo.getPasswd());

        return easSysUserinfo;
    }


    private void validatePassword(String inputPassword, String encryptedPassword){
        String decryptedPassword = passwordManager.decryptPassword(inputPassword);
        System.out.println("前端解密来的decryptedPassword: " + decryptedPassword);
        System.out.println("数据库查到的密码easSysUserinfo.getPasswd(): " + encryptedPassword);
        if (!passwordEncoder.matches(decryptedPassword, encryptedPassword)) {
            throw new EasException("密码不正确", 9901);
        }
    }
}
