package com.kxs.user.api.feign.config;

import cn.hutool.core.text.CharSequenceUtil;
import com.kxs.common.core.constant.ServiceNameConstants;
import com.kxs.user.api.feign.RemoteKxsUserService;
import io.seata.core.context.RootContext;
import jakarta.servlet.http.HttpServletRequest;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.cloud.client.loadbalancer.reactive.ReactorLoadBalancerExchangeFilterFunction;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpHeaders;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import org.springframework.web.reactive.function.client.ClientRequest;
import org.springframework.web.reactive.function.client.WebClient;
import org.springframework.web.reactive.function.client.support.WebClientAdapter;
import org.springframework.web.service.invoker.HttpServiceProxyFactory;

/**
 * <p>
 * 当前服务的webClient配置
 * 服务下的远程调用统一在此配置
 * 使用注册中心 需配置远程调用器 以实现负载均衡
 * </p>
 *
 * @author 没秃顶的码农
 * @date 2023/11/13
 */
@Configuration
@RequiredArgsConstructor
public class KxsUserFeignClientConfiguration {

	/**
	 * 负载均衡器
	 */
	private final ReactorLoadBalancerExchangeFilterFunction reactorLoadBalancerExchangeFilterFunction;

	private static final String SERVICE_NAME = ServiceNameConstants.CLIENT_NAME + ServiceNameConstants.USER_SERVICE;

	@Bean("kxsUserFeignClient")
	public WebClient oauthRequestInterceptor() {

		return WebClient.builder()
			// 给请求添加过滤器，添加自定义的认证头
			.filter((request, next) -> {
				ClientRequest.Builder filtered = ClientRequest.from(request);

				// seata XID传递
				String xid = RootContext.getXID();
				if (CharSequenceUtil.isNotBlank(xid)) {
					filtered.header(RootContext.KEY_XID, xid);
				}

				ServletRequestAttributes requestAttributes = (ServletRequestAttributes) RequestContextHolder
					.getRequestAttributes();
				// 不是web请求不传递token
				if (requestAttributes != null) {
					HttpServletRequest httpServletRequest = requestAttributes.getRequest();
					String token = httpServletRequest.getHeader(HttpHeaders.AUTHORIZATION);
					if (!CharSequenceUtil.isBlank(token)) {
						// 传递token
						filtered.header(HttpHeaders.AUTHORIZATION, token);
					}
				}
				return next.exchange(filtered.build());
			}).filter(reactorLoadBalancerExchangeFilterFunction)
			.baseUrl(SERVICE_NAME)
			.build();
	}

	/**
	 * 远程日志服务
	 * @param client 客户端
	 * @return 远程日志服务
	 */
	@Bean
	RemoteKxsUserService remoteKxsUserService(@Qualifier("kxsUserFeignClient") WebClient client) {
		HttpServiceProxyFactory factory = HttpServiceProxyFactory.builder(WebClientAdapter.forClient(client)).build();
		return factory.createClient(RemoteKxsUserService.class);
	}

}
