package com.seer.teach.common.config.feign;

import cn.dev33.satoken.stp.StpUtil;
import com.seer.teach.common.exception.RemoteCallException;
import feign.*;
import feign.codec.ErrorDecoder;
import lombok.extern.slf4j.Slf4j;
import okhttp3.*;
import okhttp3.Request;
import org.springframework.cloud.openfeign.EnableFeignClients;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.io.File;
import java.util.concurrent.TimeUnit;

/**
 * <p>
 * OpenFeign配置类
 * </p>
 *
 * @author Captain
 * @since 2025-07-15 13:56
 */
@Slf4j
@Configuration
@EnableFeignClients
public class FeignConfig {
    @Bean
    public Retryer retryer() {
        return new Retryer.Default(100, 1000, 3);
    }

    @Bean
    public ErrorDecoder errorDecoder() {
        return (methodKey, response) -> new RemoteCallException(
                response.status(), response.reason());
    }

    @Bean("okHttpClient")
    public okhttp3.OkHttpClient httpClient() {
        // 创建连接池
        ConnectionPool connectionPool = new ConnectionPool(20, 5, TimeUnit.MINUTES);

        // 创建缓存
        Cache cache = new Cache(new File("http_cache"), 50 * 1024 * 1024);


        return new OkHttpClient.Builder()
                .connectTimeout(30, TimeUnit.SECONDS)
                .readTimeout(30, TimeUnit.SECONDS)
                .writeTimeout(30, TimeUnit.SECONDS)
                .connectionPool(connectionPool)
                .cache(cache)
                .addInterceptor(tokenInterceptor())
                .retryOnConnectionFailure(true) // 自动重试失败连接
                .followRedirects(true)         // 跟随重定向
                .followSslRedirects(true) // 跟随SSL重定向
                .build();
    }

    private Interceptor tokenInterceptor() {
        return chain -> {
            Request originalRequest = chain.request();
            if(StpUtil.isLogin()){
                Request newRequest = originalRequest.newBuilder()
                        .header(StpUtil.getTokenName(), StpUtil.getTokenValue())
                        .build();
                return chain.proceed(newRequest);
            }
            return chain.proceed(originalRequest);
        };

    }


    @Bean
    public Logger feignLogger() {
        return new FeignFullLogger();
    }

    @Bean
    public Logger.Level feignLoggerLevel() {
        return Logger.Level.FULL;
    }

}