package com.mortals.xhx.daemon.task;

import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUnit;
import cn.hutool.core.date.DateUtil;
import com.mortals.framework.exception.AppException;
import com.mortals.framework.service.ITask;
import com.mortals.framework.service.ITaskExcuteService;
import com.mortals.framework.util.ThreadPool;
import com.mortals.xhx.common.utils.AddAttendThread;
import com.mortals.xhx.module.attendance.model.AttendanceLeaveRecordQuery;
import com.mortals.xhx.module.attendance.model.AttendanceRecordHikQuery;
import com.mortals.xhx.module.attendance.service.AttendanceLeaveRecordService;
import com.mortals.xhx.module.attendance.service.AttendanceRecordHikService;
import com.mortals.xhx.module.door.model.DoorEntity;
import com.mortals.xhx.module.door.model.DoorQuery;
import com.mortals.xhx.module.door.service.DoorService;
import com.mortals.xhx.module.hik.door.model.req.door.HikDoorEventReq;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StopWatch;

import java.util.Date;
import java.util.List;

/**
 * 同步获取本周门禁事件与计算
 */
@Slf4j
@Service("SyncDoorsEventWeekTask")
public class SyncDoorsEventWeekTaskImpl implements ITaskExcuteService {

    @Autowired
    private AttendanceRecordHikService recordHikService;
    @Autowired
    private AttendanceLeaveRecordService attendanceLeaveRecordService;
    @Autowired
    private DoorService doorService;


    @Value("${dingtalk.domain:}")
    protected String domain;

    @Value("${hik.host:}")
    protected String hikhost;

    @Override
    public void excuteTask(ITask task) throws AppException {
        //同步本周所以人的门禁事件
        log.info("同步本周所有的门禁事");
        DateTime weekStart = DateUtil.offsetDay(new Date(), -10);
        AttendanceRecordHikQuery hikEntity = new AttendanceRecordHikQuery();
        hikEntity.setAttendanceDateStart(DateUtil.format(weekStart, "yyyy-MM-dd"));
        hikEntity.setAttendanceDateEnd(DateUtil.today());

        //天数区间分段计算
        DateTime attendStart = DateUtil.parseDate(hikEntity.getAttendanceDateStart());
        DateTime attendEnd = DateUtil.parseDate(hikEntity.getAttendanceDateEnd());
        Long compare = DateUtil.between(attendEnd, attendStart, DateUnit.DAY);
        if (!ObjectUtils.isEmpty(hikhost)) {
            log.info("同步海康云主机");
            StopWatch stopWatch = new StopWatch("stopwatch attend1");
            log.info("考勤计算天数区间：{}", compare);
            for (int i = 0; i <= compare.intValue(); i++) {
                DateTime curDate = DateUtil.offsetDay(attendStart, i);
                log.info("考勤计算日期：{}", curDate.toDateStr());
                stopWatch.start("执行本地方法");
                hikEntity.setAttendanceDateStart(curDate.toDateStr());
                hikEntity.setAttendanceDateEnd(curDate.toDateStr());

                recordHikService.syncDoorEvents(hikEntity);
                recordHikService.deletFakeRecord(hikEntity, null);
                // recordHikService.buildSourceHikRecord(hikEntity, null);
                stopWatch.stop();
                log.info("考勤计算日期：{} 完成,耗时：{}ms", curDate.toDateStr(), stopWatch.getLastTaskTimeMillis());
            }

        } else {
            //todo
            log.info("直连海康考勤设备");
            StopWatch stopWatch = new StopWatch("stopwatch attend1");
            log.info("考勤计算天数区间：{}", compare);
            for (int i = 0; i <= compare.intValue(); i++) {
                DateTime curDate = DateUtil.offsetDay(attendStart, i);
                log.info("考勤计算日期：{}", curDate.toDateStr());
                stopWatch.start("执行本地方法");
                HikDoorEventReq hikDoorEventReq = new HikDoorEventReq();
                hikDoorEventReq.setStartTime(curDate.toJdkDate());
                hikDoorEventReq.setEndTime(curDate.toJdkDate());
                List<DoorEntity> doorEntities = doorService.find(new DoorQuery());
                for (DoorEntity doorEntity : doorEntities) {
                    doorService.syncDoorDeviceEvents(doorEntity, hikDoorEventReq);
                }
                hikEntity.setAttendanceDateStart(curDate.toDateStr());
                hikEntity.setAttendanceDateEnd(curDate.toDateStr());
                recordHikService.deletFakeRecord(hikEntity, null);
                stopWatch.stop();
                log.info("考勤计算日期：{} 完成,耗时：{}ms", curDate.toDateStr(), stopWatch.getLastTaskTimeMillis());

            }
        }
        log.info("开始计算及统计最近7天考勤！");
        AddAttendThread addAttendThread = new AddAttendThread(recordHikService, hikEntity, null);
        ThreadPool.getInstance().execute(addAttendThread);
        //同步最近钉钉请假事件
        checkDingDingEvent(attendStart, attendEnd, hikEntity);
    }

    private void checkDingDingEvent(DateTime attendStart, DateTime attendEnd, AttendanceRecordHikQuery hikEntity) {
        if (ObjectUtils.isEmpty(domain)) return;

        log.info("开始同步钉钉请假事件！");
        long between = DateUtil.between(attendStart, attendEnd, DateUnit.DAY, true);
        AttendanceLeaveRecordQuery query = new AttendanceLeaveRecordQuery();
        query.setStartTimeStart(hikEntity.getAttendanceDateStart());
        query.setEndTimeEnd(hikEntity.getAttendanceDateEnd());
        if (between > 120) return;
        Thread thread = new Thread(new Runnable() {
            @Override
            public void run() {
                attendanceLeaveRecordService.syncLeaveRecord(query, null);
            }
        });
        ThreadPool.getInstance().execute(thread);
    }


    @Override
    public void stopTask(ITask task) throws AppException {

    }
}
