package com.ywt.outpatient.service.rpc.handler;

import lombok.extern.slf4j.Slf4j;
import org.apache.http.HttpStatus;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import org.springframework.web.client.RestTemplate;

import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.HashMap;
import java.util.Map;

@Component
@Slf4j
public class RestTemplateHandler {

    private static Logger log = LoggerFactory.getLogger(RestTemplateHandler.class);
    private static String mgCenterApiService = "";

    @Autowired
    private  RestTemplate restTemplate;

    public  Resp httpPost(String serviceName,String path,Map<String, Object> params , Map<String, String> headers)  {
        String url ="";
        try{
            if(!StringUtils.hasText(serviceName)||!StringUtils.hasText(serviceName)){
                log.error("RestTemplateHandler httpPost error,param has null, service:{},path :{}",serviceName,path);
                return new Resp(HttpStatus.SC_SEE_OTHER,"参数异常");
            }

            url = "http://"+serviceName+path;

            HttpHeaders httpHeaders = new HttpHeaders();
            if(!headers.isEmpty()){
                headers.forEach(httpHeaders::add);
            }

            httpHeaders.set("R-Service-Name", serviceName);
            HttpEntity<Map<String, Object>> httpEntity = new HttpEntity<>(params, httpHeaders);
            ResponseEntity<String> result = restTemplate.postForEntity(url,httpEntity,String.class);
            return new Resp(HttpStatus.SC_OK,result.getBody());
        }catch (Exception e){
            log.error("send HTTP error ; url：{},reason:{}",url,e.getMessage(),e);
            return new Resp(HttpStatus.SC_SEE_OTHER,"参数异常");
        }
    }

    public  Resp httpGet(String serviceName,String path,Map<String, String> params , Map<String, String> headers)  {
        String url ="";
        try{
            if(!StringUtils.hasText(serviceName)||!StringUtils.hasText(serviceName)){
                log.error("RestTemplateHandler httpGet error,param has null, service:{},path :{}",serviceName,path);
                return new Resp(HttpStatus.SC_SEE_OTHER,"参数异常");
            }

            url = "http://"+serviceName+path;
            StringBuilder stringBuilder = new StringBuilder();
            if (params != null && params.size() > 0){
                for (Map.Entry<String, String> entry : params.entrySet()){
                    if (entry.getValue() == null || entry.getValue().equals("")){
                        stringBuilder.append(entry.getKey()).append("=");
                        stringBuilder.append("&");
                        continue;
                    }
                    try {
                        stringBuilder.append(entry.getKey()).append("=").append(URLEncoder.encode(entry.getValue(), "utf-8"));
                    } catch (UnsupportedEncodingException e) {
                    }
                    stringBuilder.append("&");
                }
            }
            if (stringBuilder.length() > 0) {
                stringBuilder.replace(stringBuilder.length() - 1, stringBuilder.length() - 1, "&");
            }
            StringBuilder stringBuilder_url = new StringBuilder();
            if (url.contains("?")){
                if (url.endsWith("?")) stringBuilder_url.append(url).append(stringBuilder);
                else if (url.endsWith("&")) stringBuilder_url.append(url).append(stringBuilder);
                else stringBuilder_url.append(url).append("&").append(stringBuilder);
            }else{
                stringBuilder_url.append(url).append("?").append(stringBuilder);
            }


            HttpHeaders httpHeaders = new HttpHeaders();
            if(!headers.isEmpty()){
                headers.forEach(httpHeaders::add);
            }
            httpHeaders.set("R-Service-Name", serviceName);
            HttpEntity entity = new HttpEntity(headers);


            ResponseEntity<String> result = restTemplate.exchange(stringBuilder_url.toString(),HttpMethod.GET,entity,String.class);
            return new Resp(HttpStatus.SC_OK,result.getBody());
        }catch (Exception e){
            log.error("send HTTP error ; url：{},reason:{}",url,e.getMessage(),e);
            return new Resp(HttpStatus.SC_SEE_OTHER,"参数异常");
        }
    }


    public  ByteArrayResp  httpGetBarry(String serviceName,String path,Map<String, String> params , Map<String, String> headers)  {
        StringBuilder stringBuilder_url = new StringBuilder();
        ByteArrayResp resp =  new ByteArrayResp();
        String url = "";
        try{
            if(!StringUtils.hasText(serviceName)||!StringUtils.hasText(serviceName)){
                log.error("RestTemplateHandler httpPost error,param has null, service:{},path :{}",serviceName,path);
                resp.setCode(HttpStatus.SC_SEE_OTHER);
                resp.setContent("param error".getBytes());
            }
            url = "http://"+serviceName+"/"+path;

            StringBuilder stringBuilder = new StringBuilder();
            if (params != null && params.size() > 0){
                for (Map.Entry<String, String> entry : params.entrySet()){
                    if (entry.getValue() == null || entry.getValue().equals("")){
                        stringBuilder.append(entry.getKey()).append("=");
                        stringBuilder.append("&");
                        continue;
                    }
                    try {
                        stringBuilder.append(entry.getKey()).append("=").append(URLEncoder.encode(entry.getValue(), "utf-8"));
                    } catch (UnsupportedEncodingException e) {
                    }
                    stringBuilder.append("&");
                }
            }
            if (stringBuilder.length() > 0) {
                stringBuilder.replace(stringBuilder.length() - 1, stringBuilder.length() - 1, "&");
            }
            if (url.contains("?")){
                if (url.endsWith("?")) stringBuilder_url.append(url).append(stringBuilder);
                else if (url.endsWith("&")) stringBuilder_url.append(url).append(stringBuilder);
                else stringBuilder_url.append(url).append("&").append(stringBuilder);
            }else{
                stringBuilder_url.append(url).append("?").append(stringBuilder);
            }

            HttpHeaders httpHeaders = new HttpHeaders();
            if(!headers.isEmpty()){
                headers.forEach(httpHeaders::add);
            }
            httpHeaders.set("R-Service-Name", serviceName);
            HttpEntity request = new HttpEntity(httpHeaders);

            ResponseEntity<byte[]> result = restTemplate.exchange(stringBuilder_url.toString(), HttpMethod.GET,request,byte[].class,params);
            resp.setCode(HttpStatus.SC_OK);
            resp.setContent(result.getBody());
        }catch (Exception e){
            log.error("send HTTP error ; url：{},reason:{}",stringBuilder_url.toString(),e.getMessage(),e);
            resp.setCode(HttpStatus.SC_SEE_OTHER);
            resp.setContent(null);
        }
        return resp;
    }


    public  Resp httpPostCommon(String serviceName,String path,Map<String, Object> params)  {
        Map<String, String> headers = new HashMap<>(16);
        headers.put("Content-Type", "application/json;charset=UTF-8");
        return this.httpPost(serviceName,path,params,headers);
    }



    public  ByteArrayResp httpGetBarry(String serviceName,String path,Map<String, String> params)  {
        Map<String, String> headers = new HashMap<>(16);
        headers.put("Content-Type", "application/json;charset=UTF-8");
        return this.httpGetBarry(serviceName,path,params,headers);
    }


    public static class Resp {
        public int code;
        public String content;

        public Resp() {
        }

        public Resp(int code,String content) {
            this.code = code ;
            this.content = content ;
        }

        public int getCode() {
            return this.code;
        }

        public void setCode(int code) {
            this.code = code;
        }

        public String getContent() {
            return this.content;
        }

        public void setContent(String content) {
            this.content = content;
        }
    }

    public static class ByteArrayResp {
        public int code;
        public byte[] content;

        public ByteArrayResp() {
        }

        public int getCode() {
            return this.code;
        }

        public void setCode(int code) {
            this.code = code;
        }

        public byte[] getContent() {
            return this.content;
        }

        public void setContent(byte[] content) {
            this.content = content;
        }
    }
}
