package com.zksy.visualization.config;

import cn.hutool.core.util.StrUtil;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.zksy.visualization.domain.response.AuthResponse;
import com.zksy.visualization.domain.response.PublicKeyResponse;
import com.zksy.visualization.utils.RSAutil;
import lombok.extern.slf4j.Slf4j;
import okhttp3.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;

@Configuration
@Slf4j
public class InitializationService {

    @Autowired
    private IccConfigProperty iccConfigProperty;
    @Autowired
    private OkHttpClient httpClient;
    @Autowired
    private ObjectMapper objectMapper;
    @Autowired
    private RedisTemplate<String,String> redisTemplate;

    @PostConstruct
    public void initialize() throws Exception {
        String publicKey = retrievePublicKey();
        log.info("Public Key: {}", publicKey);

        // RSA 加密
        String encryptedPassword = RSAutil.encrypt(iccConfigProperty.getPassword(), publicKey);
        iccConfigProperty.setEncryptedText(encryptedPassword);

        if (StrUtil.isNotBlank(publicKey)) {
            log.info("获取秘钥成功");

            // 构建请求体
            Map<String, Object> jsonMap = new HashMap<>();
            jsonMap.put("grant_type", "password");
            jsonMap.put("username", iccConfigProperty.getUsername());
            jsonMap.put("password", iccConfigProperty.getEncryptedText());
            jsonMap.put("client_id", iccConfigProperty.getClientId());
            jsonMap.put("client_secret", iccConfigProperty.getClientSecret());
            jsonMap.put("public_key", publicKey);

            String jsonBody;
            try {
                jsonBody = objectMapper.writeValueAsString(jsonMap);
            } catch (JsonProcessingException e) {
                log.error("JSON 处理异常", e);
                return;
            }

            // 构建请求
            MediaType mediaType = MediaType.parse("application/json; charset=utf-8");
            RequestBody requestBody = RequestBody.create(mediaType, jsonBody);
            Request request1 = new Request.Builder()
                    .url("https://" + iccConfigProperty.getHost() + "/evo-apigw/evo-oauth/1.0.0/oauth/extend/token")
                    .post(requestBody)
                    .build();

            Response response;
            try {
                response = httpClient.newCall(request1).execute();
                if (!response.isSuccessful()) {
                    log.error("请求失败: {}", response.code());
                }
                if (response.body() != null) {
                    String responseBody = response.body().string();
                    log.info("Response Body: {}", responseBody);
                    ObjectMapper objectMapper = new ObjectMapper();
                    try {
                        AuthResponse authResponse = objectMapper.readValue(responseBody, AuthResponse.class);
                        redisTemplate.opsForValue().set("Authorization:"+iccConfigProperty.getUsername(),authResponse.getData().getTokenType()+" " + authResponse.getData().getAccessToken());
                        redisTemplate.opsForValue().set("refresh_token:"+iccConfigProperty.getUsername(), authResponse.getData().getRefreshToken());
                    } catch (IOException e) {
                        log.error("请求失败:{}",e);
                    }
                }
            } catch (IOException e) {
                log.error("请求失败: {}", e);
            }
        }
    }

    private String retrievePublicKey() {
        for (int attempt = 1; attempt <= 3; attempt++) {
            String publicKey = getPublicKey(httpClient);
            if (StrUtil.isNotBlank(publicKey)) {
                return publicKey;
            } else {
                log.warn("公钥获取失败将于 {} 秒后. 重试 {}/{}", TimeUnit.MILLISECONDS.toSeconds(5000), attempt, 3);
                try {
                    Thread.sleep(5000); // 等待 5 秒钟
                } catch (InterruptedException e) {
                    Thread.currentThread().interrupt();
                    log.error("出现干扰异常", e);
                    break;
                }
            }
        }
        log.error("获取公钥失败超过重试次数 3 .");
        throw new RuntimeException("获取公钥失败超过最大重试次数");
    }

    private String getPublicKey(OkHttpClient httpClient) {
        // 获取公钥
        String publicKey = "";
        try {
            Request request = new Request.Builder()
                    .url("https://" + iccConfigProperty.getHost() + "/evo-apigw/evo-oauth/1.0.0/oauth/public-key")
                    .build();
            Response response = httpClient.newCall(request).execute();
            if (response.isSuccessful() && response.body() != null) {
                PublicKeyResponse res = objectMapper.readValue(response.body().string(), PublicKeyResponse.class);
                if (res.getSuccess()) {
                    publicKey = res.getData().getPublicKey();
                } else {
                    log.error("信息: {}", res.getErrMsg());
                    throw new Exception("获取公钥失败");
                }
            } else {
                log.error("获取公钥失败: {}", response.code());
                throw new Exception("获取公钥失败");
            }
        } catch (Exception e) {
            log.error("信息: {}", e);
        }
        return publicKey;
    }
}
