package com.friday.custody.api.feignconfig;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.friday.custody.service.basicService.TenantEscrowAuthorizationInfoService;
import com.friday.custody.api.util.GJDFSignGenerator;
import com.friday.custody.dto.TenantEscrowAuthorizationInfoDto;
import com.friday.custody.utils.R;
import feign.Logger;
import feign.RequestInterceptor;
import feign.RequestTemplate;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.io.IOException;
import java.util.*;
import java.util.stream.Collectors;

@Configuration
@Slf4j
public class GJDFConfig {
    @Autowired
    private TenantEscrowAuthorizationInfoService authorizationInfoService;
    String contentType = "application/json";
    @Bean
    Logger.Level feignLoggerLevel() {
        return Logger.Level.BASIC;
    }
    private ObjectMapper objectMapper = new ObjectMapper();
    /**
     * 请求拦截器，加上签名？
     */
    @Bean
    public RequestInterceptor requestInterceptor() {
        return requestTemplate -> {
            Map<String, String> paramMap = generateParam(requestTemplate);
            for (String param : paramMap.keySet()) {
                    requestTemplate.query(param,paramMap.get(param));
            }
            requestTemplate.header("Content-Type","application/json;charset=utf-8");
        };
    }
    Map<String, String> generateParam(RequestTemplate requestTemplate) {
        List<TenantEscrowAuthorizationInfoDto> authInfo = null;
        Map<String, Collection<String>> headers = requestTemplate.headers();
        Map<String, Collection<String>> newHeaders = new HashMap<>();
        //过滤admin，修改Cookie
        for (String s : headers.keySet()) {
            if ("Cookie".equals(s)) {
                List<String> strings = (List<String>) headers.get(s);
                newHeaders.put(s, Collections.singleton("token=" + strings.get(0)));
            } else if (!"admin".equals(s)) {
                newHeaders.put(s, headers.get(s));
            } else {
                List<String> strings = (List<String>) headers.get(s);
                authInfo = getAuthInfo(strings.get(0));
            }

        }
        requestTemplate.headers(null);
        requestTemplate.headers(newHeaders);
        assert authInfo != null;
        TenantEscrowAuthorizationInfoDto tenantEscrowAuthorizationInfoDto = authInfo.get(0);
        Map map;
        try {
            map = objectMapper.readValue(tenantEscrowAuthorizationInfoDto.getAppSecret(), Map.class);
        } catch (JsonProcessingException e) {
            log.error("json parse error",e);
            throw new RuntimeException(e);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
        String appKey = map.get("appKey").toString();
        String appSecret = map.get("appSecret").toString();
        //保存app_key，AppSecret，计算签名

        Map<String, String> signMap = new HashMap<>();
        signMap.put("app_key", appKey);
        signMap.put("AppSecret", appSecret);
        //获取url，计算签名
        String url = requestTemplate.url();
        if (url.contains("?")) {
            url = url.substring(0, url.indexOf("?"));
        }
        //获取请求方法，计算签名
        String method = requestTemplate.method();
        //获取请求体，计算签名
        String requestBody = new String(requestTemplate.body());
        //获取签名
        return GJDFSignGenerator.getSignatureMap(url, method, signMap, contentType,
                requestBody, false);
    }

    /**
     * 根据admin获取授权
     * @param admin
     */
    private List<TenantEscrowAuthorizationInfoDto> getAuthInfo(String admin){
        R<List<TenantEscrowAuthorizationInfoDto>> list = authorizationInfoService.queryAuthorizations();
        List<TenantEscrowAuthorizationInfoDto> data = list.getData();
        return data.stream().filter(t -> t.getTrustNo().equals("98") && t.getVersion().equals("api") && t.getTenantName().equals(admin)).collect(Collectors.toList());
    }

}
