package cn.iocoder.yudao.server.service;

import cn.hutool.core.collection.CollUtil;
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.companyUrl}")
    private String companyUrl;
    @Value("${oa.departmentUrl}")
    private String departmentUrl;
    @Value("${oa.userUrl}")
    private String userUrl;
    @Value("${oa.workflowId}")
    private String workflowId;
    @Value("${oa.requestName}")
    private String requestName;
    @Value("${oa.outMaintain}")
    private String outMaintainUrl;

    private static String spk = "";
    private static String secret = "";
    @Autowired
    private OaNoticeMapper oaNoticeMapper;


    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 restTemplate = SslSkippingRestTemplate.createRestTemplate();

        String result = restTemplate.postForObject(registerUrl, requestEntity, String.class);
        JSONObject jsonObject = JSON.parseObject(result);
        spk = String.valueOf(jsonObject.get("spk"));
        secret = String.valueOf(jsonObject.get("secret"));
        System.out.println("result register:" + result);

    }

    public String getToken() throws Exception{
//        if (StringUtils.isBlank(spk) || StringUtils.isBlank(secret)) {
            register();
//        }
        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 restTemplate = SslSkippingRestTemplate.createRestTemplate();

        String result = restTemplate.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;
    }

    @Autowired
    private RestTemplate restTemplate;

    // ==================== 新增：每次使用【全新的、无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 ImmutableMap<String, Object> getOaTodo(String oaId, Integer pageNo ,Integer pageSize) throws Exception {
        String token = getToken();

        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); // 保险清空

        Map<String, Object> params = new HashMap<>();
        Map<String, Object> map = new HashMap<>();
        map.put("root", ImmutableMap.of("createrid", oaId));
        params.put("conditions", map);

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

        // ==================== 关键：每次都用全新无Cookie的RestTemplate ====================
        RestTemplate noCookieRestTemplate = getNewRestTemplateWithoutCookie();

        // 待办数量
        String out = noCookieRestTemplate.postForObject(
                "https://yfoa.keruioil.com/api/workflow/paService/getDoingWorkflowRequestCount",
                requestEntityOut, String.class
        );

        //已办数量
        String done = noCookieRestTemplate.postForObject("https://yfoa.keruioil.com/api/workflow/paService/getHandledWorkflowRequestCount", requestEntityOut, String.class);

        map.put("root", ImmutableMap.of("craterid", oaId));
        params.put("conditions", map);
//        params.put("pageSize", pageSize);
//        params.put("pageNo", pageNo);
        System.out.println("-----------"+JSON.toJSONString(params));
        HttpEntity<Map<String, Object>> requestEntityOut1 = new HttpEntity<>(params, headersOut);
        // 待办明细
        String todoList = noCookieRestTemplate.postForObject(
                "https://yfoa.keruioil.com/api/workflow/paService/getDoingWorkflowRequestList?pageNo="+pageNo+"&pageSize="+pageSize,
                requestEntityOut1, String.class
        );
        List<JSONObject> jsonObjects = new ArrayList<>();
        if (todoList != null && !todoList.contains("token不存在或者超时")) {
            jsonObjects = JSON.parseArray(todoList, JSONObject.class);
        }
        //已办明细
        String doneList = noCookieRestTemplate.postForObject("https://yfoa.keruioil.com/api/workflow/paService/getHandledWorkflowRequestList?pageNo="+pageNo+"&pageSize="+pageSize, requestEntityOut1, String.class);
        List<JSONObject> doneJsonObjects = new ArrayList<>();
        if (todoList != null && !todoList.contains("token不存在或者超时")) {
            doneJsonObjects = JSON.parseArray(doneList, JSONObject.class);
        }
        return ImmutableMap.of("todoCount", out, "todoList", jsonObjects,"doneCount", done,"doneList", doneJsonObjects);
    }

    public List getOaNotice(String oaId, OaNoticeDO oaNoticeDO, String workcode) throws Exception {
        String token = getToken();

        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 {
            out = noCookieRestTemplate.postForObject("https://yfoa.keruioil.com/api/msgDataInfo/flow/get", requestEntityOut, String.class);
        } 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;
    }
}
