package com.ads.business.service.impl;

import com.ads.business.service.TokenService;
import com.ads.business.service.data.GetLoginOutData;
import com.ads.common.data.JsonResult;
import com.ads.common.dingTalk.domain.ServiceResult;
import com.ads.common.dingTalk.domain.UserDTO;
import com.ads.common.dingTalk.service.DingTalkService;
import com.ads.common.exception.LoginException;
import com.ads.common.redis.RedisKeyConstant;
import com.ads.common.redis.RedisManager;
import com.alibaba.fastjson.JSONObject;
import com.dingtalk.api.request.*;
import com.dingtalk.api.response.OapiProcessWorkrecordCreateResponse;
import com.dingtalk.api.response.OapiRoleSimplelistResponse;
import com.dingtalk.api.response.OapiWorkrecordAddResponse;
import com.dingtalk.api.response.OapiWorkrecordGetbyuseridResponse;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;

/**
 * @Return
 * @Author hou
 * @Date 2021/9/3 11:11
 * @Destription
 */
@Slf4j
@Service
public class TokenServiceImpl implements TokenService {

    @Resource
    private DingTalkService dingTalkService;

    @Resource
    private RedisManager redisManager;

    @Override
    public String getAccessToken() {
        String accessToken = (String) redisManager.get(RedisKeyConstant.ACCESS_TOKEN);
        log.info("从redis获取accessToken:{}", accessToken);
        if (StringUtils.isNotBlank(accessToken)) {
            return accessToken;
        }
        ServiceResult<String> result = dingTalkService.getAccessToken();
        if (!result.isSuccess()) {
            JsonResult.fail(result.getMessage());
        }
        return result.getResult();
    }

    @Override
    public JsonResult<String> getJsTicket() {
        String ticket = (String) redisManager.get(RedisKeyConstant.JS_TICKET);
        log.info("从redis获取jsTicket:{}", ticket);
        if (StringUtils.isNotBlank(ticket)) {
            return JsonResult.success(ticket);
        }
        String accessToken = getAccessToken();
        ServiceResult<String> result = dingTalkService.getJsTicket(accessToken);
        if (!result.isSuccess()) {
            JsonResult.fail(result.getMessage());
        }
        return JsonResult.success(result.getResult());
    }

    @Override
    public JsonResult<GetLoginOutData> getUserInfo(String token) {
        log.info("根据登陆人token获取用户详情信息");
        String dataStr= (String) redisManager.get(RedisKeyConstant.PREFIX + token);
        if (StringUtils.isNotBlank(dataStr)){
            GetLoginOutData data = JSONObject.parseObject(dataStr,GetLoginOutData.class);
            log.info("从redis获取用户信息 user:{}", data);
            if (!Objects.isNull(data)) {
                return JsonResult.success(data);
            }
        }

//        GetLoginOutData data = (GetLoginOutData) redisManager.get(token);
//        if (ObjectUtil.isNotEmpty(data)){
//            log.info("从redis获取用户信息 user:{}", data);
//            if (!Objects.isNull(data)) {
//                return JsonResult.success(data);
//            }
//        }

        String accessToken = getAccessToken();
        ServiceResult<String> userInfo = dingTalkService.getUserInfo(accessToken, token);
        if (!userInfo.isSuccess() || StringUtils.isBlank(userInfo.getResult())) {
            log.error("根据token获取用户信息失败");
            throw new LoginException();
        }
        UserDTO userDTO  = getUserById(userInfo.getResult());
        GetLoginOutData user = new GetLoginOutData();
        user.setUserId(userDTO.getUserid());
        user.setName(userDTO.getName());
        user.setHeadUrl(userDTO.getAvatar());
        user.setToken(token);
        user.setIsAdmin(userDTO.getIsAdmin());
        user.setRoleName(userDTO.getRoleName());
        user.setDeptName(userDTO.getDeptName());
        user.setDeptId(userDTO.getDeptId());
        user.setRoleId(userDTO.getRoleId());
        user.setMobile(userDTO.getMobile());
        redisManager.set(RedisKeyConstant.PREFIX + token, JSONObject.toJSONString(user), 60 * 30);
        return JsonResult.success(user);
    }

    @Override
    public List<String> getRoleUsersByIds(List<String> ids) {
        String accessToken = getAccessToken();
        ArrayList<String> list = new ArrayList<>();
        for (String id : ids) {
            ServiceResult<List<OapiRoleSimplelistResponse.OpenEmpSimple>> result = dingTalkService.getRoleUsers(accessToken, Long.valueOf(id));
            result.getResult().forEach(e -> list.add(e.getUserid()));
        }
        return list;
    }

    @Override
    public UserDTO getUserById(String userId) {
        String userDTOStr = (String) redisManager.get(RedisKeyConstant.PREFIX + userId);
        if (StringUtils.isNotBlank(userDTOStr)){
            UserDTO userDTO = JSONObject.parseObject(userDTOStr,UserDTO.class);
            log.info("从redis获取用户信息 user:{}", userDTO);
            if (!Objects.isNull(userDTO)) {
                return userDTO;
            }
        }
        String accessToken = getAccessToken();
        ServiceResult<UserDTO> user = dingTalkService.getUser(accessToken, userId);
        if (user.isSuccess()) {
            return user.getResult();
        }
        return new UserDTO();
    }

    @Override
    public JsonResult<OapiProcessWorkrecordCreateResponse.SaveFaceProcessInstanceResponse> createWorkRecord(OapiProcessWorkrecordCreateRequest.SaveFakeProcessInstanceRequest request) {
        String accessToken = getAccessToken();
        ServiceResult<OapiProcessWorkrecordCreateResponse.SaveFaceProcessInstanceResponse> workRecord = dingTalkService.createWorkRecord(accessToken, request);
        if (workRecord.isSuccess()) {
            return JsonResult.success(workRecord.getResult());
        }
        return JsonResult.fail("创建实例失败");
    }

    @Override
    public JsonResult updateWorkRecord(OapiProcessWorkrecordUpdateRequest.UpdateProcessInstanceRequest request) {
        String accessToken = getAccessToken();
        ServiceResult workRecord = dingTalkService.updateWorkRecord(accessToken, request);
        if (workRecord.isSuccess()) {
            return JsonResult.success();
        }
        return JsonResult.fail("更新实力状态失败");
    }

    @Override
    public JsonResult sendDingMessage(OapiMessageCorpconversationAsyncsendV2Request request) {
        String accessToken = getAccessToken();
        ServiceResult serviceResult = dingTalkService.sendDingMessage(accessToken, request);
        if (serviceResult.isSuccess()) {
            return JsonResult.success();
        }
        return JsonResult.fail("发送工作消息失败");
    }

    @Override
    public JsonResult<String> addWorkRecord(OapiWorkrecordAddRequest request) {
        String accessToken = getAccessToken();
        ServiceResult<OapiWorkrecordAddResponse> serviceResult = dingTalkService.addWorkRecord(accessToken, request);
        if (serviceResult.isSuccess()) {
            return JsonResult.success(serviceResult.getResult().getRecordId());
        }
        return JsonResult.fail("发送待办事项失败");
    }

    @Override
    public JsonResult workRecordUpdate(OapiWorkrecordUpdateRequest request) {
        String accessToken = getAccessToken();
        ServiceResult serviceResult = dingTalkService.workRecordUpdate(accessToken, request);
        if (serviceResult.isSuccess()) {
            return JsonResult.success();
        }
        return JsonResult.fail("更新待办事项状态失败");
    }

    @Override
    public JsonResult<List<OapiWorkrecordGetbyuseridResponse.WorkRecordVo>> getWorkRecordByUserId(OapiWorkrecordGetbyuseridRequest request) {
        String accessToken = getAccessToken();
        List<OapiWorkrecordGetbyuseridResponse.WorkRecordVo> list = new ArrayList<>();
        ServiceResult<OapiWorkrecordGetbyuseridResponse.PageResult> result = dingTalkService.getWorkRecordByUserId(accessToken, request);
        if (result.isSuccess() && CollectionUtils.isNotEmpty(result.getResult().getList())) {
            list.addAll(result.getResult().getList());
            if (result.getResult().getHasMore()) {
                request.setOffset(request.getOffset() + request.getLimit());
                list.addAll(getWorkRecordByUserId(request).getData());
            }
        }
        return JsonResult.success(list);
    }
}
