package com.ruoyi.jarvis.util;

import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.net.HttpURLConnection;
import java.net.URL;
import java.nio.charset.StandardCharsets;

/**
 * WPS365 API工具类
 * 
 * @author system
 */
public class WPS365ApiUtil {
    
    private static final Logger log = LoggerFactory.getLogger(WPS365ApiUtil.class);
    
    // 静态初始化块：禁用系统代理
    static {
        System.setProperty("java.net.useSystemProxies", "false");
        System.clearProperty("http.proxyHost");
        System.clearProperty("http.proxyPort");
        System.clearProperty("https.proxyHost");
        System.clearProperty("https.proxyPort");
        log.info("已禁用系统代理设置，WPS365 API将直接连接");
    }
    
    /**
     * 获取访问令牌
     * 
     * @param appId 应用ID
     * @param appKey 应用密钥
     * @param code 授权码
     * @param redirectUri 回调地址
     * @param tokenUrl Token地址
     * @return 包含access_token和refresh_token的JSON对象
     */
    public static JSONObject getAccessToken(String appId, String appKey, String code, String redirectUri, String tokenUrl) {
        try {
            // 构建请求参数
            StringBuilder params = new StringBuilder();
            params.append("grant_type=authorization_code");
            params.append("&client_id=").append(appId);
            params.append("&client_secret=").append(appKey);
            params.append("&code=").append(code);
            params.append("&redirect_uri=").append(java.net.URLEncoder.encode(redirectUri, "UTF-8"));
            
            // 使用HttpURLConnection，不使用代理
            URL url = new URL(tokenUrl);
            java.net.Proxy proxy = java.net.Proxy.NO_PROXY;
            HttpURLConnection conn = (HttpURLConnection) url.openConnection(proxy);
            conn.setRequestMethod("POST");
            conn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
            conn.setRequestProperty("Accept", "application/json");
            conn.setDoOutput(true);
            conn.setDoInput(true);
            conn.setConnectTimeout(10000);
            conn.setReadTimeout(30000);
            
            // 写入请求参数
            try (OutputStream os = conn.getOutputStream();
                 OutputStreamWriter osw = new OutputStreamWriter(os, StandardCharsets.UTF_8)) {
                osw.write(params.toString());
                osw.flush();
            }
            
            // 读取响应
            int statusCode = conn.getResponseCode();
            BufferedReader reader;
            if (statusCode >= 200 && statusCode < 300) {
                reader = new BufferedReader(new InputStreamReader(conn.getInputStream(), StandardCharsets.UTF_8));
            } else {
                reader = new BufferedReader(new InputStreamReader(conn.getErrorStream(), StandardCharsets.UTF_8));
            }
            
            StringBuilder response = new StringBuilder();
            String line;
            while ((line = reader.readLine()) != null) {
                response.append(line);
            }
            reader.close();
            
            String responseStr = response.toString();
            log.info("获取访问令牌响应: statusCode={}, response={}", statusCode, responseStr);
            
            if (statusCode < 200 || statusCode >= 300) {
                throw new RuntimeException("获取访问令牌失败: HTTP " + statusCode + ", response=" + responseStr);
            }
            
            return JSON.parseObject(responseStr);
        } catch (Exception e) {
            log.error("获取访问令牌失败", e);
            throw new RuntimeException("获取访问令牌失败: " + e.getMessage(), e);
        }
    }
    
    /**
     * 刷新访问令牌
     * 
     * @param appId 应用ID
     * @param appKey 应用密钥
     * @param refreshToken 刷新令牌
     * @param refreshTokenUrl 刷新令牌地址
     * @return 包含新的access_token和refresh_token的JSON对象
     */
    public static JSONObject refreshAccessToken(String appId, String appKey, String refreshToken, String refreshTokenUrl) {
        try {
            // 构建请求参数
            StringBuilder params = new StringBuilder();
            params.append("grant_type=refresh_token");
            params.append("&client_id=").append(appId);
            params.append("&client_secret=").append(appKey);
            params.append("&refresh_token=").append(refreshToken);
            
            // 使用HttpURLConnection，不使用代理
            URL url = new URL(refreshTokenUrl);
            java.net.Proxy proxy = java.net.Proxy.NO_PROXY;
            HttpURLConnection conn = (HttpURLConnection) url.openConnection(proxy);
            conn.setRequestMethod("POST");
            conn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
            conn.setRequestProperty("Accept", "application/json");
            conn.setDoOutput(true);
            conn.setDoInput(true);
            conn.setConnectTimeout(10000);
            conn.setReadTimeout(30000);
            
            // 写入请求参数
            try (OutputStream os = conn.getOutputStream();
                 OutputStreamWriter osw = new OutputStreamWriter(os, StandardCharsets.UTF_8)) {
                osw.write(params.toString());
                osw.flush();
            }
            
            // 读取响应
            int statusCode = conn.getResponseCode();
            StringBuilder response = new StringBuilder();
            
            try {
                BufferedReader reader;
                InputStream inputStream;
                
                if (statusCode >= 200 && statusCode < 300) {
                    inputStream = conn.getInputStream();
                } else {
                    // 对于错误响应，尝试读取错误流
                    inputStream = conn.getErrorStream();
                    // 如果错误流为null，尝试读取正常流（某些服务器可能将错误信息放在正常流中）
                    if (inputStream == null) {
                        inputStream = conn.getInputStream();
                    }
                }
                
                // 如果输入流仍然为null，说明无法读取响应
                if (inputStream == null) {
                    log.warn("无法读取HTTP响应流，状态码: {}", statusCode);
                    response.append("无法读取响应内容");
                } else {
                    reader = new BufferedReader(new InputStreamReader(inputStream, StandardCharsets.UTF_8));
                    String line;
                    while ((line = reader.readLine()) != null) {
                        response.append(line);
                    }
                    reader.close();
                }
            } catch (Exception e) {
                log.error("读取HTTP响应失败", e);
                response.append("读取响应失败: ").append(e.getMessage());
            }
            
            String responseStr = response.toString();
            log.info("刷新访问令牌响应: statusCode={}, response={}", statusCode, responseStr);
            
            if (statusCode < 200 || statusCode >= 300) {
                throw new RuntimeException("刷新访问令牌失败: HTTP " + statusCode + ", response=" + responseStr);
            }
            
            return JSON.parseObject(responseStr);
        } catch (Exception e) {
            log.error("刷新访问令牌失败", e);
            throw new RuntimeException("刷新访问令牌失败: " + e.getMessage(), e);
        }
    }
    
    /**
     * 发送HTTP请求
     * 
     * @param method 请求方法（GET/POST/PUT/DELETE）
     * @param url 请求URL
     * @param accessToken 访问令牌
     * @param body 请求体（JSON字符串，GET请求可为null）
     * @return 响应JSON对象
     */
    public static JSONObject httpRequest(String method, String url, String accessToken, String body) {
        try {
            log.debug("发送HTTP请求: method={}, url={}", method, url);
            
            URL requestUrl = new URL(url);
            java.net.Proxy proxy = java.net.Proxy.NO_PROXY;
            HttpURLConnection conn = (HttpURLConnection) requestUrl.openConnection(proxy);
            conn.setRequestMethod(method);
            conn.setRequestProperty("Accept", "application/json");
            conn.setRequestProperty("Authorization", "Bearer " + accessToken);
            conn.setConnectTimeout(10000);
            conn.setReadTimeout(30000);
            
            if ("POST".equals(method) || "PUT".equals(method) || "PATCH".equals(method)) {
                conn.setRequestProperty("Content-Type", "application/json");
                conn.setDoOutput(true);
                
                if (body != null && !body.isEmpty()) {
                    try (OutputStream os = conn.getOutputStream();
                         OutputStreamWriter osw = new OutputStreamWriter(os, StandardCharsets.UTF_8)) {
                        osw.write(body);
                        osw.flush();
                    }
                }
            }
            
            // 读取响应
            int statusCode = conn.getResponseCode();
            StringBuilder response = new StringBuilder();
            
            try {
                BufferedReader reader;
                InputStream inputStream;
                
                if (statusCode >= 200 && statusCode < 300) {
                    inputStream = conn.getInputStream();
                } else {
                    // 对于错误响应，尝试读取错误流
                    inputStream = conn.getErrorStream();
                    // 如果错误流为null，尝试读取正常流（某些服务器可能将错误信息放在正常流中）
                    if (inputStream == null) {
                        inputStream = conn.getInputStream();
                    }
                }
                
                // 如果输入流仍然为null，说明无法读取响应
                if (inputStream == null) {
                    log.warn("无法读取HTTP响应流，状态码: {}", statusCode);
                    response.append("无法读取响应内容");
                } else {
                    reader = new BufferedReader(new InputStreamReader(inputStream, StandardCharsets.UTF_8));
                    String line;
                    while ((line = reader.readLine()) != null) {
                        response.append(line);
                    }
                    reader.close();
                }
            } catch (Exception e) {
                log.error("读取HTTP响应失败", e);
                response.append("读取响应失败: ").append(e.getMessage());
            }
            
            String responseStr = response.toString();
            log.info("HTTP响应: statusCode={}, url={}, response={}", statusCode, url, responseStr);
            
            if (statusCode < 200 || statusCode >= 300) {
                String errorMsg = String.format("HTTP请求失败: statusCode=%d, url=%s, response=%s", 
                    statusCode, url, responseStr);
                log.error(errorMsg);
                throw new RuntimeException(errorMsg);
            }
            
            if (responseStr == null || responseStr.trim().isEmpty()) {
                return new JSONObject();
            }
            
            return JSON.parseObject(responseStr);
        } catch (Exception e) {
            log.error("HTTP请求失败: method={}, url={}", method, url, e);
            throw new RuntimeException("HTTP请求失败: " + e.getMessage(), e);
        }
    }
}

