package quant.rich.emoney.entity.config;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.Proxy;
import java.util.concurrent.TimeUnit;

import com.fasterxml.jackson.annotation.JsonIgnore;

import lombok.Data;
import lombok.experimental.Accessors;
import lombok.extern.slf4j.Slf4j;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
import quant.rich.emoney.client.OkHttpClientProvider;
import quant.rich.emoney.interceptor.EnumOptionsInterceptor.EnumOptions;
import quant.rich.emoney.interfaces.ConfigInfo;
import quant.rich.emoney.interfaces.IConfig;
import quant.rich.emoney.validator.ProxyConfigValid;

/**
 * 独立出来一个代理设置的原因是后续可能需要做一个代理池，这样的话独立配置比较适合后续扩展
 */
@Data
@Accessors(chain = true)
@Slf4j
@ProxyConfigValid
@ConfigInfo(field = "proxy", name = "代理设置", initDefault = true)
public class ProxyConfig implements IConfig<ProxyConfig> {
    
    /**
     * 代理类型
     */
    @EnumOptions("ProxyTypeEnum")
    private Proxy.Type proxyType = Proxy.Type.DIRECT;
    
    /**
     * 代理主机
     */
    private String proxyHost = "";
    
    /**
     * 代理端口
     */
    private Integer proxyPort = 1;
    
    /**
     * 是否忽略 HTTPS 证书校验
     */
    private Boolean ignoreHttpsVerification = false;
    
    public void afterBeanInit() {
        
    }
    
    
    public ProxyConfig() {}
    
    /**
     * 根据配置获取代理
     * @return
     */
    @JsonIgnore
    public Proxy getProxy() {
        if (getProxyType() != null && getProxyType() != Proxy.Type.DIRECT) {
            return new Proxy(getProxyType(), 
                    new InetSocketAddress(getProxyHost(), getProxyPort()));
        }
        return Proxy.NO_PROXY;
    }
    
    /**
     * 测试给定的 HTTP 代理是否有效，并验证是否真的走了代理。
     * @param proxy 代理
     * @param ignoreHttpsVerification 是否忽略 https 证书验证
     * @return 是否有效
     */
    public static boolean isProxyEffective(Proxy proxy, boolean ignoreHttpsVerification) {
        synchronized (ProxyConfig.class) {
            
            // OkHttp 客户端配置
            OkHttpClient client = OkHttpClientProvider.getInstance(
                    proxy, ignoreHttpsVerification,
                    builder -> builder
                        .connectTimeout(10, TimeUnit.SECONDS)
                        .readTimeout(10, TimeUnit.SECONDS));
    
            // 使用 httpbin.org/ip 获取当前请求的公网 IP
            Request request = new Request.Builder()
                    .url("https://httpbin.org/ip")
                    .header("User-Agent", "ProxyVerifier")
                    .build();
    
            try (Response response = client.newCall(request).execute()) {
                if (!response.isSuccessful()) {
                    System.out.println("Request failed with code: " + response.code());
                    return false;
                }
    
                String responseBody = response.body().string();
                System.out.println("Response from proxy: " + responseBody);
    
                // 可在此根据 IP 做进一步验证，例如是否与本地 IP 不同
                return true;
            } catch (IOException e) {
                System.out.println("Proxy error: " + e.getMessage());
                return false;
            }
        }
    }
    
    public static void main(String[] args) {
        String proxyIp = "127.0.0.1";
        int proxyPort = 7897;

        boolean result = isProxyEffective(
            new Proxy(Proxy.Type.SOCKS, new InetSocketAddress(proxyIp, proxyPort)), true);
        System.out.println("Proxy is usable: " + result);
    }
    
}
