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

import com.aliyun.dingtalkhrm_1_0.models.GetAllDismissionReasonsResponse;
import com.aliyun.dingtalkhrm_1_0.models.GetAllDismissionReasonsResponseBody;
import com.aliyun.tea.TeaException;
import com.aliyun.teautil.models.RuntimeOptions;
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.service.dto.DingTalkUserDTO;
import com.taobao.api.ApiException;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import java.util.ArrayList;
import java.util.List;

/**
 * 钉钉工具类
 *
 * @author jeeplus
 * @version 2021-5-29
 */
@Component
public class DingTalkUtils {

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

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

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

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

    @Value("${dingtalk.dingAdminId}")
    private String dingAdminId;//钉钉管理员ID

    public static com.aliyun.dingtalkhrm_1_0.Client createClient() throws Exception {
        com.aliyun.teaopenapi.models.Config config = new com.aliyun.teaopenapi.models.Config();
        config.protocol = "https";
        config.regionId = "central";
        return new com.aliyun.dingtalkhrm_1_0.Client(config);
    }
    /**
     * 获取钉钉token
     */
    public  String getToken(String tenantId) throws ApiException {
        // 创建钉钉客户端
        DingTalkClient client = new DefaultDingTalkClient("https://oapi.dingtalk.com/gettoken");
        // 配置请求参数
        OapiGettokenRequest req = new OapiGettokenRequest();
        String currentAppKey = "";
        String currentAppSecret = "";
        //根据公司判断来使用
        if("10003".equals(tenantId)){
            currentAppKey = accountAppKey;
            currentAppSecret = accountAppSecret;
        }else if("10001".equals(tenantId)){
            currentAppKey = assessAppKey;
            currentAppSecret = assessAppSecret;
        }
        req.setAppkey( currentAppKey); // 确保 appKey 已正确初始化
        req.setAppsecret(currentAppSecret); // 确保 appSecret 已正确初始化
        req.setHttpMethod("GET");
        // 执行请求，获取响应
        OapiGettokenResponse rsp = client.execute(req);
        String accessToken = rsp.getAccessToken();
        return accessToken;
    }
    

    /**
     * 获取部门列表
     */
    public  List<OapiV2DepartmentListsubResponse.DeptBaseResponse> deptList(String tenantId) throws ApiException {
        List<OapiV2DepartmentListsubResponse.DeptBaseResponse> allDepartments = new ArrayList<>();
        Long rootDeptId = 1L;
        String token = getToken(tenantId);
        fetchAllDepartments(rootDeptId, allDepartments,token);
        return allDepartments;
    }

    // 假设有一个方法可以调用 API 获取子部门列表
    public  List<OapiV2DepartmentListsubResponse.DeptBaseResponse> getSubDepartments(Long parentDeptId,String token) {
        try {
            DingTalkClient client = new DefaultDingTalkClient("https://oapi.dingtalk.com/topapi/v2/department/listsub");
            OapiV2DepartmentListsubRequest req = new OapiV2DepartmentListsubRequest();
            // 检查 deptId 是否为空
            if (parentDeptId != null) {
                req.setDeptId(parentDeptId);
            }
            OapiV2DepartmentListsubResponse rsp = client.execute(req, token);
            List<OapiV2DepartmentListsubResponse.DeptBaseResponse> result = rsp.getResult();
            // 返回 JSON 响应
            return result;
        } catch (Exception e) {
            e.printStackTrace(); // 打印错误日志（开发调试用）
            return null;
        }
    }


    // 递归获取所有子部门
    public  void fetchAllDepartments(Long parentDeptId, List<OapiV2DepartmentListsubResponse.DeptBaseResponse> allDepts,String token) throws ApiException {
        List<OapiV2DepartmentListsubResponse.DeptBaseResponse> subDepts = getSubDepartments(parentDeptId,token);
        for (OapiV2DepartmentListsubResponse.DeptBaseResponse dept : subDepts) {
            allDepts.add(dept); // 先添加当前部门
            fetchAllDepartments(dept.getDeptId(), allDepts,token); // 递归获取子部门
        }
    }


    /**
     * 创建用户
     */
    public  OapiV2UserCreateResponse addUser( DingTalkUserDTO addUserDTO,String tenantId) {
        try {
            String token = getToken(tenantId);
            DingTalkClient client = new DefaultDingTalkClient("https://oapi.dingtalk.com/topapi/v2/user/create");
            OapiV2UserCreateRequest req = new OapiV2UserCreateRequest();
            String name = addUserDTO.getName();
            String mobile = addUserDTO.getMobile();
            String deptIdList = addUserDTO.getDeptIdList();
            String userid = addUserDTO.getUserid();
            req.setName(name);
            req.setDeptIdList(deptIdList);
            req.setHideMobile(false);
            req.setMobile(mobile);
            req.setUserid(userid);
            OapiV2UserCreateResponse rsp = client.execute(req, token);
            // 返回 JSON 响应
            return rsp;
        } catch (Exception e) {
            throw  new RuntimeException(e.getMessage());
        }
    }

    public  OapiV2UserUpdateResponse updateUser(DingTalkUserDTO addUserDTO,String tenantId) {
        try {
            String token = getToken(tenantId);
            DingTalkClient client = new DefaultDingTalkClient("https://oapi.dingtalk.com/topapi/v2/user/update");
            OapiV2UserUpdateRequest req = new OapiV2UserUpdateRequest();
            String name = addUserDTO.getName();
            String mobile = addUserDTO.getMobile();
            String deptIdList = addUserDTO.getDeptIdList();
            String userId = addUserDTO.getUserid();
            req.setUserid(userId);
            req.setName(name);
            req.setDeptIdList(deptIdList);
            req.setHideMobile(false);
            req.setMobile(mobile);
            OapiV2UserUpdateResponse rsp = client.execute(req, token);
            // 返回 JSON 响应
            return rsp;
        } catch (Exception e) {
            throw  new RuntimeException(e.getMessage());
        }
    }

    /**
     * 获取用户信息
     * @param id
     * @return
     */
    public  OapiV2UserGetResponse.UserGetResponse selectUserById(String id,String tenantId) {
        try {
            String token = getToken(tenantId);
            DingTalkClient client = new DefaultDingTalkClient("https://oapi.dingtalk.com/topapi/v2/user/get");
            OapiV2UserGetRequest req = new OapiV2UserGetRequest();
            req.setUserid(id);
            req.setLanguage("zh_CN");
            OapiV2UserGetResponse rsp = client.execute(req, token);
            OapiV2UserGetResponse.UserGetResponse result = rsp.getResult();
            // 返回 JSON 响应
            return result;
        } catch (Exception e) {
            throw  new RuntimeException(e.getMessage());
        }
    }

    public  OapiV2UserDeleteResponse deleteUser(DingTalkUserDTO userDTO,String tenantId) {
        try {
            String token = getToken(tenantId);
            DingTalkClient client = new DefaultDingTalkClient("https://oapi.dingtalk.com/topapi/v2/user/delete");
            OapiV2UserDeleteRequest req = new OapiV2UserDeleteRequest();
            req.setUserid(userDTO.getUserid());
            OapiV2UserDeleteResponse rsp = client.execute(req, token);
            // 返回 JSON 响应
            return rsp;
        } catch (Exception e) {
            throw  new RuntimeException(e.getMessage());
        }
    }


    /**
     * 将钉钉用户添加至待离职状态
     * @param userDTO
     * @param tenantId
     * @return
     * @throws Exception
     */
    public Boolean userPendingResignation(DingTalkUserDTO userDTO,Long lastWorkDate,String tenantId) throws Exception {
        com.aliyun.dingtalkhrm_1_0.Client client = DingTalkUtils.createClient();
        com.aliyun.dingtalkhrm_1_0.models.EmpStartDismissionHeaders empStartDismissionHeaders = new com.aliyun.dingtalkhrm_1_0.models.EmpStartDismissionHeaders();
        empStartDismissionHeaders.xAcsDingtalkAccessToken  = getToken(tenantId);
        //获取离职原因
        String reasonLeaving = getReasonLeaving(tenantId);
        com.aliyun.dingtalkhrm_1_0.models.EmpStartDismissionRequest empStartDismissionRequest = new com.aliyun.dingtalkhrm_1_0.models.EmpStartDismissionRequest()
                .setTerminationReasonVoluntary(java.util.Arrays.asList(
                        reasonLeaving
                )) // 离职原因 默认其他
                .setPartner(false) //是否不计入人事统计
                .setLastWorkDate(lastWorkDate)//离职日期
                .setToHireDismissionTalent(false) //是否保存至招聘人才库
                .setToHireBlackList(false) //是否加入招聘黑名单
                .setUserId(userDTO.getUserid()) // 离职员工的id
                .setToHrmBlackList(false);//是否加入人事黑名单
        try {
            client.empStartDismissionWithOptions(empStartDismissionRequest, empStartDismissionHeaders, new com.aliyun.teautil.models.RuntimeOptions());
        } catch (TeaException err) {
            if (!com.aliyun.teautil.Common.empty(err.code) && !com.aliyun.teautil.Common.empty(err.message)) {
            }
            return false;
        } catch (Exception _err) {
            TeaException err = new TeaException(_err.getMessage(), _err);
            if (!com.aliyun.teautil.Common.empty(err.code) && !com.aliyun.teautil.Common.empty(err.message)) {
            }
            return false;
        }
        return true;
    }

    /**
     * 撤销用户待离职状态
     * @param userDTO
     * @param tenantId
     * @return
     * @throws Exception
     */
    public Boolean revokeUserPendingResignation(DingTalkUserDTO userDTO,String tenantId) throws Exception {
        com.aliyun.dingtalkhrm_1_0.Client client = DingTalkUtils.createClient();
        com.aliyun.dingtalkhrm_1_0.models.RevokeTerminationHeaders revokeTerminationHeaders = new com.aliyun.dingtalkhrm_1_0.models.RevokeTerminationHeaders();
        revokeTerminationHeaders.xAcsDingtalkAccessToken  = getToken(tenantId);
        com.aliyun.dingtalkhrm_1_0.models.RevokeTerminationRequest revokeTerminationRequest = new com.aliyun.dingtalkhrm_1_0.models.RevokeTerminationRequest()
         .setUserId(userDTO.getUserid());
        try {
            client.revokeTerminationWithOptions(revokeTerminationRequest, revokeTerminationHeaders, new com.aliyun.teautil.models.RuntimeOptions());
        } catch (TeaException err) {
            if (!com.aliyun.teautil.Common.empty(err.code) && !com.aliyun.teautil.Common.empty(err.message)) {
            }
            return false;
        } catch (Exception _err) {
            TeaException err = new TeaException(_err.getMessage(), _err);
            if (!com.aliyun.teautil.Common.empty(err.code) && !com.aliyun.teautil.Common.empty(err.message)) {
            }
            return false;
        }
        return true;
    }


    /**
     * 获取离职原因(默认返回 其他 )
     * @param tenantId
     * @return
     * @throws Exception
     */
    public  String getReasonLeaving(String tenantId) throws Exception {
        com.aliyun.dingtalkhrm_1_0.Client client = DingTalkUtils.createClient();
        com.aliyun.dingtalkhrm_1_0.models.GetAllDismissionReasonsHeaders getAllDismissionReasonsHeaders = new com.aliyun.dingtalkhrm_1_0.models.GetAllDismissionReasonsHeaders();
        getAllDismissionReasonsHeaders.xAcsDingtalkAccessToken  = getToken(tenantId);
        GetAllDismissionReasonsResponseBody.GetAllDismissionReasonsResponseBodyResult result = null;
        try {
            GetAllDismissionReasonsResponse allDismissionReasonsWithOptions = client.getAllDismissionReasonsWithOptions(getAllDismissionReasonsHeaders, new RuntimeOptions());
           result = allDismissionReasonsWithOptions.getBody().getResult();
        } catch (TeaException err) {
            if (!com.aliyun.teautil.Common.empty(err.code) && !com.aliyun.teautil.Common.empty(err.message)) {
            }
        } catch (Exception _err) {
            TeaException err = new TeaException(_err.getMessage(), _err);
            if (!com.aliyun.teautil.Common.empty(err.code) && !com.aliyun.teautil.Common.empty(err.message)) {
            }
        }
        List<GetAllDismissionReasonsResponseBody.GetAllDismissionReasonsResponseBodyResultVoluntaryList> voluntaryList = result.getVoluntaryList();
        GetAllDismissionReasonsResponseBody.GetAllDismissionReasonsResponseBodyResultVoluntaryList getAllDismissionReasonsResponseBodyResultVoluntaryList = voluntaryList.get(4);
        String id = getAllDismissionReasonsResponseBodyResultVoluntaryList.getId();//获取 其他原因的 id
        return id;
    }


    /**
     * 确认离职并删除员工
     * @param dingUserDTO
     * @param tenantId
     * @return
     * @throws Exception
     */
    public  void confirmRe(DingTalkUserDTO dingUserDTO,String tenantId) throws Exception {
        com.aliyun.dingtalkhrm_1_0.Client client = DingTalkUtils.createClient();
        com.aliyun.dingtalkhrm_1_0.models.HrmProcessTerminationAndHandoverHeaders hrmProcessTerminationAndHandoverHeaders = new com.aliyun.dingtalkhrm_1_0.models.HrmProcessTerminationAndHandoverHeaders();
        hrmProcessTerminationAndHandoverHeaders.xAcsDingtalkAccessToken = getToken(tenantId);
        long yesterdayTimestamp = System.currentTimeMillis() - 24 * 60 * 60 * 1000;
        com.aliyun.dingtalkhrm_1_0.models.HrmProcessTerminationAndHandoverRequest hrmProcessTerminationAndHandoverRequest = new com.aliyun.dingtalkhrm_1_0.models.HrmProcessTerminationAndHandoverRequest()
                .setUserId(dingUserDTO.getUserid())
                .setLastWorkDate(yesterdayTimestamp)
                .setOptUserId(dingAdminId)//操作者的id，是本组织的并且非离职员工本人
                .setDismissionMemo("");
        try {
            client.hrmProcessTerminationAndHandoverWithOptions(hrmProcessTerminationAndHandoverRequest, hrmProcessTerminationAndHandoverHeaders, new com.aliyun.teautil.models.RuntimeOptions());
        } catch (TeaException err) {
            if (!com.aliyun.teautil.Common.empty(err.code) && !com.aliyun.teautil.Common.empty(err.message)) {
            }
        } catch (Exception _err) {
            TeaException err = new TeaException(_err.getMessage(), _err);
            if (!com.aliyun.teautil.Common.empty(err.code) && !com.aliyun.teautil.Common.empty(err.message)) {
            }
        }
    }

}
