package com.bjtdba.gateWay.filter;


import cn.hutool.json.JSONObject;
import com.alibaba.fastjson.JSON;
import com.bjtdba.gateWay.redis.RedisUtil;
import com.bjtdba.utils.ResponseUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.core.Ordered;
import org.springframework.core.io.buffer.DataBuffer;
import org.springframework.core.io.buffer.DataBufferUtils;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.http.server.reactive.ServerHttpRequestDecorator;
import org.springframework.stereotype.Component;
import org.springframework.util.AntPathMatcher;
import org.springframework.util.MultiValueMap;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;

import java.net.URI;
import java.nio.charset.StandardCharsets;
import java.util.Collections;
import java.util.List;

@Component
@Slf4j
public class ApiRequestFilter implements GlobalFilter, Ordered {

    @Autowired
    private RedisUtil redisUtil;

    JSONObject jsonObject=new JSONObject();

    private final AntPathMatcher pathMatcher = new AntPathMatcher();

    private static final List<String> EXTERNAL_PATHS = Collections.singletonList(
            "/external/**"
    );

    private boolean isExternalPath(String path) {
        for (String pattern : EXTERNAL_PATHS) {
            if (pathMatcher.match(pattern, path)) {
                return true;
            }
        }
        return false;
    }

    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        ServerHttpRequest request = exchange.getRequest();
        String url = request.getURI().getPath();

        //参数打印

        URI URIPath = request.getURI();
        String path = request.getPath().value();
        String method = request.getMethodValue();
        HttpHeaders header = request.getHeaders();

        // 检查是否为外部API路径
        if (isExternalPath(path)) {
            return chain.filter(exchange); // 跳过当前过滤器
        }

        log.info("***********************************请求信息**********************************");

        jsonObject.set("URI",URIPath);
        jsonObject.set("path",path);
        jsonObject.set("header",header);
        jsonObject.set("method",method);
//        log.info("URI = {}", URIPath);
//        log.info("path = {}", path);
//        log.info("header = {}", header);
//        log.info("method = {}",method);


//        Flux<DataBuffer> dataBufferFlux = request.getBody();
//        log.info(dataBufferFlux.toString());
//        //获取body中的数据
//        String body = FilterRequestResponseUtil.resolveBodyFromRequest(dataBufferFlux);
//        log.info("body:{}",body);


        if(!url.equals("/system_service/sysconfig/queryByKey")){
//            if(request.getMethod() == HttpMethod.GET){
//                // get请求 处理参数
//                return handleGetMethod(exchange, chain, request);
//            }
//
//            if(request.getMethod() == HttpMethod.POST){
////                String body="";
////                ServerHttpRequest httpRequest = this.resRequest(body, request);
////                log.info("body = {}",resolveBodyFromRequest(httpRequest));
//                // post请求 处理参数
////                System.out.println("================="+request.getMethod());
//                return handlePostMethod(exchange, chain, request);
//            }
            return  handleMethod(exchange, chain, request);
        }



        return chain.filter(exchange);
    }





    /**
     * 请求 处理参数
     * @param exchange
     * @param chain
     * @param request
     * @return
     */
    private Mono<Void> handleMethod(ServerWebExchange exchange, GatewayFilterChain chain, ServerHttpRequest request ) {

        HttpHeaders headers =  exchange.getRequest().getHeaders();
//        JSONObject jsonObject1=jsonObject.
        List<String> list = headers.get("X-Token");
        MultiValueMap<String, String> queryParams = request.getQueryParams();
//        log.info("param = {}",queryParams);
        jsonObject.set("param", queryParams);
//        log.info("X-Token = {}",list);
        jsonObject.set("X-Token", list);
        ServerHttpRequest.Builder builder = request.mutate();
        if(list!=null&&list.size()!=0){
            String token=list.get(0);
            //获取redis数据
            if(token!=null&&!token.equals("")) {
                if (!redisUtil.hasKey("java_" + token)) {
                    log.info("用户token过期,token =="+token);
                    return unauthorized(exchange, 40000, "用户token过期");
                }
                String uid = redisUtil.get("java_" + token).toString();
//                log.info("uid = {}",uid);
                jsonObject.set("uid", uid);
                builder.header("uid", uid);
            }
//                if(uid==null||"".equals(uid)){
//                    System.out.println("用户token过期");
//                    return unauthorized(exchange,400,"用户token过期");
//
//                }


            //将jwt token中的用户信息传给服务
//            builder.header(GatewayConstans.X_CLIENT_TOKEN_USER, permissionService.getUserTokenBase64(authentication));
//            return chain.filter(exchange.mutate().request(builder.build()).build());
        }
        long num= headers.getContentLength();
//        log.info("num = {}",num);
        if(num<=0){
//            log.info("body：" );
            jsonObject.set("body", "");
            log.info("requestId_{}={}",request.getId(),jsonObject);
//            log.info("****************************************************************************\n");
            return chain.filter(exchange.mutate().request(builder.build()).build());
        }

        return  DataBufferUtils.join(exchange.getRequest().getBody())
                .flatMap(dataBuffer -> {
                    byte[] bytes = new byte[dataBuffer.readableByteCount()];
                    dataBuffer.read(bytes);
                    String bodyString = new String(bytes, StandardCharsets.UTF_8);
//                    log.info("body：" + bodyString);
                    jsonObject.set("body", bodyString);
                    exchange.getAttributes().put("POST_BODY", bodyString);
                    DataBufferUtils.release(dataBuffer);
                    Flux<DataBuffer> cachedFlux = Flux.defer(() -> {
                        DataBuffer buffer = exchange.getResponse().bufferFactory()
                                .wrap(bytes);
                        return Mono.just(buffer);
                    });
//
                    ServerHttpRequest mutatedRequest = new ServerHttpRequestDecorator(
                            exchange.getRequest()) {
                        @Override
                        public Flux<DataBuffer> getBody() {
                            return cachedFlux;
                        }
                    };
                    log.info("requestId_{}={}",request.getId(),jsonObject);
                    log.info("****************************************************************************\n");
                    return chain.filter(exchange.mutate().request(mutatedRequest).build());
                });


//        return chain.filter(exchange);
    }

    /**
     * post请求 校验参数
     * @param exchange
     * @param chain
     * @param request
     * @return
     */
//    private Mono<Void> handlePostMethod(ServerWebExchange exchange, GatewayFilterChain chain, ServerHttpRequest request){
//
//            HttpHeaders headers =  exchange.getRequest().getHeaders();
////        MediaType contentType = request.getHeaders().getContentType();
//
//            // 请求内容为 application json
//            List<String> list = headers.get("X-Token");
//            log.info("X-Token = {}",list);
//            ServerHttpRequest.Builder builder = request.mutate();
//            if(list!=null&&list.size()!=0){
//                String token=list.get(0);
//                //获取redis数据
//                if(token!=null&&!token.equals("")) {
//                    if (!redisUtil.hasKey("java_" + token)) {
//                        log.info("用户token过期");
//                        return unauthorized(exchange, 400, "用户token过期");
//                    }
//                    String uid = redisUtil.get("java_" + token).toString();
////                if(uid==null||"".equals(uid)){
////                    System.out.println("用户token过期");
////                    return unauthorized(exchange,400,"用户token过期");
////
////                }
//
//                    builder.header("uid", uid);
//                }
//                //将jwt token中的用户信息传给服务
////            builder.header(GatewayConstans.X_CLIENT_TOKEN_USER, permissionService.getUserTokenBase64(authentication));
//
//            }
//            long num= headers.getContentLength();
//            if(num==0){
//                log.info("body：" );
//                log.info("****************************************************************************\n");
//                return chain.filter(exchange.mutate().request(builder.build()).build());
//            }
//
//            return  DataBufferUtils.join(exchange.getRequest().getBody())
//                .flatMap(dataBuffer -> {
//                    byte[] bytes = new byte[dataBuffer.readableByteCount()];
//                    dataBuffer.read(bytes);
//                    String bodyString = new String(bytes, StandardCharsets.UTF_8);
//                    log.info("body：" + bodyString);
//                    exchange.getAttributes().put("POST_BODY", bodyString);
//                    DataBufferUtils.release(dataBuffer);
//                    Flux<DataBuffer> cachedFlux = Flux.defer(() -> {
//                        DataBuffer buffer = exchange.getResponse().bufferFactory()
//                                .wrap(bytes);
//                        return Mono.just(buffer);
//                    });
////
//                    ServerHttpRequest mutatedRequest = new ServerHttpRequestDecorator(
//                            exchange.getRequest()) {
//                        @Override
//                        public Flux<DataBuffer> getBody() {
//                            return cachedFlux;
//                        }
//                    };
//
//                    log.info("****************************************************************************\n");
//                    return chain.filter(exchange.mutate().request(mutatedRequest).build());
//                });
//
////            return chain.filter(exchange);
//
//    }





    /**
     * 网关拒绝，返回401
     *
     * @param msg
     */
    protected Mono<Void> unauthorized(ServerWebExchange serverWebExchange, Integer status,String msg) {
        DataBuffer buffer = serverWebExchange.getResponse()
                .bufferFactory().wrap(JSON.toJSONBytes(ResponseUtil.fail(status,  msg )));
        serverWebExchange.getResponse().getHeaders()
                .add("Content-Type", "application/json;charset=UTF-8");
        serverWebExchange.getResponse().setStatusCode(HttpStatus.OK);
//        log.error("未授权！", msg);
        return serverWebExchange.getResponse().writeWith(Flux.just(buffer));
    }


    @Override
    public int getOrder() {
        return 2;
    }
}

