package im.zhaojun.system.service;

import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.http.*;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;

import javax.annotation.PostConstruct;
import java.lang.reflect.Type;
import java.util.Map;
import java.util.concurrent.TimeUnit;

@Service
@Slf4j
public class QingZhiLoginCacheService {

    @Autowired
    private StringRedisTemplate stringRedisTemplate;

    @Value("${qingzhi.redis.token}")
    private String qztoken;

    @Value("${qingzhi.login.username}")
    private String username;

    @Value("${qingzhi.login.password}")
    private String password;

    @Value("${qingzhi.login.url}")
    private String url;

    @Value("${qingzhi.login.keepaliveurl}")
    private String keepaliveurl;

    @PostConstruct
    public void printConfig(){
        log.info("config params:"+ "redis key:" + qztoken +" ,username:"+username+ " ,password:"+password+ " ,url:"+url+ " ,keepaliveurl:"+keepaliveurl);
    }

    public String   keepAlive() {
        String token=null;
        try {
            String tokencache = stringRedisTemplate.opsForValue().get(qztoken);
            if (tokencache != null) {
                token= doKeepAlive(tokencache);
            } else {
                tokencache = loginServer(url, username, password);
                if (tokencache != null) {
                    token=doKeepAlive(tokencache);
                }
            }
        } catch (Exception e) {
            System.out.println(e.toString());
            log.error(e.getMessage());
        }
        return token;
    }

    private String  doKeepAlive(String token) {
        HttpHeaders headers = getHttpHeaders();
        headers.add("token",token);
        HttpEntity<String> requestEntity = new HttpEntity<>(null, headers);
        RestTemplate client = new RestTemplate();
        ResponseEntity<String> request = client.exchange((keepaliveurl+"?token="+token), HttpMethod.GET, requestEntity, String.class);
        String newToken = getTokenData(request);
        if (newToken != null) {
//            log.info("doKeepAlive response " + request.getBody());
            stringRedisTemplate.opsForValue().set(qztoken, newToken, 2, TimeUnit.MINUTES);
        } else {
            log.error("doKeepAlive response " + "empty...");
        }
        return newToken;
    }

    private String loginServer(String url, String username, String password) {
        HttpHeaders headers = getHttpHeaders();
        headers.setContentType(MediaType.APPLICATION_JSON_UTF8);
        RestTemplate client = new RestTemplate();
        ResponseEntity<String> response = client.getForEntity((url+"?username="+username+"&password="+password),String.class);
        return getTokenData(response);
    }

    private HttpHeaders getHttpHeaders() {
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_JSON_UTF8);
        return headers;
    }
    private String getTokenData(ResponseEntity<String> response){
        try {
            if (response != null && response.getBody() != null && response.getBody().contains("status")) {
                String ret = response.getBody();
                Gson gson = new Gson();
                Type stringStringMap = new TypeToken<Map<String, String>>() {
                }.getType();
                Map<String, String> map = gson.fromJson(ret, stringStringMap);
                if (map != null && map.get("data").length() > 10 && Integer.parseInt(map.get("status")) ==200) {
                    return map.get("data");
                } else {
                    log.error("getTokenData error :" + response.getBody());
                }
            } else {
                log.error("getTokenData empty...");
            }
        }catch (Exception e){
            System.out.println(e.toString());
            log.error(e.getMessage());
        }
        return null;
    }
}
