package com.koobietech.eas.service.impl;

import com.anji.captcha.model.common.ResponseModel;
import com.koobietech.eas.common.constant.UserType;
import com.koobietech.eas.common.exception.EasException;
import com.koobietech.eas.common.pojo.JwtUserDto;
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.AdminPojo;
import com.koobietech.eas.dao.adminLoginPojo.UserDetail;
import com.koobietech.eas.dao.dto.LoginToken;
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.AdminLoginService;
import com.koobietech.eas.service.LoginRedisService;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;

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

@Service
public class AdminLoginServiceImpl implements AdminLoginService {

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

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

    @Override
    public LoginToken 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里面
        UserDetail userDetailInRedis = adminLoginMapper.getUserDetailById(id);
        System.out.println("接收前" + userDetailInRedis);
        userDetailInRedis.setDepartments(adminLoginMapper.getUserDepartmentsById(id));
        userDetailInRedis.setPermissions(adminLoginMapper.getUserPermissionsById(id));
        System.out.println("接收后" + userDetailInRedis);

            // 先调用自定义sql查询用户详细信息、部门信息 和 权限信息
            UserType userType = UserType.TEACHER;
            if (userDetailInRedis.getUsername().equals("admin")) {
                userType = UserType.ADMIN;
            }

            // 生成token
            JwtUserDto jwtUserDto = new JwtUserDto(userDetailInRedis.getUsername(), userDetailInRedis.getId(), userType);
            String token = jwtManager.createJwt(jwtUserDto, token_expires);
            String refreshToken = jwtManager.createJwt(jwtUserDto, refreshToken_expires);
            System.out.println("token:" + token);
            System.out.println("refreshToken:" + refreshToken);

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

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

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

    @Override
    public LoginToken refreshToken(String refreshToken) {
        // 解析refresh token
        JwtUserDto jwtUserDto = jwtManager.decodeJwt(refreshToken);

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

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

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

        // 更新Redis中的token和refresh token
        loginRedisService.loginSaveCache(newRedisTokenKey, userDetailInRedis, token_expires);
        loginRedisService.loginSaveCache(newRedisRefreshTokenKey, userDetailInRedis, refreshToken_expires);
        return new LoginToken(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 UserDetail getUserInfo(String token) {

        try {
            // 解析token
            JwtUserDto jwtUserDto = jwtManager.decodeJwt(token);
            // 封装成字符以便在redis中查找
            String tokenToRedisKey = loginRedisService.createJwtTokenKey(jwtUserDto);
            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);
        }
    }
}
