package com.usoftchina.uas.office.dingtalk.task;

import com.dingtalk.api.response.OapiAttendanceListRecordResponse;
import com.usoftchina.dingtalk.sdk.OaSdk;
import com.usoftchina.uas.office.dingtalk.entity.CardLog;
import com.usoftchina.uas.office.dingtalk.entity.Employee;
import com.usoftchina.uas.office.dingtalk.entity.OutSign;
import com.usoftchina.uas.office.dingtalk.manage.service.DingTalkSettingService;
import com.usoftchina.uas.office.dingtalk.service.UasCardLogService;
import com.usoftchina.uas.office.dingtalk.service.UasEmployeeService;
import com.usoftchina.uas.office.dingtalk.service.UasOutSignService;
import com.usoftchina.uas.office.entity.DataCenter;
import com.usoftchina.uas.office.jdbc.DataSourceHolder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;

import java.time.LocalDate;
import java.time.ZoneId;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * @author yingp
 * @date 2020/2/16
 */
@Component
public class DingTalkCheckinTask {

    @Autowired
    private OaSdk oaSdk;

    @Autowired
    private UasEmployeeService employeeService;

    @Autowired
    private DingTalkSettingService settingService;

    @Autowired
    private UasCardLogService cardLogService;

    @Autowired
    private UasOutSignService outSignService;

    /**
     * 每次最多条数据
     */
    private final int maxSeed = 50;

    private final Logger logger = LoggerFactory.getLogger(DingTalkCheckinTask.class);

    /**
     * 抓取打卡数据
     */
    @Scheduled(fixedDelay = 300000, initialDelay = 30000)
    public void pullCheckinData() {
        DataCenter dataCenter = DataCenter.INSTANCE;
        if (null != dataCenter.getUsername() && null != dataCenter.getPassword() && null != dataCenter.getUrl()) {
            try {
                DataSourceHolder.set(dataCenter);
                List<Employee> employees = employeeService.getAll();
                if (!CollectionUtils.isEmpty(employees)) {
                    Map<String, Employee> employeeMap = employees.stream().collect(Collectors.toMap(Employee::getEm_ding, e -> e));
                    Long lastTime = settingService.getCheckinTime();
                    if (lastTime == null) {
                        lastTime = LocalDate.now().atStartOfDay(ZoneId.systemDefault()).toInstant().toEpochMilli();
                    }
                    Date now = new Date();
                    long unixStartTime = lastTime + 1;
                    long unixEndTime = now.getTime();
                    Stream.iterate(0, n -> n + 1)
                            .limit((int) Math.ceil((double) employees.size() / maxSeed)).forEach(page -> {
                                List<String> userList = employees.stream().skip(page * maxSeed).limit(maxSeed).map(Employee::getEm_ding).collect(Collectors.toList());
                        List<OapiAttendanceListRecordResponse.Recordresult> dataList = oaSdk.getAttendanceRecordList("Uas", userList, unixStartTime, unixEndTime);
                        saveCheckinData(employeeMap, dataList);
                    });
                    settingService.setCheckinTime(now);
                }
            } finally {
                DataSourceHolder.clear();
            }
        }
    }

    private void saveCheckinData(Map<String, Employee> employeeMap, List<OapiAttendanceListRecordResponse.Recordresult> dataList) {
        dataList.forEach(data -> {
            Employee employee = employeeMap.get(data.getUserId());
            logger.debug("get checkin data, user {}, type {}", employee.getEm_name(), data.getLocationResult());
            if ("Outside".equals(data.getLocationResult())) {
                // 外勤签到 插入外勤打卡记录
                outSignService.save(new OutSign(employee, data));
            } else {
                cardLogService.save(new CardLog(employee, data));
            }
        });
    }
}
