package com.zkqy.common.utils.http;

import com.zkqy.common.config.bpm.BpmProperties;
import com.zkqy.common.core.domain.AjaxResult;
import com.zkqy.common.utils.SecurityUtils;
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.UnsupportedEncodingException;
import java.lang.reflect.Array;
import java.lang.reflect.Field;
import java.net.URLEncoder;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;


@Component
public class Sending<T> {

    @Autowired
    private BpmProperties bpmProperties;

    // 创建RestTemplate实例
    RestTemplate restTemplate = new RestTemplate();

    /**
     * get请求拼接参数使用
     *
     * @param url 请求接口地址
     * @param obj map类型、实体类型、单个字符作为参数、数组等等
     * @return 拼接参数后的URL
     */
    private String appendParamsToUrl(String url, T obj) {
        if (obj == null) {
            return url;
        }

        if (obj.getClass().isArray()) {
            // 如果是数组类型，处理数组参数
            int length = Array.getLength(obj);
            for (int i = 0; i < length; i++) {
                Object arrayElement = Array.get(obj, i);
                url = appendParamToUrl(url, "param" + i, arrayElement);
            }
        } else if (obj instanceof Map) {
            // 如果是Map类型，处理Map参数
            Map<String, Object> paramMap = (Map<String, Object>) obj;
            for (Map.Entry<String, Object> entry : paramMap.entrySet()) {
                String key = entry.getKey();
                Object value = entry.getValue();
                url = appendParamToUrl(url, key, value);
            }
        } else {
            // 如果是其他类型，假设是实体类型，处理实体参数
            Class<?> clazz = obj.getClass();
            Field[] fields = clazz.getDeclaredFields();
            for (Field field : fields) {
                field.setAccessible(true);
                String fieldName = field.getName();
                try {
                    Object value = field.get(obj);
                    url = appendParamToUrl(url, fieldName, value);
                } catch (IllegalAccessException e) {
                    e.printStackTrace();
                }
            }
        }

        return url;
    }

    private String appendParamToUrl(String url, String key, Object value) {
        if (value != null) {
            try {
                // 对参数进行URL编码
                String encodedKey = URLEncoder.encode(key, "UTF-8");
                String encodedValue = URLEncoder.encode(value.toString(), "UTF-8");

                // 检查URL是否已经包含参数
                if (url.contains("?")) {
                    url += "&" + encodedKey + "=" + encodedValue;
                } else {
                    url += "?" + encodedKey + "=" + encodedValue;
                }
            } catch (UnsupportedEncodingException e) {
                e.printStackTrace();
            }
        }
        return url;
    }


    public ResponseEntity<String> sendCommon(String url, String httpMethod, T param) {
        // 得到当前用户的token  下发流程请求需要携带
        String token = SecurityUtils.getLoginUser().getToken();
        // 设置请求头
        HttpHeaders headers = new HttpHeaders();
        headers.set("Authorization", "XIAFA" + token);
        // 判断请求类型
        if (HttpMethod.GET.name().equalsIgnoreCase(httpMethod)) {
            // 如果是 GET 请求，将参数拼接到 URL 上
            url = appendParamsToUrl(url, param);
        }
        // 将请求体和请求头添加到 HttpEntity
        HttpEntity<Object> requestEntity = new HttpEntity<>(param, headers);
        // 发送请求
        ResponseEntity<String> response = restTemplate.exchange(url, HttpMethod.resolve(httpMethod), requestEntity, String.class);
        // 返回响应
        return response;
    }

    /**
     * 共通get请求，params传参形式
     * @param url 地址
     * @param param
     * @return
     */
    public ResponseEntity<AjaxResult> sendCommonGetParams(String url,T param){

        // 得到当前用户的token  下发流程请求需要携带
        String token = SecurityUtils.getLoginUser().getToken();
        // 设置请求头
        HttpHeaders headers = new HttpHeaders();
        headers.set("Authorization", "XIAFA" + token);
        HttpEntity request = new HttpEntity(headers);
        ResponseEntity<AjaxResult> response = restTemplate.exchange(
                url,
                HttpMethod.GET,
                request,
                AjaxResult.class,
                param
        );
        return response;
    }

    /**
     * 执行流程排产 -> 共通修改
     */
    public ResponseEntity sendCommonUpdate(T param) {
        return this.sendCommon(bpmProperties.formCommonUpdateIp, "PUT", param);
    }

    /**
     * 根据脚本key得到所有异常脚本信息
     */
    public ResponseEntity sendGetScriptInfo(T param) {
        return this.sendCommon(bpmProperties.getNodeScriptsIp, "POST", param);
    }

    /**
     * 共通获取详情接口
     */
    public ResponseEntity sendCommonGetInfo(T param) {
        return this.sendCommon(bpmProperties.formCommonGetInfoIp, "GET", param);
    }

    /**
     * 通过字段类型得到当前租户字典的所有值
     */
    public ResponseEntity sendGetTenantDict(T param) {
        return this.sendCommon(bpmProperties.getTenantDictValIp, "GET", param);
    }

    /**
     * 根据scriptKey获取节点脚本详情接口
     */
    public ResponseEntity sendGetNodeScript(T param) {
        return this.sendCommonGetParams(bpmProperties.getNodeScriptIp,param);
    }

    /**
     * 查看角色下是否存在真实用户接口
     */
    public ResponseEntity sendQueryUserExistsByRoleKey(T param) {
        return this.sendCommonGetParams(bpmProperties.queryUserExistsByRoleKeyIp,param);
    }

    /**
     * 查看一组用户下是否存在真实用户接口
     */
    public ResponseEntity sendQueryUserExistsByUserIds(T param) {
        return this.sendCommonGetParams(bpmProperties.queryUserExistsByUserIdsIp,param);
    }

    /**
     * FORM_共通批量新增接口
     */
    public ResponseEntity sendCommonInsert(T param) {
        return this.sendCommon(bpmProperties.formCommonInsertIp, "POST", param);
    }

    /**
     * 根据fid获取表单详情接口
     */
    public ResponseEntity sendGetFormInfo(T param) {
        return this.sendCommonGetParams(bpmProperties.formGetFormInfoIp,param);
    }

    /**
     * 根据fid获取表格组详情接口
     */
    public ResponseEntity sendGetGroupInfo(T param) {
        return this.sendCommonGetParams(bpmProperties.getFormGetGroupInfoIp(),param);
    }

    /**
     * 获取模板库数据表信息接口
     */
    public ResponseEntity sendQueryTemplateBaseTable(){
        // 得到当前用户的token  下发流程请求需要携带
        String token = SecurityUtils.getLoginUser().getToken();
        // 设置请求头
        HttpHeaders headers = new HttpHeaders();
        headers.set("Authorization", "XIAFA" + token);
        HttpEntity request = new HttpEntity(headers);
        ResponseEntity<AjaxResult> response = restTemplate.exchange(
                bpmProperties.crmQueryTemplateBaseTableIp,
                HttpMethod.GET,
                request,
                AjaxResult.class
        );;
        return response;
    }
}
