/**
 * Copyright &copy; 2021-2026 <a href="http://www.jeeplus.org/">JeePlus</a> All rights reserved.
 */
package com.jeeplus.human.enrollment.enrollmentRegistration.utils;

import cn.hutool.extra.spring.SpringUtil;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.dingtalk.api.DefaultDingTalkClient;
import com.dingtalk.api.DingTalkClient;
import com.dingtalk.api.request.*;
import com.dingtalk.api.response.*;
import com.jeeplus.human.enrollment.enrollmentRegistration.domain.EnrollmentRegistration;
import com.jeeplus.human.enrollment.enrollmentRegistration.service.EnrollmentRegistrationService;
import com.jeeplus.sys.feign.IDictApi;
import com.jeeplus.sys.feign.IUserApi;
import com.jeeplus.sys.service.dto.UserDTO;
import com.jeeplus.utils.StringUtils;
import com.taobao.api.ApiException;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.*;
import java.util.stream.Collectors;

/**
 * 钉钉数据同步
 *
 * @author jeeplus
 * @version 2021-5-29
 */
@Component
public class DingTalkSyncUtil {
    @Resource
    private EnrollmentRegistrationService enrollmentRegistrationService;

    //会计钉钉配置
    @Value("${dingtalk.accountAppKey}")
    private String accountAppKey;

    @Value("${dingtalk.accountAppSecret}")
    private String accountAppSecret;

    //评估钉钉配置
    @Value("${dingtalk.assessAppKey}")
    private String assessAppKey;

    @Value("${dingtalk.assessAppSecret}")
    private String assessAppSecret;

    /**
     * 获取评估钉钉token
     */
    public String getAssessToken() throws ApiException {
        // 创建钉钉客户端
        DingTalkClient client = new DefaultDingTalkClient("https://oapi.dingtalk.com/gettoken");
        // 配置请求参数
        OapiGettokenRequest req = new OapiGettokenRequest();
        req.setAppkey(assessAppKey); // 确保 appKey 已正确初始化
        req.setAppsecret(assessAppSecret); // 确保 appSecret 已正确初始化
        req.setHttpMethod("GET");
        // 执行请求，获取响应
        OapiGettokenResponse rsp = client.execute(req);
        String accessToken = rsp.getAccessToken();
        return accessToken;
    }

    /**
     * 获取会计钉钉token
     */
    public String getAccountToken() throws ApiException {
        // 创建钉钉客户端
        DingTalkClient client = new DefaultDingTalkClient("https://oapi.dingtalk.com/gettoken");
        // 配置请求参数
        OapiGettokenRequest req = new OapiGettokenRequest();
        req.setAppkey(accountAppKey); // 确保 appKey 已正确初始化
        req.setAppsecret(accountAppSecret); // 确保 appSecret 已正确初始化
        req.setHttpMethod("GET");
        // 执行请求，获取响应
        OapiGettokenResponse rsp = client.execute(req);
        String accessToken = rsp.getAccessToken();
        return accessToken;
    }


    /**
     * 同步用户数据，使用线程池，防止定时任务执行结果为失败
     */
    public void getUserByMobileSyncData() {
        try {
            String dictValue = SpringUtil.getBean(IDictApi.class).getDictValue("dd_status", "dd_status", "0");
            if (!"1".equals(dictValue)) {
                return;
            }

            IUserApi userApi = SpringUtil.getBean(IUserApi.class);
            List<UserDTO> allUserInfo = userApi.getAllUserInfo();
            String accountToken = getAccountToken();
            String assessToken = getAssessToken();

            // 创建线程池
            int coreThreads = Math.max(2, Runtime.getRuntime().availableProcessors() / 2);
            ExecutorService executor = new ThreadPoolExecutor(
                    coreThreads,
                    Runtime.getRuntime().availableProcessors(),
                    60L, TimeUnit.SECONDS,
                    new LinkedBlockingQueue<>()
            );

            // 限制最大并发请求数3
            Semaphore semaphore = new Semaphore(3);
            List<CompletableFuture<Void>> futures = allUserInfo.stream()
                    .filter(user -> user.getTenantDTO() != null)
                    .filter(user -> "10003".equals(user.getTenantDTO().getId()) || "10001".equals(user.getTenantDTO().getId()))
                    .filter(user -> StringUtils.isBlank(user.getDdId()))
                    .map(user -> CompletableFuture.runAsync(() -> {
                        try {
                            semaphore.acquire(); // 控制最大并发请求数
                            processUser(user, userApi, accountToken, assessToken);
                        } catch (InterruptedException e) {
                            Thread.currentThread().interrupt();
                        } finally {
                            semaphore.release(); // 释放
                        }
                    }, executor))
                    .collect(Collectors.toList());
            // 等待任务完成
            CompletableFuture.allOf(futures.toArray(new CompletableFuture[0])).join();
            executor.shutdown();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 处理单个用户的钉钉 ID 获取和更新
     */
    private void processUser(UserDTO user, IUserApi userApi, String accountToken, String assessToken) {
        try {
                String token = "10003".equals(user.getTenantDTO().getId()) ? accountToken : assessToken;
                DingTalkClient client = new DefaultDingTalkClient("https://oapi.dingtalk.com/topapi/v2/user/getbymobile");
                OapiV2UserGetbymobileRequest req = new OapiV2UserGetbymobileRequest();
                req.setMobile(user.getMobile());
                String body = client.execute(req, token).getBody();
                JSONObject jsonObject = JSONUtil.parseObj(body);
                String ddUserId = "";
                UserDTO userDTO = new UserDTO();
                EnrollmentRegistration enrollmentRegistration = new EnrollmentRegistration();
                if ("0".equals(jsonObject.getStr("errcode"))) {
                    ddUserId = jsonObject.getJSONObject("result").getStr("userid");
                    userDTO.setDdId(ddUserId);
                    enrollmentRegistration.setDdId(ddUserId);
                    enrollmentRegistration.setDdType("1");
                    // 更新用户数据
                    userDTO.setId(user.getId());
                    userApi.updateUserById(userDTO);
                } else {
                    //若用户不存在钉钉，则在
                    enrollmentRegistration.setDdType("0");
                }
                // 更新入职登记数据
                enrollmentRegistration.setUserId(user.getId());
                enrollmentRegistrationService.updateDdIdById(enrollmentRegistration);
        } catch (Exception e) {
            e.printStackTrace();
        }

    }
}
