package yangtz.cs.liu.dingding.utils;

import com.aliyun.dingtalkstorage_1_0.models.AddPermissionResponse;
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.ruoyi.common.utils.StringUtils;
import com.taobao.api.ApiException;
import com.taobao.api.FileItem;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import yangtz.cs.liu.dingding.vo.DingSchoolUserVo;

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 用户管理
 */
@Component
public class DingUserUtils {

    @Autowired
    private AccessTokenUtils accessTokenUtils;

    private static final String UPLOAD_FILE_URL = "https://oapi.dingtalk.com/media/upload?access_token=ACCESS_TOKEN&media=FILE_PATH";

    /**
     * 上传文件到钉盘
     * @param filePath
     */
    public String uploadFileToDingTalk(String filePath) {
        String accessToken = accessTokenUtils.getToken();
        try {
            DingTalkClient client = new DefaultDingTalkClient("https://oapi.dingtalk.com/media/upload");
            OapiMediaUploadRequest req = new OapiMediaUploadRequest();
            req.setType("file");
            req.setMedia(new FileItem(filePath));
            req.setTopContentType("multipart/form-data");
            OapiMediaUploadResponse rsp = client.execute(req, accessToken);
            return rsp.getBody();
        } catch (ApiException e) {
            e.printStackTrace();
            return "下载失败";
        }
    }

    /**
     * 创建用户
     */
    public OapiV2UserCreateResponse.UserCreateResponse createUser(DingSchoolUserVo userVo){
        //获取access_token
        String token = accessTokenUtils.getToken();
        try {
            DingTalkClient client = new DefaultDingTalkClient("https://oapi.dingtalk.com/topapi/v2/user/create");
            OapiV2UserCreateRequest req = new OapiV2UserCreateRequest();
            if (StringUtils.isNotEmpty(userVo.getUserid())){
                req.setUserid(userVo.getUserid());
            }
            if (StringUtils.isNotEmpty(userVo.getName())){
                req.setName(userVo.getName());
            }
            if (StringUtils.isNotNull(userVo.getSeniorMode())){
                req.setSeniorMode(userVo.getSeniorMode());
            }
            if (StringUtils.isNotEmpty(userVo.getMobile())){
                req.setMobile(userVo.getMobile());
            }
            if (StringUtils.isNotEmpty(userVo.getTitle())){
                req.setTitle(userVo.getTitle());
            }
            if (StringUtils.isNotEmpty(userVo.getEmail())){
                req.setEmail(userVo.getEmail());
            }
            if (StringUtils.isNotEmpty(userVo.getOrgEmail())){
                req.setOrgEmail(userVo.getOrgEmail());
            }
            if (StringUtils.isNotEmpty(userVo.getOrgEmailType())){
                req.setOrgEmailType(userVo.getOrgEmailType());
            }
            if (StringUtils.isNotEmpty(userVo.getDeptTitleList())){
                req.setDeptTitleList(userVo.getDeptTitleList());
            }
            if (StringUtils.isNotNull(userVo.getHideMobile())){
                req.setHideMobile(userVo.getHideMobile());
            }
            if (StringUtils.isNotEmpty(userVo.getTelephone())){
                req.setTelephone(userVo.getTelephone());
            }
            if (StringUtils.isNotEmpty(userVo.getJobNumber())){
                req.setJobNumber(userVo.getJobNumber());
            }
            if (StringUtils.isNotNull(userVo.getHiredDate())){
                req.setHiredDate(userVo.getHiredDate());
            }
            if (StringUtils.isNotEmpty(userVo.getWorkPlace())){
                req.setWorkPlace(userVo.getWorkPlace());
            }
            if (StringUtils.isNotEmpty(userVo.getRemark())){
                req.setRemark(userVo.getRemark());
            }
            if (StringUtils.isNotEmpty(userVo.getDeptIdList())){
                req.setDeptIdList(userVo.getDeptIdList());
            }
            if (StringUtils.isNotEmpty(userVo.getDeptOrderList())){
                req.setDeptOrderList(userVo.getDeptOrderList());
            }
            if (StringUtils.isNotEmpty(userVo.getExtension())){
                req.setExtension(userVo.getExtension());
            }
            if (StringUtils.isNotEmpty(userVo.getManagerUserid())){
                req.setManagerUserid(userVo.getManagerUserid());
            }
            if (StringUtils.isNotEmpty(userVo.getLoginEmail())){
                req.setLoginEmail(userVo.getLoginEmail());
            }
            OapiV2UserCreateResponse rsp = client.execute(req, token);
            return rsp.getResult();
        } catch (ApiException e) {
            e.printStackTrace();
        }
        return new OapiV2UserCreateResponse.UserCreateResponse();
    }

    /**
     * 更新用户信息
     */
    public String updateUser(DingSchoolUserVo userVo){
        //获取access_token
        String token = accessTokenUtils.getToken();
        try {
            DingTalkClient client = new DefaultDingTalkClient("https://oapi.dingtalk.com/topapi/v2/user/update");
            OapiV2UserUpdateRequest req = new OapiV2UserUpdateRequest();
            req.setUserid(userVo.getUserid());
            if (StringUtils.isNotEmpty(userVo.getName())){
                req.setName(userVo.getName());
            }
            if (StringUtils.isNotNull(userVo.getHideMobile())){
                req.setHideMobile(userVo.getHideMobile());
            }
            if (StringUtils.isNotEmpty(userVo.getTelephone())){
                req.setTelephone(userVo.getTelephone());
            }
            if (StringUtils.isNotEmpty(userVo.getJobNumber())){
                req.setJobNumber(userVo.getJobNumber());
            }
            if (StringUtils.isNotEmpty(userVo.getManagerUserid())){
                req.setManagerUserid(userVo.getManagerUserid());
            }
            if (StringUtils.isNotEmpty(userVo.getTitle())){
                req.setTitle(userVo.getTitle());
            }
            if (StringUtils.isNotEmpty(userVo.getEmail())){
                req.setEmail(userVo.getEmail());
            }
            if (StringUtils.isNotEmpty(userVo.getOrgEmail())){
                req.setOrgEmail(userVo.getOrgEmail());
            }
            if (StringUtils.isNotEmpty(userVo.getWorkPlace())){
                req.setWorkPlace(userVo.getWorkPlace());
            }
            if (StringUtils.isNotEmpty(userVo.getRemark())){
                req.setRemark(userVo.getRemark());
            }
            if (StringUtils.isNotEmpty(userVo.getDeptIdList())){
                req.setDeptIdList(userVo.getDeptIdList());
            }
            if (StringUtils.isNotEmpty(userVo.getDeptOrderList())){
                req.setDeptOrderList(userVo.getDeptOrderList());
            }
            if (StringUtils.isNotEmpty(userVo.getDeptTitleList())){
                req.setDeptTitleList(userVo.getDeptTitleList());
            }
            if (StringUtils.isNotEmpty(userVo.getExtension())){
                req.setExtension(userVo.getExtension());
            }
            if (StringUtils.isNotNull(userVo.getSeniorMode())){
                req.setSeniorMode(userVo.getSeniorMode());
            }
            if (StringUtils.isNotNull(userVo.getHiredDate())){
                req.setHiredDate(userVo.getHiredDate());
            }
            if (StringUtils.isNotEmpty(userVo.getLanguage())){
                req.setLanguage(userVo.getLanguage());
            }
            if (StringUtils.isNotEmpty(userVo.getForceUpdateFields())){
                req.setForceUpdateFields(userVo.getForceUpdateFields());
            }
            OapiV2UserUpdateResponse rsp = client.execute(req, token);
            return rsp.getErrmsg();
        } catch (ApiException e) {
            e.printStackTrace();
        }
        return "";
    }

    /**
     * 删除用户信息
     */
    public String deleteUser(String userId){
        //获取access_token
        String token = accessTokenUtils.getToken();
        try {
            DingTalkClient client = new DefaultDingTalkClient("https://oapi.dingtalk.com/topapi/v2/user/delete");
            OapiV2UserDeleteRequest req = new OapiV2UserDeleteRequest();
            req.setUserid(userId);
            OapiV2UserDeleteResponse rsp = client.execute(req, token);
            return rsp.getErrmsg();
        } catch (ApiException e) {
            e.printStackTrace();
        }
        return "";
    }

    /**
     * 获取用户详情
     */
    public OapiV2UserGetResponse.UserGetResponse getUser(String userId){
        //获取access_token
        String token = accessTokenUtils.getToken();
        try {
            DingTalkClient client = new DefaultDingTalkClient("https://oapi.dingtalk.com/topapi/v2/user/get");
            OapiV2UserGetRequest req = new OapiV2UserGetRequest();
            req.setUserid(userId);
            OapiV2UserGetResponse rsp = client.execute(req, token);
            return rsp.getResult();
        } catch (ApiException e) {
            e.printStackTrace();
        }
        return new OapiV2UserGetResponse.UserGetResponse();
    }

    /**
     * 获取部门用户基础信息
     * @param deptId 部门ID，如果是根部门，该参数传1。
     * @param cursor 分页查询的游标，最开始传0，后续传返回参数中的next_cursor值。
     * @param size 分页长度，最大值100。
     * @param orderField 部门成员的排序规则。默认值，custom。
     *                  entry_asc：代表按照进入部门的时间升序。
     *                  entry_desc：代表按照进入部门的时间降序。
     *                  modify_asc：代表按照部门信息修改时间升序。
     *                  modify_desc：代表按照部门信息修改时间降序。
     *                  custom：代表用户定义(未定义时按照拼音)排序。
     * @param containAccessLimit 是否返回访问受限的员工。 true：是 false：否
     * @param language 通讯录语言，取值。  zh_CN：中文（默认值）。   en_US：英文。
     * @return List<Map<String,String>>
     */
    public List<Map<String,String>> getUserByDeptId(Long deptId, Long cursor, Long size, String orderField, String containAccessLimit, String language)
    {
        //获取access_token
        String token = accessTokenUtils.getToken();
        List<Map<String,String>> maps = new ArrayList<>();
        try {
            DingTalkClient client = new DefaultDingTalkClient("https://oapi.dingtalk.com/topapi/user/listsimple");
            OapiUserListsimpleRequest req = new OapiUserListsimpleRequest();
            req.setDeptId(deptId);
            req.setCursor(cursor);
            req.setSize(size);
            if (StringUtils.isNotEmpty(orderField)){
                req.setOrderField(orderField);
            }
            if (StringUtils.isNotEmpty(containAccessLimit)){
                req.setContainAccessLimit(Boolean.valueOf(containAccessLimit));
            }
            if (StringUtils.isNotEmpty(language)){
                req.setLanguage(language);
            }
            OapiUserListsimpleResponse rsp = client.execute(req, token);
            OapiUserListsimpleResponse.PageResult result = rsp.getResult();
            List<OapiUserListsimpleResponse.ListUserSimpleResponse> list = result.getList();
            for (OapiUserListsimpleResponse.ListUserSimpleResponse listUserSimpleResponse : list) {
                Map<String,String> map = new HashMap<>();
                String name = listUserSimpleResponse.getName();
                String userid = listUserSimpleResponse.getUserid();
                map.put("name",name);
                map.put("userId",userid);
                maps.add(map);
            }
            return maps;
        } catch (ApiException e) {
            e.printStackTrace();
        }
        return maps;
    }

    /**
     * 获取部门用户userId列表
     */
    public OapiUserListidResponse.ListUserByDeptResponse getuserIdByDept(Long deptId){
        //获取access_token
        String token = accessTokenUtils.getToken();
        try {
            DingTalkClient client = new DefaultDingTalkClient("https://oapi.dingtalk.com/topapi/user/listid");
            OapiUserListidRequest req = new OapiUserListidRequest();
            req.setDeptId(deptId);
            OapiUserListidResponse rsp = client.execute(req, token);
            return rsp.getResult();
        } catch (ApiException e) {
            e.printStackTrace();
        }
        return new OapiUserListidResponse.ListUserByDeptResponse();
    }

    /**
     * 查询部门用户详情
     */
    public List<OapiV2UserListResponse.ListUserResponse> getUserInfoByDeptId(Long deptId, Long cursor, Long size, String orderField, String containAccessLimit, String language)
    {
        //获取access_token
        String token = accessTokenUtils.getToken();
        try {
            DingTalkClient client = new DefaultDingTalkClient("https://oapi.dingtalk.com/topapi/v2/user/list");
            OapiV2UserListRequest req = new OapiV2UserListRequest();
            req.setDeptId(deptId);
            req.setCursor(cursor);
            req.setSize(size);
            if (StringUtils.isNotEmpty(orderField)){
                req.setOrderField(orderField);
            }
            if (StringUtils.isNotEmpty(containAccessLimit)){
                req.setContainAccessLimit(Boolean.valueOf(containAccessLimit));
            }
            if (StringUtils.isNotEmpty(language)){
                req.setLanguage(language);
            }
            OapiV2UserListResponse rsp = client.execute(req, token);
            OapiV2UserListResponse.PageResult result = rsp.getResult();
            return result.getList();
        } catch (ApiException e) {
            e.printStackTrace();
        }
        return new ArrayList<>();
    }

    /**
     * 获取员工人数
     */
    public Long getUserCount(Boolean onlyActive){
        //获取access_token
        String token = accessTokenUtils.getToken();
        try {
            DingTalkClient client = new DefaultDingTalkClient("https://oapi.dingtalk.com/topapi/user/count");
            OapiUserCountRequest req = new OapiUserCountRequest();
            req.setOnlyActive(onlyActive);
            OapiUserCountResponse rsp = client.execute(req, token);
            OapiUserCountResponse.CountUserResponse result = rsp.getResult();
            return result.getCount();
        } catch (ApiException e) {
            e.printStackTrace();
        }
        return 0L;
    }

    /**
     * 根据手机号查询企业账号用户
     */
    public OapiV2UserGetbymobileResponse.UserGetByMobileResponse getbymobile(String mobile, Boolean supportExclusiveAccountSearch){
        //获取access_token
        String token = accessTokenUtils.getToken();
        try {
            DingTalkClient client = new DefaultDingTalkClient("https://oapi.dingtalk.com/topapi/v2/user/getbymobile");
            OapiV2UserGetbymobileRequest req = new OapiV2UserGetbymobileRequest();
            req.setMobile(mobile);
            req.setSupportExclusiveAccountSearch(supportExclusiveAccountSearch);
            OapiV2UserGetbymobileResponse rsp = client.execute(req, token);
            return rsp.getResult();
        } catch (ApiException e) {
            e.printStackTrace();
        }
        return new OapiV2UserGetbymobileResponse.UserGetByMobileResponse();
    }

    /**
     * 根据unionid查询用户
     */
    public OapiUserGetbyunionidResponse.UserGetByUnionIdResponse getbyunionid(String unionId){
        //获取access_token
        String token = accessTokenUtils.getToken();
        try {
            DingTalkClient client = new DefaultDingTalkClient("https://oapi.dingtalk.com/topapi/user/getbyunionid");
            OapiUserGetbyunionidRequest req = new OapiUserGetbyunionidRequest();
            req.setUnionid(unionId);
            OapiUserGetbyunionidResponse rsp = client.execute(req, token);
            return rsp.getResult();
        } catch (ApiException e) {
            e.printStackTrace();
        }
        return new OapiUserGetbyunionidResponse.UserGetByUnionIdResponse();
    }

    /**
     * 获取管理员列表
     */
    public List<OapiUserListadminResponse.ListAdminResponse> getAdminList(){
        //获取access_token
        String token = accessTokenUtils.getToken();
        try {
            DingTalkClient client = new DefaultDingTalkClient("https://oapi.dingtalk.com/topapi/user/listadmin");
            OapiUserListadminRequest req = new OapiUserListadminRequest();
            OapiUserListadminResponse rsp = client.execute(req, token);
            return rsp.getResult();
        } catch (ApiException e) {
            e.printStackTrace();
        }
        return new ArrayList<>();
    }

    /**
     * 获取管理员通讯录权限范围
     */
    public List<Long> getAdminScope(String userId){
        //获取access_token
        String token = accessTokenUtils.getToken();
        try {
            DingTalkClient client = new DefaultDingTalkClient("https://oapi.dingtalk.com/topapi/user/get_admin_scope");
            OapiUserGetAdminScopeRequest req = new OapiUserGetAdminScopeRequest();
            req.setUserid(userId);
            OapiUserGetAdminScopeResponse rsp = client.execute(req, token);
            return rsp.getDeptIds();
        } catch (ApiException e) {
            e.printStackTrace();
        }
        return new ArrayList<>();
    }
}
