package com.jeeplus.centerservice.utils;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.extra.spring.SpringUtil;
import com.alibaba.fastjson.JSONObject;
import com.jeeplus.common.TokenProvider;
import com.jeeplus.sys.feign.IUserApi;
import com.jeeplus.sys.service.dto.UserDTO;


import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.methods.PostMethod;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.*;
import org.springframework.stereotype.Component;
import org.springframework.web.client.RestTemplate;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.nio.charset.Charset;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
import java.util.StringTokenizer;

@Component
public class RestTemplateService {

    @Autowired
    private RestTemplate restTemplate;

    /**
     * 访问get接口 - CAS 系统
     * @param path 接口路径
     * @param token token
     * @param paramMap 请求参数-路径后
     * @return
     */
    public Object getCas(String path, String token, Map<String, Object> paramMap) {
        return httpRequest(HttpMethod.GET, token, paramMap, null, Global.getConfig("CAS_PATH"), path,"cas");
    }

    /**
     * 访问post接口 - CCPM 系统
     * @param path 接口路径
     * @param token token
     * @param paramMap 请求参数-路径后
     * @param bodyMap 请求参数-请求体
     * @return
     */
    public Object postCCPM(String path, String token, Map<String, Object> paramMap, Map<String, Object> bodyMap) {
        return httpRequest(HttpMethod.POST, token, paramMap, bodyMap, Global.getConfig("CCPM_PATH"), path, "ccpm");
    }

    /**
     * 访问get接口 - CCPM 系统
     * @param path 接口路径
     * @param token token
     * @param paramMap 请求参数-路径后
     * @return
     */
    public Object getCCPM(String path, String token, Map<String, Object> paramMap) {
        return httpRequest(HttpMethod.GET, token, paramMap, null, Global.getConfig("CCPM_PATH"), path,"ccpm");
    }

    /**
     * 访问get接口 - CCPM 系统
     * @param path 接口路径
     * @param token token
     * @param paramMap 请求参数-路径后
     * @return
     */
    public Object getCCPMMultithreading(String path, String token, Map<String, Object> paramMap, UserDTO userDTO) {
        return httpRequestMultithreading(HttpMethod.GET, token, paramMap, null, Global.getConfig("CCPM_PATH"), path,"ccpm",userDTO);
    }

    /**
     * 访问远程接口方法
     * @param method 请求类型
     * @param token token
     * @param paramMap 请求参数-路径后
     * @param bodyMap 请求参数-请求体
     * @param hostAddress 服务host地址
     * @param path 接口路径
     * @param flag 接口路径
     * @return
     */
    public Object httpRequest(HttpMethod method, String token, Map<String, Object> paramMap, Map<String, Object> bodyMap, String hostAddress, String path, String flag) {
        Object res = null;
        //获取当前登陆人的信息
        UserDTO currentUserDTO = SpringUtil.getBean(IUserApi.class).getByToken(TokenProvider.getCurrentToken());
        try {
            JSONObject jsonObject = new JSONObject();
            if (CollectionUtil.isNotEmpty(bodyMap)) {
                jsonObject = new JSONObject(bodyMap); // 另一端接口需要使用@RequestBody来接收此参数
            }
            String url = getUrl(hostAddress, path, paramMap);
            HttpHeaders httpHeaders = new HttpHeaders();
            if("ccpm".equals(flag)){
                String cookie = ccpmValidatePassword(currentUserDTO);
                httpHeaders.add("cookie", cookie);
            }else{
    //        httpHeaders.add("token",token);
            }
            httpHeaders.add("Accept", MediaType.ALL_VALUE);
            httpHeaders.setContentType(new MediaType("application", "json", Charset.forName("UTF-8")));
            HttpEntity<Object> entity = new HttpEntity<>(jsonObject, httpHeaders);
            ResponseEntity<Object> responseEntity = restTemplate.exchange(url, method, entity, Object.class);
            res = responseEntity.getBody();
        } catch (Exception e) {
            System.out.println("远程调用失败");
            e.printStackTrace();
        }
        return res;
    }

    /**
     * 访问远程接口方法
     * @param method 请求类型
     * @param token token
     * @param paramMap 请求参数-路径后
     * @param bodyMap 请求参数-请求体
     * @param hostAddress 服务host地址
     * @param path 接口路径
     * @param flag 接口路径
     * @return
     */
    public Object httpRequestMultithreading(HttpMethod method, String token, Map<String, Object> paramMap, Map<String, Object> bodyMap, String hostAddress, String path, String flag, UserDTO userDTO) {
        Object res = null;
        try {
            JSONObject jsonObject = new JSONObject();
            if (CollectionUtil.isNotEmpty(bodyMap)) {
                jsonObject = new JSONObject(bodyMap); // 另一端接口需要使用@RequestBody来接收此参数
            }
            String url = getUrl(hostAddress, path, paramMap);
            HttpHeaders httpHeaders = new HttpHeaders();
            if("ccpm".equals(flag)){
                String cookie = ccpmValidatePassword(userDTO);
                httpHeaders.add("cookie", cookie);
            }else{
    //        httpHeaders.add("token",token);
            }
            httpHeaders.add("Accept", MediaType.ALL_VALUE);
            httpHeaders.setContentType(new MediaType("application", "json", Charset.forName("UTF-8")));
            HttpEntity<Object> entity = new HttpEntity<>(jsonObject, httpHeaders);
            ResponseEntity<Object> responseEntity = restTemplate.exchange(url, method, entity, Object.class);
            res = responseEntity.getBody();
        } catch (Exception e) {
            System.out.println("远程调用失败");
            e.printStackTrace();
        }
        return res;
    }

    /**
     * 判定人员信息是否有效
     * @param user
     * @return
     * @throws IOException
     */
    public String ccpmValidatePassword(UserDTO user) {
        StringBuffer response = new StringBuffer();
        //请求地址
        String url = Global.getConfig("CCPM_PATH") + "/a/sys/register/validatePasswordPublic";
        HttpClient client = new HttpClient();
        //post请求方式
        PostMethod postMethod = new PostMethod(url);
        //推荐的数据存储方式,类似key-value形式
        Map telPair = new HashMap();
        telPair.put("loginName",user.getLoginName());
        telPair.put("password", Global.getPublicPassword());
        //封装请求参数
        postMethod.setRequestBody(telPair.toString());
        //这里是设置请求内容为json格式,根据站点的格式决定
        //因为这个网站会将账号密码转为json格式,所以需要这一步
        postMethod.setRequestHeader("Content-Type","application/json; charset=UTF-8;");
        //执行请求
        try {
            client.executeMethod(postMethod);
            // 读取为 InputStream
            BufferedReader reader = new BufferedReader(new InputStreamReader(postMethod.getResponseBodyAsStream()));
            String line;
            while ((line = reader.readLine()) != null) {
                response.append(line);
            }
            reader.close();
        } catch (IOException e) {
            System.out.println("远程调用失败");
        } finally {
            postMethod.releaseConnection();
        }
        if("true".equals(response.toString())){
            String cookie = getCcpmCookie(user);
            return cookie;
        }
        return null;
    }

    /**
     * 获取ccpm登录用户cookie信息
     * @param user
     * @return
     * @throws IOException
     */
    public String getCcpmCookie(UserDTO user) {
        //请求地址
        String url = Global.getConfig("CCPM_PATH") + "/a/login";
        HttpClient client = new HttpClient();
        //post请求方式
        PostMethod postMethod = new PostMethod(url);
        //封装请求参数
        postMethod.setParameter("username",user.getName());
        postMethod.setParameter("password", Global.getPublicPassword());
        //这里是设置请求内容为json格式,根据站点的格式决定
        //因为这个网站会将账号密码转为json格式,所以需要这一步
        postMethod.setRequestHeader("Content-Type","application/x-www-form-urlencoded; charset=UTF-8;");
        //执行请求
        try {
            client.executeMethod(postMethod);
            //通过Post/GetMethod对象获取响应头信息
            String cookies = postMethod.getResponseHeader("Set-Cookie").getValue();
            if(StringUtils.isNotBlank(cookies)){
                StringTokenizer result = new StringTokenizer(cookies,";");   // 实例化对象，并指向以 - 对 a 进行分割
                while(result.hasMoreTokens()){ // 对 result 遍历并打印子字符串；
                    String cookie = result.nextToken();
                    if(StringUtils.isNotBlank(cookie) && cookie.contains("jeeplus.session.id")){
                        return cookie;
                    }
                }
            }
        } catch (IOException e) {
            System.out.println("远程调用失败");
        } finally {
            postMethod.releaseConnection();
        }
        return null;
    }

    /**
     * 将参数拼接到请求路径中
     * @param hostAddress 服务host地址
     * @param path 接口路径
     * @param map 请求参数
     * @return
     */
    public String getUrl(String hostAddress, String path, Map<String, Object> map) {
        String url = hostAddress + path;
        StringBuilder paramStr = new StringBuilder();
        if (CollectionUtil.isNotEmpty(map)) {
            for (String key : map.keySet()) {
                Object o = map.get(key);
                if (Objects.nonNull(o)) {
//                    String value = URLEncoder.encode(o.toString(), "utf-8");
                    paramStr.append("&").append(key).append("=").append(o);
                }
            }
        }
        if (StringUtils.isNotBlank(paramStr.toString())){
            String param = paramStr.substring(1).toString(); // 去掉第一个&
            url = url + "?" + param;
        }
        return url;
    }
}
