package com.thinkunion.smart.park.core.gateway.filter;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.thinkunion.smart.park.core.gateway.provider.RequestProvider;
import com.thinkunion.smart.park.core.gateway.provider.ResponseProvider;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
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.data.redis.core.RedisTemplate;
import org.springframework.http.HttpStatus;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.stereotype.Component;
import org.springframework.util.AntPathMatcher;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;

import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.List;


@Slf4j
@Component
@AllArgsConstructor
public class MiniProgramAuthFilter implements GlobalFilter, Ordered {
	@Autowired
	private RedisTemplate<String,String> redisTemplate;
	private final ObjectMapper objectMapper;
	private final AntPathMatcher antPathMatcher = new AntPathMatcher();
	private static final List<String> DEFAULT_SKIP_URL = new ArrayList<>();
	static {
		//****原本的接口暂时不走登录校验
		//consumer相关接口
		DEFAULT_SKIP_URL.add("/saas-consumer/invoice/**");
		DEFAULT_SKIP_URL.add("/saas-consumer/parking/**");
		DEFAULT_SKIP_URL.add("/saas-consumer/people/**");
		DEFAULT_SKIP_URL.add("/saas-consumer/RegisterPlate/**");
		DEFAULT_SKIP_URL.add("/saas-consumer/mail/**");
		DEFAULT_SKIP_URL.add("/saas-consumer/test/**");
		DEFAULT_SKIP_URL.add("/saas-consumer/uploadImg/**");
		DEFAULT_SKIP_URL.add("/saas-consumer/vehicle/**");
		DEFAULT_SKIP_URL.add("/saas-consumer/visitor/**");
		DEFAULT_SKIP_URL.add("/saas-consumer/tempMessage/**");
		DEFAULT_SKIP_URL.add("/saas-consumer/order/pay/**");

		//支付相关接口
		DEFAULT_SKIP_URL.add("/saas-payment/pay/**");
		DEFAULT_SKIP_URL.add("/saas-payment/test/**");

		//访客相关接口
		DEFAULT_SKIP_URL.add("/saas-visitor/hikIsc/**");
		DEFAULT_SKIP_URL.add("/saas-visitor/visitor/**");

		//**新接口
		DEFAULT_SKIP_URL.add("/saas-consumer/wechat/auth/**");//登录相关接口不走校验
		DEFAULT_SKIP_URL.add("/saas-consumer/v2/api-docs/**");//swagger接口不走校验
	}
	private static final List<String> DEFAULT_VERIFICATION_URL = new ArrayList<>();
	static {
		DEFAULT_VERIFICATION_URL.add("/mini-program/**");//小程序接口走token校验
	}

	private boolean isVerification(String path) {
		return DEFAULT_VERIFICATION_URL.stream().anyMatch(pattern -> antPathMatcher.match(pattern, path));
	}
	private boolean isSkip(String path) {
		return DEFAULT_SKIP_URL.stream().anyMatch(pattern -> antPathMatcher.match(pattern, path));
	}


	@Override
	public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
//		//校验 Token 放行
//		String originalRequestUrl = RequestProvider.getOriginalRequestUrl(exchange);
//		String path = exchange.getRequest().getURI().getPath();
//
//		if(isVerification(path)||isVerification(originalRequestUrl)){
//			if(isSkip(path)||isSkip(originalRequestUrl)){
//				return chain.filter(exchange);
//			}else{
//				log.info("originalRequestUrl:{},path:{}",originalRequestUrl,path);
//			}
//		}else {
//			return chain.filter(exchange);
//		}
//
//		//校验 Token 合法性
//		ServerHttpResponse resp = exchange.getResponse();
//		String headerToken = exchange.getRequest().getHeaders().getFirst("Authorization");
//		if (StringUtils.isBlank(headerToken)) {
//			return unAuth(resp, "缺失令牌,鉴权失败");
//		}
//
//		String json=redisTemplate.opsForValue().get("wechat:login:"+headerToken);
//		if(StringUtils.isBlank(json)){
//			return unAuth(resp, "缺失令牌,鉴权失败");
//		}


		return chain.filter(exchange);
	}

	private Mono<Void> unAuth(ServerHttpResponse resp, String msg) {
		resp.setStatusCode(HttpStatus.UNAUTHORIZED);
		resp.getHeaders().add("Content-Type", "application/json;charset=UTF-8");
		String result = "";
		try {
			result = objectMapper.writeValueAsString(ResponseProvider.unAuth(msg));
		} catch (JsonProcessingException e) {
			log.error(e.getMessage(), e);
		}
		DataBuffer buffer = resp.bufferFactory().wrap(result.getBytes(StandardCharsets.UTF_8));
		return resp.writeWith(Flux.just(buffer));
	}


	@Override
	public int getOrder() {
		return -100;
	}

}
