package cn.iocoder.yudao.module.system.service.attendance.fixed;

import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.util.date.DateUtils;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import cn.iocoder.yudao.module.system.controller.admin.fixed.vo.AttendanceFixedPageReqVO;
import cn.iocoder.yudao.module.system.controller.admin.fixed.vo.AttendanceFixedSaveReqVO;
import cn.iocoder.yudao.module.system.controller.app.attendance.dto.AttendancePunchPageDTO;
import cn.iocoder.yudao.module.system.controller.app.attendance.vo.AttendancePunchPageVO;
import cn.iocoder.yudao.module.system.dal.dataobject.attendance.fixed.AttendanceFixedDO;
import cn.iocoder.yudao.module.system.dal.dataobject.attendance.group.AttendanceGroupDO;
import cn.iocoder.yudao.module.system.dal.mysql.attendance.fixed.AttendanceFixedMapper;
import cn.iocoder.yudao.module.system.service.attendance.AttendanceService;
import cn.iocoder.yudao.module.system.service.attendance.groupshift.AttendanceGroupShiftService;
import cn.iocoder.yudao.module.system.service.attendance.groupshiftitem.AttendanceGroupShiftItemService;
import cn.iocoder.yudao.module.system.service.attendance.punch.PunchService;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.Lazy;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.validation.annotation.Validated;

import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.Date;
import java.util.List;

import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
import static cn.iocoder.yudao.module.system.enums.ErrorCodeConstants.FIXED_NOT_EXISTS;

/**
 * 固定班制考勤设置 Service 实现类
 *
 * @author 艾楷
 */
@Service("fixed")
@Validated
@Slf4j
public class AttendanceFixedServiceImpl implements AttendanceFixedService, PunchService {
    @Resource
    private AttendanceFixedMapper attendanceFixedMapper;
    @Resource
    @Lazy // 避免依赖循环
    private AttendanceService attendanceService;

    @Override
    public Long createFixed(AttendanceFixedSaveReqVO createReqVO) {
        // 插入
        AttendanceFixedDO fixed = BeanUtils.toBean(createReqVO, AttendanceFixedDO.class);
        attendanceFixedMapper.insert(fixed);
        // 返回
        return fixed.getId();
    }

    @Override
    public void updateFixed(AttendanceFixedSaveReqVO updateReqVO) {
        // 校验存在
        validateFixedExists(updateReqVO.getId());
        // 更新
        AttendanceFixedDO updateObj = BeanUtils.toBean(updateReqVO, AttendanceFixedDO.class);
        attendanceFixedMapper.updateById(updateObj);
    }

    @Override
    public void deleteFixed(Long id) {
        // 校验存在
        validateFixedExists(id);
        // 删除
        attendanceFixedMapper.deleteById(id);
    }

    private void validateFixedExists(Long id) {
        if (attendanceFixedMapper.selectById(id) == null) {
            throw exception(FIXED_NOT_EXISTS);
        }
    }

    @Override
    public AttendanceFixedDO getFixed(Long id) {
        return attendanceFixedMapper.selectById(id);
    }

    @Override
    public PageResult<AttendanceFixedDO> getFixedPage(AttendanceFixedPageReqVO pageReqVO) {
        return attendanceFixedMapper.selectPage(pageReqVO);
    }

    @Override
    public AttendanceFixedDO getByGroupIdAndWeek(Long attendanceGroupId, Integer week) {
        List<AttendanceFixedDO> list = attendanceFixedMapper.selectList(new LambdaQueryWrapper<AttendanceFixedDO>()
                .eq(attendanceGroupId != null, AttendanceFixedDO::getAttendanceGroupId, attendanceGroupId)
                .eq(week != null, AttendanceFixedDO::getWeekTime, week));
        if (!list.isEmpty()) {
            return list.get(0);
        }
        return null;
    }

    @Override
    public AttendancePunchPageVO getPunchPage(AttendancePunchPageDTO dto) {
        AttendancePunchPageVO vo = new AttendancePunchPageVO();
        vo.setActivationGroup(dto.getActivationGroup());
        AttendanceGroupDO activationGroup = dto.getActivationGroup();
        // -- 判断是否根据节假日自动排班 - 如果是的话 - 根据排班的来
        Boolean isHolidayFlag = AttendanceGroupDO.TRUE.equals(activationGroup.getAutoHolidaysFlag()) ?
                attendanceService.isHoliday(dto.getLocalDateTime()) : null;
        // -- 当前是节假日 并且是放假
        if (isHolidayFlag != null && isHolidayFlag) {
            return vo.setTodayNeedAttendance(AttendanceGroupDO.FALSE);
        }
        //获取到当天是周几
        int week = dto.getLocalDateTime().getDayOfWeek().getValue();
        AttendanceFixedDO attendanceFixedDO = this.getByGroupIdAndWeek(activationGroup.getId(), week);
        // -- 当前没有班次 - 不需要考勤
        if (attendanceFixedDO == null || attendanceFixedDO.getAttendanceGroupShiftId() == null) {
            return vo.setTodayNeedAttendance(AttendanceGroupDO.FALSE);
        }
        vo.setAttendanceGroupShiftId(attendanceFixedDO.getAttendanceGroupShiftId());
        attendanceService.calculatePunch(dto, vo);
        return vo;
    }


}