package cn.iocoder.yudao.module.system.service.dingding;

import cn.hutool.core.collection.CollUtil;
import com.dingtalk.api.DefaultDingTalkClient;
import com.dingtalk.api.DingTalkClient;
import com.dingtalk.api.request.OapiV2DepartmentGetRequest;
import com.dingtalk.api.request.OapiV2DepartmentListsubRequest;
import com.dingtalk.api.request.OapiV2DepartmentListsubidRequest;
import com.dingtalk.api.response.OapiV2DepartmentGetResponse;
import com.dingtalk.api.response.OapiV2DepartmentListsubResponse;
import com.dingtalk.api.response.OapiV2DepartmentListsubidResponse;
import com.taobao.api.ApiException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;


/**
 * @author hanzy
 * @description
 * @date 2024年06月04日 13:42
 */
@Slf4j
@Service
public class DingDeptService {
    /**
     * @description: 获取部门列表
     * @param: accessToken
     * @return: com.dingtalk.api.response.OapiV2DepartmentListsubResponse
     */
    public OapiV2DepartmentListsubResponse listsub(String accessToken, Long deptId) {
        OapiV2DepartmentListsubResponse rsp;
        DingTalkClient client = new DefaultDingTalkClient("https://oapi.dingtalk.com/topapi/v2/department/listsub");
        OapiV2DepartmentListsubRequest req = new OapiV2DepartmentListsubRequest();
        req.setDeptId(deptId);
        req.setLanguage("zh_CN");
        try {
            rsp = client.execute(req, accessToken);
        } catch (ApiException e) {
            log.error("Failed to getUserName: " + e.getErrMsg());
            return null;
        }
        return rsp;
    }

    /**
     * @description: 获取子部门ID列表
     * @param: accessToken
     * @return: com.dingtalk.api.response.OapiV2DepartmentListsubidResponse
     */
    public OapiV2DepartmentListsubidResponse listsubid(String accessToken, Long deptId) {
        OapiV2DepartmentListsubidResponse rsp;
        DingTalkClient client = new DefaultDingTalkClient("https://oapi.dingtalk.com/topapi/v2/department/listsubid");
        OapiV2DepartmentListsubidRequest req = new OapiV2DepartmentListsubidRequest();
        req.setDeptId(deptId);
        try {
            rsp = client.execute(req, accessToken);
        } catch (ApiException e) {
            log.error("Failed to getUserName: " + e.getErrMsg());
            return null;
        }
        return rsp;
    }

    /**
     * @description: 获取部门详情
     * @param: accessToken
     * @return: com.dingtalk.api.response.OapiV2DepartmentGetResponse
     */
    public OapiV2DepartmentGetResponse get(String accessToken, Long deptId) {
        OapiV2DepartmentGetResponse rsp;
        DingTalkClient client = new DefaultDingTalkClient("https://oapi.dingtalk.com/topapi/v2/department/get");
        OapiV2DepartmentGetRequest req = new OapiV2DepartmentGetRequest();
        req.setDeptId(deptId);
        req.setLanguage("zh_CN");
        try {
            rsp = client.execute(req, accessToken);
            ;
        } catch (ApiException e) {
            log.error("Failed to getUserName: " + e.getErrMsg());
            return null;
        }
        return rsp;
    }

    public List<Long> getSubDeptIdList(String accessToken, Long deptId) {
        List<Long> result = new ArrayList<>();
        OapiV2DepartmentListsubidResponse listsubid = listsubid(accessToken, deptId);
        if (listsubid.getErrcode() == 0) {
            result = listsubid.getResult().getDeptIdList();
        }
        return result;
    }

    public OapiV2DepartmentGetResponse.DeptGetResponse getDepInfo(String accessToken, Long deptId) {
        OapiV2DepartmentGetResponse.DeptGetResponse result = new OapiV2DepartmentGetResponse.DeptGetResponse();
        OapiV2DepartmentGetResponse oapiV2DepartmentGetResponse = get(accessToken, deptId);
        if (oapiV2DepartmentGetResponse.getErrcode() == 0) {
            result = oapiV2DepartmentGetResponse.getResult();
        }
        return result;
    }

    public void getChildDeptIdList(String accessToken, Long parentId, List<Long> children) {
        List<Long> deptIdList = getSubDeptIdList(accessToken, parentId);
        if (CollUtil.isEmpty(deptIdList)) {
            return;
        }
        children.addAll(deptIdList);
        for (Long deptId : deptIdList) {
            getChildDeptIdList(accessToken, deptId, children);
        }
    }

    public List<OapiV2DepartmentGetResponse.DeptGetResponse> deptGetResponseList(String accessToken, Long parentId) {
        List<OapiV2DepartmentGetResponse.DeptGetResponse> deptGetResponseList = new ArrayList<>();
        List<Long> children = new ArrayList<>();
        getChildDeptIdList(accessToken, parentId, children);
        Set<Long> depIdSet = convertSet(children);
        for (Long depId : depIdSet) {
            OapiV2DepartmentGetResponse.DeptGetResponse depInfo = getDepInfo(accessToken, depId);
            if (depInfo != null) {
                deptGetResponseList.add(depInfo);
            }
        }
        return deptGetResponseList;
    }

    public static <T> Set<T> convertSet(Collection<T> from) {
        return convertSet(from, v -> v);
    }
    public static <T, U> Set<U> convertSet(Collection<T> from, Function<T, U> func) {
        if (CollUtil.isEmpty(from)) {
            return new HashSet<>();
        }
        return from.stream().map(func).filter(Objects::nonNull).collect(Collectors.toSet());
    }
}
