package com.jpsoft.shinestar.modules.base.service.impl;

import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.jpsoft.shinestar.modules.base.entity.PersonDeviceLog;
import com.jpsoft.shinestar.modules.base.entity.WorkPersonScheduling;
import com.jpsoft.shinestar.modules.base.entity.WorkShiftInfo;
import com.jpsoft.shinestar.modules.base.service.*;
import com.jpsoft.shinestar.modules.base.dao.WorkOverPersonDAO;
import com.jpsoft.shinestar.modules.base.entity.WorkOverPerson;
import com.jpsoft.shinestar.modules.common.dto.Sort;
import com.jpsoft.shinestar.modules.sys.entity.DataDictionary;
import com.jpsoft.shinestar.modules.sys.service.DataDictionaryService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.joda.time.DateTime;
import org.joda.time.Minutes;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * @author 墨鱼_mo
 * @date 2021-5-21 9:21
 */
@Slf4j
@Transactional
@Component(value="workOverPersonService")
public class WorkOverPersonServiceImpl implements WorkOverPersonService {

    @Resource(name="workOverPersonDAO")
    private WorkOverPersonDAO workOverPersonDAO;

    @Autowired
    private PersonDeviceLogService personDeviceLogService;

    @Autowired
    private DataDictionaryService dataDictionaryService;

    @Autowired
    private WorkOverService workOverService;

    @Autowired
    private WorkPersonSchedulingService workPersonSchedulingService;

    @Autowired
    private WorkShiftInfoService workShiftInfoService;

    @Override
    public WorkOverPerson get(String id) {
        // TODO Auto-generated method stub
        return workOverPersonDAO.get(id);
    }

    @Override
    public int insert(WorkOverPerson model) {
        // TODO Auto-generated method stub
        //model.setId(UUID.randomUUID().toString());

        return workOverPersonDAO.insert(model);
    }

    @Override
    public int update(WorkOverPerson model) {
        // TODO Auto-generated method stub
        return workOverPersonDAO.update(model);
    }

    @Override
    public int delete(String id) {
        // TODO Auto-generated method stub
        return workOverPersonDAO.delete(id);
    }

    @Override
    public int deletePerson(String id) {
        // TODO Auto-generated method stub
        return workOverPersonDAO.deletePerson(id);
    }

    @Override
    public boolean exist(String id) {
        // TODO Auto-generated method stub
        int count = workOverPersonDAO.exist(id);

        return count > 0 ? true : false;
    }

    @Override
    public List<WorkOverPerson> list() {
        // TODO Auto-generated method stub
        return workOverPersonDAO.list();
    }

    @Override
    public Page<WorkOverPerson> pageSearch(Map<String, Object> searchParams, int pageNumber, int pageSize, boolean count, List<Sort> sortList) {
        Page<WorkOverPerson> page = PageHelper.startPage(pageNumber,pageSize,count).doSelectPage(()->{
            workOverPersonDAO.search(searchParams,sortList);
        });

        return page;
    }

    @Override
    public List<WorkOverPerson> findByWorkOverId(String workOverId) {
        return workOverPersonDAO.findByWorkOverId(workOverId);
    }

    @Override
    public WorkOverPerson findOneByPersonIdAndDate(Long personId, Date attendanceDate) {
        return workOverPersonDAO.findOneByPersonIdAndDate(personId,attendanceDate);
    }

    @Override
    public List<WorkOverPerson> findByPersonIdAndSEDate(Long personId, Date startDate,Date endDate){
        return workOverPersonDAO.findByPersonIdAndSEDate(personId,startDate,endDate);
    }

    @Override
    public WorkOverPerson findOneByPersonIdAndOffsetMinute(Long personId, Date recordTime, int earlyMinutes, int delayMinutes) {
        return workOverPersonDAO.findOneByPersonIdAndOffsetMinute(personId,recordTime,earlyMinutes,delayMinutes);
    }

    @Override
    public List<Map> findUnFinishByDate(Date startDate, Date endDate) {
        return workOverPersonDAO.findUnFinishByDate(startDate, endDate);
    }

    @Override
    public int updateFinishTime(String day) {
        int affectCount = 0;

        try {
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm");
            Date startDate = sdf.parse(day + " 00:00");
            Date endDate = sdf.parse(day + " 23:59");

            List<DataDictionary> ddList = dataDictionaryService.findByCatalogName("设备用途");

            String scene = "";

            for (DataDictionary dd : ddList) {
                if (dd.getName().indexOf("考勤") != -1) {
                    scene = dd.getValue();
                    break;
                }
            }

            //查询当天申请加班记录
            List<Map> mapList = findUnFinishByDate(startDate, endDate);

            for (Map map : mapList) {
                String id = map.get("id_").toString();
                Long personId = Long.valueOf(map.get("person_id").toString());
                DateTime startTime = new DateTime((Date) map.get("start_time"));
                DateTime endTime = new DateTime((Date) map.get("end_time"));

                List<PersonDeviceLog> personDeviceLogs = personDeviceLogService.findByPersonAndDateAndScene(personId,
                        startTime.plusHours(-1).toDate(), endTime.plusHours(2).toDate(), scene);

                boolean exist = false;

                //取最后一条
                if (personDeviceLogs.size() > 0) {
                    PersonDeviceLog personDeviceLog = personDeviceLogs.get(personDeviceLogs.size() - 1);

                    //最后一条打卡记录>加班开始时间+30分钟
                    if(personDeviceLog.getRecordTime().after(startTime.plusMinutes(30).toDate())){
                        exist = true;

                        boolean result = workOverService.punchIn(personDeviceLog.getDeviceNo(), personDeviceLog.getPersonId(), personDeviceLog.getRecordTime());

                        if (result) {
                            affectCount++;
                        }
                    }
                }

                if(!exist){
                    boolean allowUpdate = false;

                    //查询该员工半小时内是否还有加班，如果有则直接取计划结束时间作为实际完成时间
                    WorkOverPerson nextWorkOverPerson = findOneByPersonIdAndDate(personId, endTime.plusMinutes(30).toDate());

                    if (nextWorkOverPerson != null) {
                        allowUpdate = true;
                    }
                    else {
                        //加班结束时间是否与上班时间重复
                        SimpleDateFormat sdf1 = new SimpleDateFormat("yyyy-MM-dd");
                        WorkPersonScheduling workPersonScheduling = workPersonSchedulingService.findByPersonIdSchedulingDay(personId, sdf1.parse(day));

                        if(workPersonScheduling!=null) {
                            String shiftIds = workPersonScheduling.getShiftIds();

                            if (StringUtils.isNotEmpty(shiftIds)) {
                                String[] shiftIdArr = shiftIds.split(",");

                                List<WorkShiftInfo> shiftList = new ArrayList<>();

                                for (String shiftId : shiftIdArr) {
                                    WorkShiftInfo workShiftInfo = workShiftInfoService.get(shiftId);

                                    if (workShiftInfo != null) {
                                        if (!workShiftInfo.getNumber().equals("0")) {
                                            shiftList.add(workShiftInfo);
                                        }
                                    }
                                }

                                if (shiftList.size() > 0) {
                                    //按照上班考勤开始时间排序
                                    shiftList.sort(Comparator.comparing(e -> e.getWorkStartTime()));

                                    SimpleDateFormat fullFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm");

                                    //上班考勤开始时间
                                    DateTime workTime = new DateTime(fullFormat.parse(day + " " + shiftList.get(0).getWorkTime()));

                                    int minutes = Minutes.minutesBetween(new DateTime(endTime),new DateTime(workTime)).getMinutes();

                                    if(Math.abs(minutes)<=30){
                                        allowUpdate = true;
                                    }
                                }
                            }
                        }
                    }

                    if(allowUpdate) {
                        WorkOverPerson workOverPerson = get(id);

                        if (workOverPerson.getBeginTime() == null) {
                            workOverPerson.setBeginTime(startTime.toDate());
                        }

                        workOverPerson.setFinishTime(endTime.toDate());

                        int minutes = (int) Minutes.minutesBetween(startTime, new DateTime(workOverPerson.getFinishTime())).getMinutes();
                        workOverPerson.setDuration(minutes);

                        int intHours = minutes / 60;
                        int intMinutes = minutes % 60;
                        workOverPerson.setDurationStr(intHours + "小时" + intMinutes + "分钟");

                        workOverPerson.setUpdateTime(new Date());

                        update(workOverPerson);
                    }
                }
            }
        }
        catch (Exception ex){
            log.error(ex.getMessage(),ex);
        }

        return affectCount;
    }
}
