package cn.iocoder.yudao.server.service;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.CharsetUtil;
import cn.hutool.core.util.NumberUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.crypto.asymmetric.KeyType;
import cn.hutool.crypto.asymmetric.RSA;
import cn.hutool.http.HttpRequest;
import cn.hutool.json.JSONUtil;
import cn.iocoder.yudao.framework.common.exception.ErrorCode;
import cn.iocoder.yudao.framework.common.exception.ServiceException;
import cn.iocoder.yudao.module.system.oa.E9ApiTokenUtil;
import cn.iocoder.yudao.module.system.oa.SslSkippingRestTemplate;
import cn.iocoder.yudao.server.dal.dataobject.OaNoticeDO;
import cn.iocoder.yudao.server.dal.mysql.OaNoticeMapper;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.google.common.collect.ImmutableMap;
import lombok.Data;
import org.apache.commons.lang3.StringUtils;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.impl.client.LaxRedirectStrategy;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;
import org.springframework.stereotype.Component;
import org.springframework.util.MultiValueMap;
import org.springframework.web.client.RestClientException;
import org.springframework.web.client.RestTemplate;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.stream.Collectors;

@Component
public class PortalOaFlow {
    @Value("${oa.appid}")
    private String appid;
    @Value("${oa.cpk}")
    private String cpk;
    @Value("${oa.register}")
    private String registerUrl;
    @Value("${oa.gettoken}")
    private String tokenUrl;
    @Value("${oa.spk}")
    private String spk;
    @Value("${oa.secrit}")
    private String secrit;

    private static final Map<String,String> SYSTEM_CACHE = new HashMap <>();

    @Autowired
    private OaNoticeMapper oaNoticeMapper;


    // ==================== 新增：每次使用【全新的、无Cookie】的RestTemplate ====================
    private RestTemplate getNewRestTemplateWithoutCookie() {
//        return new RestTemplate(new HttpComponentsClientHttpRequestFactory(
//                HttpClients.custom()
//                        .disableCookieManagement() // 彻底禁用Cookie，不保存、不携带
//                        .setRedirectStrategy(new LaxRedirectStrategy())
//                        .build()
//        ));
        RestTemplate restTemplate = new RestTemplate(new HttpComponentsClientHttpRequestFactory(
                HttpClients.custom()
                        .disableCookieManagement() // 彻底禁用Cookie
                        .setRedirectStrategy(new LaxRedirectStrategy())
                        .build()
        ));
        // 关键：强制响应编码为 UTF-8
        restTemplate.getMessageConverters().stream()
                .filter(converter -> converter instanceof org.springframework.http.converter.StringHttpMessageConverter)
                .forEach(converter -> ((org.springframework.http.converter.StringHttpMessageConverter) converter)
                        .setDefaultCharset(java.nio.charset.StandardCharsets.UTF_8));
        return restTemplate;
    }


    public static Map<String,Object> testRegist(String address){
        //获取当前系统RSA加密的公钥
        RSA rsa = new RSA();
        String publicKey = rsa.getPublicKeyBase64();
        String privateKey = rsa.getPrivateKeyBase64();
        // 客户端RSA私钥
        SYSTEM_CACHE.put("LOCAL_PRIVATE_KEY",privateKey);
        // 客户端RSA公钥
        SYSTEM_CACHE.put("LOCAL_PUBLIC_KEY",publicKey);
        //调用ECOLOGY系统接口进行注册
        String data = HttpRequest.post(address + "/api/ec/dev/auth/regist")
                .header("appid", "TW")
                .header("cpk","MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEApmtQUp9M82/z22P7am5owQCknjQnjF4U4ckEh7XVtJVQZrZx7d1lCPfoYrwOKEM4DEV7khW6++4Zv5caJ/9nqPn4QFwCqJWVmCEm9vC1BA6i2yfa4bmTxdR1/oeU/Af9pDFlvv5GC9XyilO7CIKu19Ce50v7aN6h1Tjix+h5Ba8e12XAEpEZk9pFroEYfR4lrecvi1pQOwRw8YzDRC4lhGNOo5Cen1rGjk7dwzzgs4uEv9ZyPZoVJnty5P9JE/ctboEf3x4jbqIliuCRgOyXYsLlp+N282CKcWZ35URkGw2orKyG1U6L1hNoj7kkpvAo8Zagf97SdZ0nYdRBIHv6PQIDAQAB")
                .timeout(2000)
                .disableCookie()
                .execute().body();
        // 打印ECOLOGY响应信息
        System.out.println("testRegist()："+data);
        Map<String,Object> datas = JSONUtil.parseObj(data);
        //ECOLOGY返回的系统公钥
        SYSTEM_CACHE.put("SERVER_PUBLIC_KEY",StrUtil.nullToEmpty((String)datas.get("spk")));
        //ECOLOGY返回的系统密钥
        SYSTEM_CACHE.put("SERVER_SECRET",StrUtil.nullToEmpty((String)datas.get("secrit")));
        return datas;
    }

    public Map<String,Object> testGetoken(String address){
        // 从系统缓存或者数据库中获取ECOLOGY系统公钥和Secret信息
//        String secret = SYSTEM_CACHE.get("SERVER_SECRET");
//        String spk = SYSTEM_CACHE.get("SERVER_PUBLIC_KEY");
        // 如果为空,说明还未进行注册,调用注册接口进行注册认证与数据更新
//        if (Objects.isNull(secret)||Objects.isNull(spk)){
            testRegist(address);
//            // 重新获取最新ECOLOGY系统公钥和Secret信息
//            secret = SYSTEM_CACHE.get("SERVER_SECRET");
//            spk = SYSTEM_CACHE.get("SERVER_PUBLIC_KEY");
//        }
        String secrett = SYSTEM_CACHE.get("SERVER_SECRET");
        String spkk = SYSTEM_CACHE.get("SERVER_PUBLIC_KEY");
        // 公钥加密,所以RSA对象私钥为null
        RSA rsa = new RSA(null,spkk);
        //对秘钥进行加密传输，防止篡改数据
        String encryptSecret = rsa.encryptBase64(secrett, CharsetUtil.CHARSET_UTF_8, KeyType.PublicKey);
        //调用ECOLOGY系统接口进行注册
        String data = HttpRequest.post(address+ "/api/ec/dev/auth/applytoken")
                .header("appid","TW")
                .header("secret",encryptSecret)
                .header("time","3600")
                .disableCookie()
                .execute().body();
        System.out.println("testGetoken()："+data);
        Map<String,Object> datas = JSONUtil.parseObj(data);
        //ECOLOGY返回的token
        // TODO 为Token缓存设置过期时间
        SYSTEM_CACHE.put("SERVER_TOKEN",StrUtil.nullToEmpty((String)datas.get("token")));
        return datas;
    }

    public String testRestful(String address,String api,String jsonParams, String userid){
        //ECOLOGY返回的token
        String token= SYSTEM_CACHE.get("SERVER_TOKEN");
//        if (StrUtil.isEmpty(token)){
            token = (String) testGetoken(address).get("token");
//        }
//        String spk = SYSTEM_CACHE.get("SERVER_PUBLIC_KEY");
        //封装请求头参数
        String secrett = SYSTEM_CACHE.get("SERVER_SECRET");
        String spkk = SYSTEM_CACHE.get("SERVER_PUBLIC_KEY");
        RSA rsa = new RSA(null,spkk);
        //对用户信息进行加密传输,暂仅支持传输OA用户ID
        String encryptUserid = rsa.encryptBase64(userid,CharsetUtil.CHARSET_UTF_8,KeyType.PublicKey);
        //调用ECOLOGY系统接口，注意此处的disableCookie，可翻阅hutool的文档查看

        System.out.println("======================"+token);
        System.out.println("======================"+encryptUserid);
        String data = HttpRequest
                .post(address + api).disableCookie()
                .header("appid","TW")
                .header("token",token)
                .header("userid",encryptUserid)
                .body(jsonParams).contentType("application/json")
                .execute().body();
        System.out.println("testRestful()："+data);
        return data;
    }

    public String testRestfulNoHeader(String address,String api,String jsonParams, String userid){
        String data = HttpRequest
                .post(address + api + "?user="+userid).disableCookie()
                .body(jsonParams)
                .execute().body();
        System.out.println("testRestful()："+data);
        return data;
    }

    public String testRestfulNoHeaderUser(String address,String api,String jsonParams, String userid){
        String data = HttpRequest
                .post(address + api + "&user="+userid).disableCookie()
                .body(jsonParams)
                .execute().body();
        System.out.println("testRestful()："+data);
        return data;
    }
//    public void register() throws Exception{
//        HttpHeaders headers = new HttpHeaders();
//        headers.add("appid", appid);
//        headers.add("cpk", cpk);
//
//        HttpEntity<MultiValueMap<String, String>> requestEntity = new HttpEntity<>(headers);
//        RestTemplate noCookieRestTemplate = getNewRestTemplateWithoutCookie();
//        String result = noCookieRestTemplate.postForObject(registerUrl, requestEntity, String.class);
//        JSONObject jsonObject = JSON.parseObject(result);
//        //ECOLOGY返回的系统公钥
//        SYSTEM_CACHE.put("SERVER_PUBLIC_KEY", String.valueOf(jsonObject.get("spk")));
//        //ECOLOGY返回的系统密钥
//        SYSTEM_CACHE.put("SERVER_SECRET",String.valueOf(jsonObject.get("secret")));
//        System.out.println("result register:" + result);
//
//    }
//
//    public String getToken() throws Exception{
//        String secret = SYSTEM_CACHE.get("SERVER_SECRET");
//        String spk = SYSTEM_CACHE.get("SERVER_PUBLIC_KEY");
//        // 如果为空,说明还未进行注册,调用注册接口进行注册认证与数据更新
//        if (Objects.isNull(secret)||Objects.isNull(spk)){
//            register();
//            // 重新获取最新ECOLOGY系统公钥和Secret信息
//            secret = SYSTEM_CACHE.get("SERVER_SECRET");
//            spk = SYSTEM_CACHE.get("SERVER_PUBLIC_KEY");
//        }
//        String secretEn = E9ApiTokenUtil.encryptString(spk, secret);
//        HttpHeaders headers = new HttpHeaders();
//        headers.add("appid", appid);
//        headers.add("secret", secretEn);
//
//        HttpEntity<MultiValueMap<String, String>> requestEntity = new HttpEntity<>(headers);
//        RestTemplate noCookieRestTemplate = getNewRestTemplateWithoutCookie();
//
//        String result = noCookieRestTemplate.postForObject(tokenUrl, requestEntity, String.class);
//        JSONObject jsonObject = JSON.parseObject(result);
//        String token = String.valueOf(jsonObject.get("token"));
//        System.out.println("result token:" + result);
//        return token;
//    }

    public ImmutableMap<String, Object> getOaTodo(String oaId, Integer pageNo ,Integer pageSize) throws Exception {
//        return ImmutableMap.of("todoCount", 0 , "todoList", new ArrayList<>(),"doneCount", 0,"doneList", new ArrayList<>());
        Map<String, Object> params = new HashMap<>();
        Map<String, Object> map = new HashMap<>();
        map.put("root", ImmutableMap.of("createrid", oaId));
        params.put("conditions", map);

        String out = testRestfulNoHeader("https://yfoa.keruioil.com", "/api/workflow/paService/getDoingWorkflowRequestCountInside", JSON.toJSONString(params), oaId);
        String done = testRestfulNoHeader("https://yfoa.keruioil.com", "/api/workflow/paService/getHandledWorkflowRequestCountInside", JSON.toJSONString(params), oaId);
        map.put("root", ImmutableMap.of("craterid", oaId,"isdebug", "true"));
        params.put("conditions", map);
        System.out.println("-----------"+JSON.toJSONString(params));

        String todoList = testRestfulNoHeaderUser("https://yfoa.keruioil.com", "/api/workflow/paService/getDoingWorkflowRequestListInside?pageNo="+pageNo+"&pageSize="+pageSize, JSON.toJSONString(params), oaId);
        List<JSONObject> jsonObjects = new ArrayList<>();
        if (todoList != null && !todoList.contains("token不存在或者超时")) {
            jsonObjects = JSON.parseArray(todoList, JSONObject.class);
        }
        //已办明细
        String doneList = testRestfulNoHeaderUser("https://yfoa.keruioil.com", "/api/workflow/paService/getHandledWorkflowRequestListInside?pageNo="+pageNo+"&pageSize="+pageSize, JSON.toJSONString(params), oaId);
        List<JSONObject> doneJsonObjects = new ArrayList<>();
        if (todoList != null && !todoList.contains("token不存在或者超时")) {
            doneJsonObjects = JSON.parseArray(doneList, JSONObject.class);
        }
        return ImmutableMap.of("todoCount", NumberUtil.isNumber(out)?out:0 , "todoList", jsonObjects,"doneCount", NumberUtil.isNumber(done)?done : 0,"doneList", doneJsonObjects);
    }

    public List getOaNotice(String oaId, OaNoticeDO oaNoticeDO, String workcode) throws Exception {
//        String token = getToken();
//        String spk = SYSTEM_CACHE.get("SERVER_PUBLIC_KEY");
//        HttpHeaders headersOut = new HttpHeaders();
//        headersOut.add("token", token);
//        headersOut.add("appid", appid);
//        String person = E9ApiTokenUtil.encryptString(spk, oaId);
//        headersOut.add("userid", person);
//        headersOut.setContentType(MediaType.APPLICATION_JSON);
//        headersOut.remove(HttpHeaders.COOKIE); // 保险清空
//
//        headersOut.setAcceptCharset(Collections.singletonList(java.nio.charset.StandardCharsets.UTF_8));
//        headersOut.add(HttpHeaders.ACCEPT, "application/json;charset=UTF-8");

        Map<String, Object> params = new HashMap<>();
        params.put("userId", oaId);
        if (oaNoticeDO != null) {
            if (StringUtils.isNotBlank(oaNoticeDO.getOaCreateTime())) {
                DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
                // 2. 字符串转时间对象
                LocalDateTime dateTime = LocalDateTime.parse(oaNoticeDO.getOaCreateTime(), formatter);
                // 3. 往前推 1 秒（核心）
                LocalDateTime newTime = dateTime.plusSeconds(1);
                // 4. 转回字符串输出
                String result = newTime.format(formatter);
                params.put("dateTime", result);
            }
        }

//        HttpEntity<Map<String, Object>> requestEntityOut = new HttpEntity<>(params, headersOut);

//        RestTemplate noCookieRestTemplate = getNewRestTemplateWithoutCookie();
        //消息通知
        String out = null;
        try {
            System.out.println("---------------"+JSON.toJSONString(params));
//            out = noCookieRestTemplate.postForObject("https://yfoa.keruioil.com/api/msgDataInfo/flow/get", requestEntityOut, String.class);
            out = testRestfulNoHeader("https://yfoa.keruioil.com", "/api/msgDataInfo/flow/get", JSON.toJSONString(params), oaId);

        } catch (RestClientException e) {
            throw new ServiceException(new ErrorCode(1,"获取OA消息通知信息失败"));
        }
        if (Objects.isNull(out)||StringUtils.isBlank(out)) {return new ArrayList();}
        JSONObject out1 = JSON.parseObject(out);
        //查询的某个日期后面的未读消息中心
        String data1 = out1.getString("data");
        List<OaNoticeVo> oaNoticeDOS = JSON.parseArray(data1, OaNoticeVo.class);
        if (CollUtil.isEmpty(oaNoticeDOS)) {return  new ArrayList();}
        List<OaNoticeDO> collect = oaNoticeDOS.stream().map(e -> {
            OaNoticeDO oaNoticeDO1 = new OaNoticeDO();
            oaNoticeDO1.setOaCreateName(e.getCreatorName());
            oaNoticeDO1.setOaCreateTime(e.getCreateTime());
            oaNoticeDO1.setTitle(e.getTitle());
            oaNoticeDO1.setOaCreator(e.getCreator());
            oaNoticeDO1.setDeleted(false);
            //未读
            oaNoticeDO1.setStatus("0");
            oaNoticeDO1.setWorkCode(workcode);
            return oaNoticeDO1;
        }).collect(Collectors.toList());
        oaNoticeMapper.insertBatch(collect);
        return oaNoticeDOS;
    }

    @Data
    static class OaNoticeVo{
        private String creator;
        private String createTime;
        private String creatorName;
        private String title;
    }
}
