package com.mortals.xhx.module.attendance.service.impl;

import com.mortals.framework.model.PageInfo;
import com.mortals.framework.model.Result;
import com.mortals.framework.util.DateUtils;
import com.mortals.framework.util.StringUtils;
import com.mortals.xhx.common.code.LeaveTypeEnum;
import com.mortals.xhx.common.utils.BeanUtil;
import com.mortals.xhx.module.attendance.dao.AttendanceSummaryDao;
import com.mortals.xhx.module.attendance.model.AttendanceStaffStatEntity;
import com.mortals.xhx.module.attendance.model.AttendanceStaffStatQuery;
import com.mortals.xhx.module.attendance.model.AttendanceStatQuery;
import com.mortals.xhx.module.attendance.model.vo.AttendanceSummaryQuery;
import com.mortals.xhx.module.attendance.model.vo.ErrorSummaryVo;
import com.mortals.xhx.module.attendance.model.vo.LeaveSummaryVo;
import com.mortals.xhx.module.attendance.model.vo.VacationBalanceSummaryVo;
import com.mortals.xhx.module.attendance.service.AttendanceStaffStatService;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.mortals.framework.service.impl.AbstractCRUDServiceImpl;
import com.mortals.framework.exception.AppException;
import com.mortals.framework.model.Context;
import com.mortals.xhx.module.attendance.dao.AttendanceStatDao;
import com.mortals.xhx.module.attendance.model.AttendanceStatEntity;
import com.mortals.xhx.module.attendance.service.AttendanceStatService;

import java.math.BigDecimal;
import java.util.Calendar;
import java.util.Date;
import java.util.List;

/**
 * AttendanceStatService
 * 考勤汇总信息 service实现
 *
 * @author zxfei
 * @date 2023-04-08
 */
@Service("attendanceStatService")
public class AttendanceStatServiceImpl extends AbstractCRUDServiceImpl<AttendanceStatDao, AttendanceStatEntity, Long> implements AttendanceStatService {
    @Autowired
    private AttendanceStaffStatService attendanceStaffStatService;
    @Autowired
    private AttendanceSummaryDao attendanceSummaryDao;

    @Override
    protected void findAfter(AttendanceStatEntity entity, Context context, List<AttendanceStatEntity> list) throws AppException {
        //开始时间
        String startYears =entity.getStartTime().split("-",0)[0];
        Long startYear = Long.valueOf(startYears);
        String startMonths = entity.getStartTime().split("-",0)[1];
        Long startMonth =Long.valueOf(startMonths);
        String startDays= entity.getStartTime().split("-",0)[2];
        Long startDay =Long.valueOf(startDays);
        //结束时间
        String endYears =entity.getEndTime().split("-",0)[0];
        Long endYear = Long.valueOf(endYears);
        String endMonths = entity.getEndTime().split("-",0)[1];
        Long endMonth =Long.valueOf(endMonths);
        String endDays= entity.getEndTime().split("-",0)[2];
        Long endDay =Long.valueOf(endDays);
        list.forEach(item -> {
            AttendanceStaffStatQuery staffStatQuery = new AttendanceStaffStatQuery();
            staffStatQuery.setStaffId(entity.getStaffId());
            if (startYear==endYear){
                staffStatQuery.setYear(startYear.intValue());
            }else {
                staffStatQuery.setYearStart(startYear.intValue());
                staffStatQuery.setYearEnd(endYear.intValue());
            }
            if (startMonth==endMonth){
                staffStatQuery.setMonth(startMonth.intValue());
            }else {
                staffStatQuery.setMonthStart(startMonth.intValue());
                staffStatQuery.setMonthEnd(startMonth.intValue());
            }
            if (startDay==endDay){
                staffStatQuery.setDay(startDay.intValue());
            }else {
                staffStatQuery.setDayStart(startDay.intValue());
                staffStatQuery.setDayEnd(startDay.intValue());
            }
            //比较 year  month day todo
//            staffStatQuery.setYear(year);//相等
//            staffStatQuery.setYearStart();
//            staffStatQuery.setYearEnd();
            //month and day  同上
            List<AttendanceStaffStatEntity> attendanceStaffStatEntities = attendanceStaffStatService.find(staffStatQuery);
           item.setAttendanceStaffStatEntities(attendanceStaffStatEntities);
        });
        super.findAfter(entity, context, list);
    }

    @Override
    protected void findAfter(AttendanceStatEntity params, PageInfo pageInfo, Context context, List<AttendanceStatEntity> list) throws AppException {
        //开始时间
        String startYears =params.getStartTime().split("-",0)[0];
        Long startYear = Long.valueOf(startYears);
        String startMonths = params.getStartTime().split("-",0)[1];
        Long startMonth =Long.valueOf(startMonths);
        String startDays= params.getStartTime().split("-",0)[2];
        Long startDay =Long.valueOf(startDays);
        //结束时间
        String endYears =params.getEndTime().split("-",0)[0];
        Long endYear = Long.valueOf(endYears);
        String endMonths = params.getEndTime().split("-",0)[1];
        Long endMonth =Long.valueOf(endMonths);
        String endDays= params.getEndTime().split("-",0)[2];
        Long endDay =Long.valueOf(endDays);
        list.forEach(item -> {
            AttendanceStaffStatQuery staffStatQuery = new AttendanceStaffStatQuery();
            staffStatQuery.setStaffId(item.getStaffId());
            if (startYear==endYear){
                staffStatQuery.setYear(startYear.intValue());
            }else {
                staffStatQuery.setYearStart(startYear.intValue());
                staffStatQuery.setYearEnd(endYear.intValue());
            }
            if (startMonth==endMonth){
                staffStatQuery.setMonth(startMonth.intValue());
            }else {
                staffStatQuery.setMonthStart(startMonth.intValue());
                staffStatQuery.setMonthEnd(endMonth.intValue());
            }
            if (startDay==endDay){
                staffStatQuery.setDay(startDay.intValue());
            }else {
                staffStatQuery.setDayStart(startDay.intValue());
                staffStatQuery.setDayEnd(endDay.intValue());
            }
            //比较 year  month day todo
//            staffStatQuery.setYear(year);//相等
//            staffStatQuery.setYearStart();
//            staffStatQuery.setYearEnd();
            //month and day  同上
            List<AttendanceStaffStatEntity> attendanceStaffStatEntities = attendanceStaffStatService.find(staffStatQuery);
            item.setAttendanceStaffStatEntities(attendanceStaffStatEntities);
        });
        super.findAfter(params, pageInfo, context, list);
    }

    @Override
    public void doAttendanceSummary(AttendanceSummaryQuery query) {
        try {
            long currentTime = System.currentTimeMillis();
            if (query == null) {
                query = new AttendanceSummaryQuery();
            }
            if (StringUtils.isEmpty(query.getSummaryTime())) {
                Calendar now = Calendar.getInstance();
                now.setTime(new Date());
                now.add(Calendar.DAY_OF_MONTH, -1); //默认查最近30天数据
                query.setSummaryTime(DateUtils.getStrDate(now.getTime()));
            }
            Calendar calendar = Calendar.getInstance();
            calendar.setTime(DateUtils.StrToDate(query.getSummaryTime()));
            int dayOfWeek = calendar.get(Calendar.DAY_OF_WEEK);
            if(dayOfWeek==Calendar.SATURDAY||dayOfWeek==Calendar.SUNDAY){
                return;
            }
            log.info("开始汇总[" + query.getSummaryTime() + "]考勤.....");
            //汇总当前日期假期余额
            List<VacationBalanceSummaryVo> vacationBalanceSummaryVoList = attendanceSummaryDao.getVacationBalanceSummary(query);
            if (CollectionUtils.isNotEmpty(vacationBalanceSummaryVoList)) {
                for (VacationBalanceSummaryVo item : vacationBalanceSummaryVoList) {
                    AttendanceStatEntity temp = this.selectOne(new AttendanceStatQuery().staffId(item.getStaffId()).year(item.getYear()).month(item.getMonth()).day(item.getDay()));
                    if (temp == null) {
                        AttendanceStatEntity attendanceStatEntity = new AttendanceStatEntity();
                        attendanceStatEntity.initAttrValue();
                        BeanUtils.copyProperties(item, attendanceStatEntity, BeanUtil.getNullPropertyNames(item));
                        attendanceStatEntity.setCreateTime(new Date());
                        attendanceStatEntity.setCreateUserId(1l);
                        attendanceStatEntity.setGoTimes(1);   //默认当天全勤
                        this.dao.insert(attendanceStatEntity);
                    } else {
                        BeanUtils.copyProperties(item, temp, BeanUtil.getNullPropertyNames(item));
                        temp.setUpdateTime(new Date());
                        this.dao.update(temp);
                    }
                }
            }
            log.info("完成汇总当前日期假期余额.....");
            //汇总当前日期请假情况
            List<LeaveSummaryVo> leaveSummaryVoList = attendanceSummaryDao.getLeaveSummary(query);
            if (CollectionUtils.isNotEmpty(leaveSummaryVoList)) {
                BigDecimal hour = new BigDecimal(3600);
                for (LeaveSummaryVo item : leaveSummaryVoList) {
                    String attendanceSummary = "";
                    AttendanceStatEntity temp = this.selectOne(new AttendanceStatQuery().staffId(item.getStaffId()).year(item.getYear()).month(item.getMonth()).day(item.getDay()));
                    if (temp != null) {
                        BigDecimal leaveTime = new BigDecimal(item.getDuration()).divide(hour, 1, BigDecimal.ROUND_HALF_DOWN);
                        temp.setGoTimes(0);     //默认只要有请假，当天就不算全勤
                        LeaveTypeEnum leaveTypeEnum = LeaveTypeEnum.getByValue(item.getLeaveType());
                        if(leaveTypeEnum == null){
                            leaveTypeEnum = LeaveTypeEnum.事假;  //默认为事假
                        }
                        attendanceSummary = leaveTypeEnum.getDesc()+"*1";
                        switch (leaveTypeEnum) {
                            case 事假:
                                temp.setPersonalLeave(leaveTime);
                                break;
                            case 调休:
                                temp.setCompensatedLeaveDays(leaveTime);
                                break;
                            case 病假:
                                temp.setSickLeave(leaveTime);
                                break;
                            case 年假:
                                temp.setAnnualLeaveDays(leaveTime);
                                break;
                            case 产假:
                                temp.setMaternityLeave(leaveTime);
                                break;
                            case 陪产假:
                                temp.setPaternityLeaveDays(leaveTime);
                                break;
                            case 婚假:
                                temp.setMarriageLeave(leaveTime);
                                break;
                            case 例假:
                                temp.setMenstrualLeaveDays(leaveTime);
                                break;
                            case 哺乳假:
                                temp.setBreastfeedingLeaveDays(leaveTime);
                                break;
                            case 丧假:
                                temp.setFuneralLeave(leaveTime);
                                break;
                            default:
                                temp.setPersonalLeave(leaveTime);
                                break;
                        }
                        this.dao.update(temp);
                    }

                    AttendanceStaffStatEntity staffStat = new AttendanceStaffStatEntity();
                    staffStat.initAttrValue();
                    BeanUtils.copyProperties(item, staffStat, BeanUtil.getNullPropertyNames(item));
                    staffStat.setAttendanceSummary(attendanceSummary);
                    AttendanceStaffStatEntity staffStatTemp = attendanceStaffStatService.selectOne(new AttendanceStaffStatQuery().staffId(item.getStaffId()).year(item.getYear()).month(item.getMonth()).day(item.getDay()));
                    if(staffStatTemp!=null){
                        staffStat.setId(staffStatTemp.getId());
                        staffStat.setUpdateTime(new Date());
                        attendanceStaffStatService.update(staffStat);
                    }else {
                        staffStat.setCreateTime(new Date());
                        staffStat.setCreateUserId(1l);
                        attendanceStaffStatService.save(staffStat);
                    }
                }
            }
            log.info("完成汇总当前日期请假情况.....");
            //汇总当前日期异常考勤
            List<ErrorSummaryVo> errorSummaryVoList = attendanceSummaryDao.getErrorSummary(query);
            if (CollectionUtils.isNotEmpty(errorSummaryVoList)) {
                for (ErrorSummaryVo item : errorSummaryVoList) {
                    AttendanceStatEntity temp = this.selectOne(new AttendanceStatQuery().staffId(item.getStaffId()).year(item.getYear()).month(item.getMonth()).day(item.getDay()));
                    if (temp != null) {
                        BeanUtils.copyProperties(item, temp, BeanUtil.getNullPropertyNames(item));
                        temp.setGoTimes(0);     //默认只要有异常考勤，当天就不算全勤
                        this.dao.update(temp);
                    }
                    String attendanceSummary = "";
                    if(item.getMorningTimes()>0){
                        attendanceSummary+="缺卡*"+item.getMorningTimes()+"次;";
                    }
                    if(item.getLateTimes()>0){
                        attendanceSummary+="迟到*"+item.getLateTimes()+"次;";
                    }
                    if(item.getOvertimeTimes()>0){
                        attendanceSummary+="早退*"+item.getOvertimeTimes()+"次;";
                    }
                    AttendanceStaffStatEntity staffStat = new AttendanceStaffStatEntity();
                    staffStat.initAttrValue();
                    BeanUtils.copyProperties(item, staffStat, BeanUtil.getNullPropertyNames(item));
                    staffStat.setAttendanceSummary(attendanceSummary);
                    AttendanceStaffStatEntity staffStatTemp = attendanceStaffStatService.selectOne(new AttendanceStaffStatQuery().staffId(item.getStaffId()).year(item.getYear()).month(item.getMonth()).day(item.getDay()));
                    if(staffStatTemp!=null){
                        staffStat.setId(staffStatTemp.getId());
                        staffStat.setUpdateTime(new Date());
                        attendanceStaffStatService.update(staffStat);
                    }else {
                        staffStat.setCreateTime(new Date());
                        staffStat.setCreateUserId(1l);
                        attendanceStaffStatService.save(staffStat);
                    }
                }
            }
            log.info("完成汇总当前日期异常考勤.....");
            log.info("日期:" + query.getSummaryTime() + ",考勤汇总执行完成,耗时:" + (System.currentTimeMillis() - currentTime) + "毫秒....");
        }catch (Exception e){
            log.error("考勤汇总出错",e);
        }
    }

    @Override
    public Result<AttendanceStatEntity> findExt(AttendanceSummaryQuery params, PageInfo pageInfo, Context context) throws AppException {
        if(params==null){
            params = new AttendanceSummaryQuery();
            Calendar now = Calendar.getInstance();
            now.setTime(new Date());
            now.add(Calendar.DAY_OF_MONTH, -30); //默认查最近30天数据
            params.setSummaryTimeStart(DateUtils.getStrDate(now.getTime()));
            params.setSummaryTimeEnd(DateUtils.getCurrStrDate());
        }
        if(StringUtils.isNotEmpty(params.getStaffName())){
            params.setStaffName("%"+params.getStaffName()+"%");
        }
        if(StringUtils.isNotEmpty(params.getPhoneNumer())){
            params.setPhoneNumer("%"+params.getPhoneNumer()+"%");
        }
        if(pageInfo == null){
            pageInfo = new PageInfo(10);
        }
        Result<AttendanceStatEntity> result = dao.getListExt(params,pageInfo);
        if(CollectionUtils.isNotEmpty(result.getList())){
            for(AttendanceStatEntity item:result.getList()){
                params.setStaffId(item.getStaffId());
                List<AttendanceStaffStatEntity> statEntities = attendanceStaffStatService.getListExt(params);
                if(CollectionUtils.isNotEmpty(statEntities)){
                    item.setAttendanceStaffStatEntities(statEntities);
                }
            }
        }
        return result;
    }
}