package com.dxhy.auth.service.impl;

import java.util.HashMap;
import java.util.Map;

import javax.annotation.Resource;

import org.apache.commons.lang3.StringUtils;
import org.jasig.cas.client.util.CommonUtils;
import org.jasig.cas.client.util.XmlUtils;
import org.springframework.stereotype.Service;

import com.alibaba.fastjson.JSON;
import com.dxhy.admin.sys.config.AdminConfig;
import com.dxhy.admin.sys.config.SysConfig;
import com.dxhy.admin.sys.service.LoginService;
import com.dxhy.auth.service.AuthService;
import com.dxhy.auth.util.user.JwtTokenUtil;
import com.dxhy.common.constant.RedisConstant;
import com.dxhy.common.jwt.JWTInfo;
import com.dxhy.common.util.redis.RedisUtils;
import com.dxhy.common.vo.JwtAuthenticationRequest;
import com.dxhy.common.vo.UserInfo;

import cn.hutool.http.HttpUtil;
import lombok.extern.slf4j.Slf4j;

/**
 * @author jiaohongyang
 */
@Service("authService")
@Slf4j
public class AuthServiceImpl implements AuthService {
    @Resource
    private JwtTokenUtil jwtTokenUtil;
    @Resource
    private RedisUtils redisUtils;
    @Resource
    private LoginService loginService;

    @Override
    public String login(JwtAuthenticationRequest authenticationRequest) throws Exception {
        UserInfo info = loginService.validate(authenticationRequest.getUsername(), authenticationRequest.getPassword());
        if (info == null) {
            return null;
        }
        if (StringUtils.isNotBlank(info.getStatus()) && SysConfig.STATUS.equals(info.getStatus())) {
            return "true";
        }
        if (StringUtils.isNotBlank(info.getId())) {
            String userInfo = JSON.toJSONString(info);
            String generateToken = jwtTokenUtil
                .generateToken(new JWTInfo(userInfo, info.getUsername(), info.getId() + "", info.getLoginname()));
            redisUtils.set(RedisConstant.KEY_TOKEN + info.getLoginname(), generateToken, AdminConfig.expore);
            return generateToken;
        } else {
            return null;
        }
    }

    @Override
    public Map<String, String> casLogin(JwtAuthenticationRequest authenticationRequest) throws Exception {
        log.info("CAS 登录 serviceParam: {}  , ticketParam : {}", authenticationRequest.getService(),
            authenticationRequest.getTicket());

        Map<String, String> map = new HashMap<>();
        String serviceValidateUrl = AdminConfig.validateUrl;
        String response = HttpUtil.get(serviceValidateUrl.replaceAll("serviceParam", authenticationRequest.getService())
            .replaceAll("ticketParam", authenticationRequest.getTicket()));
        log.info("CAS 登录返回信息：{}", response);
        String error = XmlUtils.getTextForElement(response, "authenticationFailure");
        if (CommonUtils.isNotBlank(error)) {
            map.put("code", "9999");
            map.put("message", error);
            return map;
        } else {
            String principal = XmlUtils.getTextForElement(response, "user");
            String email = XmlUtils.getTextForElement(response, "email");
            log.info("获取CAS认证结果,用户信息为：{} ，用户EMAIL为：{}", principal, email);
            UserInfo info = loginService.validateEmail(email);
            if (StringUtils.isNotBlank(info.getId())) {
                String userInfo = JSON.toJSONString(info);
                String generateToken = jwtTokenUtil
                    .generateToken(new JWTInfo(userInfo, info.getUsername(), info.getId() + "", info.getLoginname()));
                redisUtils.set(RedisConstant.KEY_TOKEN + info.getLoginname(), generateToken, AdminConfig.expore);
                map.put("code", "0000");
                map.put("token", generateToken);
                return map;
            } else {
                map.put("code", "0001");
                map.put("token", "");
                return map;
            }
        }
    }

    @Override
    public void validate(String token) throws Exception {
        jwtTokenUtil.getInfoFromToken(token);
    }

    @Override
    public String refresh(String oldToken) throws Exception {
        return jwtTokenUtil.generateToken(jwtTokenUtil.getInfoFromToken(oldToken));
    }
}
