package com.mortals.xhx.daemon.task;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.PageUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSON;
import com.mortals.framework.common.Rest;
import com.mortals.framework.exception.AppException;
import com.mortals.framework.model.Context;
import com.mortals.framework.service.ITask;
import com.mortals.framework.service.ITaskExcuteService;
import com.mortals.framework.util.DateUtils;
import com.mortals.xhx.base.system.user.model.UserEntity;
import com.mortals.xhx.common.code.YesNoEnum;
import com.mortals.xhx.module.attendance.model.AttendanceRecordHikEntity;
import com.mortals.xhx.module.attendance.model.AttendanceRecordHikQuery;
import com.mortals.xhx.module.attendance.service.AttendanceRecordHikService;
import com.mortals.xhx.module.attendance.service.AttendanceStatService;
import com.mortals.xhx.module.hik.door.model.req.door.DoorEventReq;
import com.mortals.xhx.module.hik.door.model.rsp.door.DoorEventDataInfo;
import com.mortals.xhx.module.hik.door.service.IHikDoorService;
import com.mortals.xhx.module.staff.model.StaffEntity;
import com.mortals.xhx.module.staff.service.StaffService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.ObjectUtils;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * 同步获取下午海康门禁事件
 */
@Slf4j
@Service("SyncDoorsEventAfterTask")
public class SyncDoorsEventAfterTaskImpl implements ITaskExcuteService {

    @Autowired
    private AttendanceRecordHikService recordHikService;

    @Autowired
    private StaffService staffService;

    @Autowired
    private IHikDoorService hikDoorService;
    @Autowired
    private AttendanceStatService attendanceStatService;


    @Override
    public void excuteTask(ITask task) throws AppException {
        // syncDoorEvents();
        //判断时间段 不在时间段的 不做计算
        //早上9点 子晚上8点 计算
        Date beginDateTime = DateUtil.parseDateTime(DateUtil.today() + " 07:00:00");
        Date endDateTime = DateUtil.parseDateTime(DateUtil.today() + " 23:30:00");

        boolean in = DateUtil.isIn(new Date(), beginDateTime, endDateTime);
        if (in) {
            calculateAttendByDay();
        }

        //统计当日
        log.info("统计当日考勤");
        attendanceStatService.homeStat(null);
        log.info("统计当日考勤结束");
    }


    private void calculateAttendByDay() {
        Context context = new Context();
        UserEntity userEntity = new UserEntity();
        userEntity.setCreateUserId(1L);
        userEntity.setId(1L);
        userEntity.setCreateUserName("admin");
        userEntity.setCreateTime(new Date());
        context.setUser(userEntity);
        AttendanceRecordHikQuery recordHikQuery = new AttendanceRecordHikQuery();

        // Date todayStart = DateUtil.offsetHour(new Date(), -5).toJdkDate();
        //  recordHikQuery.setAttendanceDateStart(DateUtils.getCurrStrDate());
        recordHikQuery.setAttendanceDateStart(DateUtil.today());
        recordHikQuery.setAttendanceDateEnd(DateUtil.today());
        try {
            recordHikService.addAttendanceRecordByQuery(recordHikQuery, context);
        } catch (Exception e) {
            log.error("计算考勤异常", e);
        }
    }

    private void syncDoorEvents() {
        DoorEventReq doorEventReq = new DoorEventReq();
        List<Integer> eventTypes = new ArrayList<>();
        eventTypes.add(196885);
        eventTypes.add(196887);
        eventTypes.add(196893);
        eventTypes.add(196888);
        eventTypes.add(196889);
        eventTypes.add(196890);
        eventTypes.add(196891);
        doorEventReq.setEventTypes(eventTypes);
        // 获取当天的开始时间
        //  Date todayStart = DateUtil.offsetHour(new Date(), -5).toJdkDate();
        Date todayStart = DateUtil.beginOfDay(new Date());
        // 获取当天的结束时间
        Date todayEnd = DateUtil.endOfDay(new Date());
        doorEventReq.setStartTime(todayStart);
        doorEventReq.setEndTime(todayEnd);
        doorEventReq.setPageNo(1);
        doorEventReq.setPageSize(1);

        Rest<DoorEventDataInfo> doorEventsRest = hikDoorService.getDoorEvents(doorEventReq);
        log.info("doorEventsRest:{} msg:{}", doorEventsRest.getCode(), doorEventsRest.getMsg());
        if (doorEventsRest.getCode() == YesNoEnum.YES.getValue()) {
            //分页获取考勤数据
            Integer total = doorEventsRest.getData().getTotal();
            int pageCount = PageUtil.totalPage(total, 1000);
            for (int i = 1; i <= pageCount; i++) {
                doorEventReq.setPageNo(i);
                doorEventReq.setPageSize(1000);
                doorEventsRest = hikDoorService.getDoorEvents(doorEventReq);
                // log.info("doorEventsRest:{} msg:{},page:{}", doorEventsRest.getCode(), doorEventsRest.getMsg(), doorEventReq.getPageNo());
                getDoorEvents(doorEventsRest);
            }
        }
    }

    private void getDoorEvents(Rest<DoorEventDataInfo> doorEventsRest) {
        //同步当前考勤数据
        List<AttendanceRecordHikEntity> attRecords = doorEventsRest.getData().getList().stream().map(item -> {
            AttendanceRecordHikEntity recordHikEntity = new AttendanceRecordHikEntity();
            recordHikEntity.initAttrValue();

            if (ObjectUtils.isEmpty(item.getJobNo())) {
                log.info("jobNo is null ==>{}", JSON.toJSONString(item));
                return null;
            }

            StaffEntity staffCache = staffService.getExtCache(StrUtil.padPre(item.getJobNo(), 8, "0"));
            if (ObjectUtils.isEmpty(staffCache)) {
                log.info("staff is null !staffCode:{}", item.getJobNo());
                return null;
            }

            recordHikEntity.setStaffId(staffCache.getId());
            recordHikEntity.setStaffName(staffCache.getName());
            recordHikEntity.setWorkNum(staffCache.getWorkNum());
            recordHikEntity.setDeptId(staffCache.getDeptId());
            recordHikEntity.setDeptName(staffCache.getDeptName());
            recordHikEntity.setSalaId(staffCache.getSalaId());
            recordHikEntity.setSalaName(staffCache.getSalaName());
            recordHikEntity.setPositionId(staffCache.getPositionId());
            recordHikEntity.setPositionName(staffCache.getPositionName());

            recordHikEntity.setAttendanceDate(item.getEventTime());
            recordHikEntity.setAttendanceAddress(item.getDoorName());
            recordHikEntity.setEventSource("门禁点");
            recordHikEntity.setRemark(item.getEventId());
            recordHikEntity.setCreateTime(new Date());
            recordHikEntity.setCreateUserName("系统管理员");
            recordHikEntity.setCreateUserId(1L);
            return recordHikEntity;
        }).filter(f -> f != null).collect(Collectors.toList());
        log.info("attRecords size:{}", attRecords.size());
        List<String> eventIds = attRecords.parallelStream().filter(f -> !ObjectUtils.isEmpty(f) && !ObjectUtils.isEmpty(f.getRemark())).map(i -> i.getRemark()).collect(Collectors.toList());

        //查询当天考勤记录是否有重复的 有的 则不添加
        AttendanceRecordHikQuery recordHikQuery = new AttendanceRecordHikQuery();
        recordHikQuery.setAttendanceDateStart(DateUtil.format(DateUtil.beginOfDay(new Date()), "yyyy-MM-dd"));
        recordHikQuery.setAttendanceDateEnd(DateUtil.format(DateUtil.beginOfDay(new Date()), "yyyy-MM-dd"));
        recordHikQuery.setRemarkList(eventIds);
        Set<String> eventIdSet = recordHikService.find(recordHikQuery).parallelStream().map(i -> i.getRemark()).collect(Collectors.toSet());

        //去重 时分秒打卡的 也要去掉重复。
        List<AttendanceRecordHikEntity> saveRecordList = attRecords.stream().filter(f -> !eventIdSet.contains(f.getRemark())).collect(Collectors.toList());
        if (!ObjectUtils.isEmpty(saveRecordList)) {
            //单个插入 去掉重复时间段的打卡记录
            for (AttendanceRecordHikEntity recordHikEntity : saveRecordList) {
                try {
                    recordHikService.getDao().insert(recordHikEntity);
                } catch (Exception e) {
                    //log.error("基础考勤数据保存异常", e.getMessage());
                }
            }
        }
        log.info("saveRecordList size:{}", saveRecordList.size());
    }


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

    }
}
