package com.galaxis.manatee.service;

import com.dingtalk.api.DingTalkClient;
import com.dingtalk.api.request.OapiProcessinstanceGetRequest;
import com.dingtalk.api.request.OapiProcessinstanceListidsRequest;
import com.dingtalk.api.response.OapiProcessinstanceGetResponse;
import com.dingtalk.api.response.OapiProcessinstanceListidsResponse;
import com.galaxis.manatee.constant.DingTalkConstant;
import com.galaxis.manatee.dao.DingTalkProcessInstanceDao;
import com.galaxis.manatee.entity.ding.DingTalkProcessInstance;
import com.taobao.api.ApiException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.time.ZoneOffset;
import java.time.temporal.ChronoUnit;
import java.util.*;

/**
 * 钉钉定时任务
 * @author zcj
 * @version 0.1
 * @date 2020/1/10 2:28 下午
 */
@Slf4j
@Service
public class DingTalkScheduledTask {

    /**
     * 审批Id列表客户端
     */
    private DingTalkClient processInstanceListIdsClient;

    /**
     * 审批实例客户端
     */
    private DingTalkClient processInstanceClient;

    /**
     * 钉钉审批实例保存方法
     */
    private DingTalkProcessInstanceDao dingTalkProcessInstanceDao;

    public DingTalkScheduledTask(DingTalkClient processInstanceListIdsClient, DingTalkClient processInstanceClient, DingTalkProcessInstanceDao dingTalkProcessInstanceDao) {
        this.processInstanceListIdsClient = processInstanceListIdsClient;
        this.processInstanceClient = processInstanceClient;
        this.dingTalkProcessInstanceDao = dingTalkProcessInstanceDao;
    }

    /**
     * 每小时更新
     */
    @Scheduled(fixedDelay = 3600000L)
    private void updateBusinessTripProcessInstance(){
    }

    /**
     * 每个小时定期更新出差申请数据
     */
    @Scheduled(fixedDelay = 3600000L)
    void updateBusinessTripProcessInstanceIdList() throws ApiException {
        updateProcessInstanceIdList(DingTalkConstant.PROCESS_CODE_BUSINESS_TRIP);
    }

    /**
     * 每小时根据出差申请Id跟新出差申请信息。
     */
    @Scheduled(fixedDelay = 3600000L)
    void updateProcessInstanceList() throws ApiException {
        updateProcessInstanceIdList(DingTalkConstant.PROCESS_CODE_MATERIAL_RESEND);
    }

    private void updateProcessInstanceIdList(String businessTripProcessCode) throws ApiException {
        boolean flag=true;
        //单个请求
        OapiProcessinstanceListidsRequest oapiProcessinstanceListidsRequest=new OapiProcessinstanceListidsRequest();
        oapiProcessinstanceListidsRequest.setProcessCode(businessTripProcessCode);
        oapiProcessinstanceListidsRequest.setStartTime(LocalDateTime.of(2019,1,1,0,0).toInstant(ZoneOffset.UTC).toEpochMilli());
        oapiProcessinstanceListidsRequest.setEndTime(LocalDateTime.now().toInstant(ZoneOffset.UTC).toEpochMilli());
        oapiProcessinstanceListidsRequest.setCursor(0L);
        oapiProcessinstanceListidsRequest.setSize(20L);
        while(flag){
            LocalDateTime start=LocalDateTime.now();
            OapiProcessinstanceListidsResponse oapiProcessinstanceListidsResponse=processInstanceListIdsClient.execute(oapiProcessinstanceListidsRequest,DingTalkConstant.DING_TALK_TOKEN);
            List<DingTalkProcessInstance> dingTalkProcessInstanceList=new ArrayList<>();
            if(oapiProcessinstanceListidsResponse.getErrcode()!=0){
                log.info(oapiProcessinstanceListidsResponse.getErrmsg());
                try {
                    Thread.sleep(5000);
                } catch (InterruptedException e) {
                    log.error(e.getMessage());
                }
                continue;
            }
            //逐个请求
            oapiProcessinstanceListidsResponse.getResult().getList().forEach(resultId->{
                Optional<DingTalkProcessInstance> instance=dingTalkProcessInstanceDao.findById(resultId);
                if(!instance.isEmpty()&&instance.get()==null){
                    //淘宝SDK方法
                    OapiProcessinstanceGetRequest request=new OapiProcessinstanceGetRequest();
                    request.setProcessInstanceId(resultId);
                    DingTalkProcessInstance dingTalkProcessInstance=new DingTalkProcessInstance(resultId,businessTripProcessCode);
                    try {
                        OapiProcessinstanceGetResponse oapiProcessinstanceGetResponse = processInstanceClient.execute(request, DingTalkConstant.DING_TALK_TOKEN);
                        dingTalkProcessInstance.setProcessInstance(oapiProcessinstanceGetResponse.getProcessInstance());
                    } catch (ApiException e) {
                        e.printStackTrace();
                    }
                    //淘宝SDK方法结束
                    dingTalkProcessInstanceList.add(dingTalkProcessInstance);
                }
            });

            //保存id列表和实例列表
            dingTalkProcessInstanceDao.saveAll(dingTalkProcessInstanceList);
            log.info(businessTripProcessCode+"下一个cursor为"+oapiProcessinstanceListidsResponse.getResult().getNextCursor()+"保存成功"+"耗时"+ ChronoUnit.SECONDS.between(start,LocalDateTime.now())+"秒");
            flag=null!=oapiProcessinstanceListidsResponse.getResult().getNextCursor();
            if (flag){
                oapiProcessinstanceListidsRequest.setCursor(oapiProcessinstanceListidsResponse.getResult().getNextCursor());
            }
        }
    }
}