package com.mvc.utils;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.mvc.constant.QueryUserType;
import com.mvc.interceptor.JwtInterceptor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.core.io.FileSystemResource;
import org.springframework.http.*;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.io.File;
import java.lang.reflect.Field;
import java.util.Map;

public class HttpUtil {
    private static Logger log = LoggerFactory.getLogger(HttpUtil.class);

    private static RestTemplate restTemplate;

    private static RestTemplate getRestTemplate() {
        if (restTemplate == null) {
            restTemplate = new RestTemplate();
        }
        return restTemplate;
    }

    public static <T> String postData(String url, T model) {
        HttpHeaders headers = new HttpHeaders();
        MediaType type = MediaType.parseMediaType("application/json; charset=UTF-8");
        headers.setContentType(type);
        headers.add("Accept", MediaType.APPLICATION_JSON.toString());

        MultiValueMap<String, Object> map = new LinkedMultiValueMap<String, Object>();
        JSONObject param = new JSONObject();
        try {
            Field[] fields = model.getClass().getDeclaredFields();
            for (int i = 0; i < fields.length; i++) {
                Field f = fields[i];
                f.setAccessible(true);
                Object value = f.get(model);
                if (value != null && !map.containsKey(f.getName())) {
                    map.add(f.getName(), f.get(model));
                    param.put(f.getName(), f.get(model));
                }
            }

            HttpEntity<String> formEntity = new HttpEntity<String>(param.toString(), headers);
            return getRestTemplate().postForObject(url, formEntity, String.class);
        } catch (Exception e) {
            e.printStackTrace();
            log.error(url,e);
        }
        return "";
    }

    /**
     * Post服务侧识别的in参数
     * @param url
     * @param inModel
     * @param file
     * @return
     */
    public static ResponseEntity postInParam(String url, Object inModel, File file) {
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.MULTIPART_FORM_DATA);
        FileSystemResource resource = new FileSystemResource(file);
        MultiValueMap<String, Object> map = new LinkedMultiValueMap<>();
        map.add("file", resource);
        map.add("inJson", JSON.toJSONString(inModel));
        ResponseEntity<String> response= null;

        try {
            HttpEntity<MultiValueMap<String, Object>> entity = new HttpEntity<>(map, headers);
            response = getRestTemplate().postForEntity(url, entity, String.class);
        } catch (Exception ex) {
            log.warn("调用识别服务出错:" + JSON.toJSONString(inModel));
            log.error(ex.getMessage());
        }
        return response;
    }

    /**
     * get方式调用HTTP接口
     * @param url
     * @return
     */
    public static String getForEntity(String url){
        ResponseEntity<String> entity = getRestTemplate().getForEntity(url,String.class);
        if(entity.getStatusCode()==HttpStatus.OK){
            return entity.getBody();
        }
        else {
            System.out.println(entity.getStatusCode());
        }
        return "";
    }

    /**
     * 将对象转换为表单参数
     * @param model
     * @return
     */
    public static MultiValueMap<String, String> convertToFormParams(Object model) {
        MultiValueMap<String, String> params = new LinkedMultiValueMap<>();
        if (model == null) {
            return params; // 如果 model 为 null，返回空的 params
        }

        // 使用 fastjson 将对象转换为 JSONObject
        JSONObject jsonObject = (JSONObject) JSONObject.toJSON(model);

        // 遍历 JSONObject 中的每一个键值对
        for (Map.Entry<String, Object> entry : jsonObject.entrySet()) {
            String key = entry.getKey();
            Object value = entry.getValue();
            if (value != null) {
                params.add(key, value.toString());
            }
        }
        return params;
    }

    /**
     * 获取查询用户类型
     *
     * @return
     */
    public static QueryUserType getQueryUserTypeByRequest() {
        //注意:服务主动调用时,无法获取request(例如定时器)
        if (RequestContextHolder.getRequestAttributes() == null) {
            return null;
        }
        try {
            HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
            QueryUserType queryUserType = JwtInterceptor.getQueryUserTypeByRequest(request);
            return queryUserType;
        } catch (Exception e) {
            return null;
        }
    }
}
