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

import cn.hutool.core.util.StrUtil;
import cn.iocoder.yudao.framework.common.Constants;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import cn.iocoder.yudao.module.system.controller.admin.scheduling.vo.AttendanceSchedulingPageReqVO;
import cn.iocoder.yudao.module.system.controller.admin.scheduling.vo.AttendanceSchedulingSaveReqVO;
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.group.AttendanceGroupDO;
import cn.iocoder.yudao.module.system.dal.dataobject.attendance.scheduling.AttendanceSchedulingDO;
import cn.iocoder.yudao.module.system.dal.mysql.attendance.scheduling.AttendanceSchedulingMapper;
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 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.util.List;
import java.util.Map;

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

/**
 * 排班制考勤设置 Service 实现类
 *
 * @author 艾楷
 */
@Service("scheduling")
@Validated
public class AttendanceSchedulingServiceImpl implements AttendanceSchedulingService, PunchService {

    @Resource
    private AttendanceSchedulingMapper schedulingMapper;
    @Resource
    private StringRedisTemplate stringRedisTemplate;
    @Resource
    private AttendanceGroupShiftService attendanceGroupShiftService;
    @Resource
    private AttendanceGroupShiftItemService attendanceGroupShiftItemService;
    @Resource
    @Lazy
    private AttendanceService attendanceService;

    @Override
    public Long createScheduling(AttendanceSchedulingSaveReqVO createReqVO) {
        // 插入
        AttendanceSchedulingDO scheduling = BeanUtils.toBean(createReqVO, AttendanceSchedulingDO.class);
        schedulingMapper.insert(scheduling);
        // 返回
        return scheduling.getId();
    }

    @Override
    public void updateScheduling(AttendanceSchedulingSaveReqVO updateReqVO) {
        // 校验存在
        validateSchedulingExists(updateReqVO.getId());
        // 更新
        AttendanceSchedulingDO updateObj = BeanUtils.toBean(updateReqVO, AttendanceSchedulingDO.class);
        schedulingMapper.updateById(updateObj);
    }

    @Override
    public void deleteScheduling(Long id) {
        // 校验存在
        validateSchedulingExists(id);
        // 删除
        schedulingMapper.deleteById(id);
    }

    private void validateSchedulingExists(Long id) {
        if (schedulingMapper.selectById(id) == null) {
            throw exception(SCHEDULING_NOT_EXISTS);
        }
    }

    @Override
    public AttendanceSchedulingDO getScheduling(Long id) {
        return schedulingMapper.selectById(id);
    }

    @Override
    public PageResult<AttendanceSchedulingDO> getSchedulingPage(AttendanceSchedulingPageReqVO pageReqVO) {
        return schedulingMapper.selectPage(pageReqVO);
    }

    @Override
    public AttendanceSchedulingDO getSchedulingByIndexDay(Long attendanceGroupId, Integer indexDay) {
        List<AttendanceSchedulingDO> list = schedulingMapper.selectList(new LambdaQueryWrapper<AttendanceSchedulingDO>()
                .eq(AttendanceSchedulingDO::getAttendanceGroupShiftId, attendanceGroupId)
                .eq(AttendanceSchedulingDO::getIndexDay, indexDay));
        if (!list.isEmpty()) {
            return list.get(0);
        }
        return null;
    }

    @Override
    public Integer getCycleDay(Long attendanceGroupId) {
        return Math.toIntExact(schedulingMapper.selectCount(new LambdaQueryWrapper<AttendanceSchedulingDO>()
                .eq(AttendanceSchedulingDO::getAttendanceGroupShiftId, attendanceGroupId)));
    }

    @Override
    public Map<Long, Integer> countGroupId() {
        return schedulingMapper.countGroupId();
    }

    @Override
    public AttendancePunchPageVO getPunchPage(AttendancePunchPageDTO dto) {
        AttendancePunchPageVO vo = new AttendancePunchPageVO();
        AttendanceGroupDO activationGroup = dto.getActivationGroup();
        vo.setActivationGroup(activationGroup);
        //获取到当天是第几天
        String schedulingKey = Constants.SCHEDULING + Constants.UNDERLINE + activationGroup.getId();
        String indexDayObj = stringRedisTemplate.opsForValue().get(schedulingKey);
        if (StrUtil.isEmpty(indexDayObj)) {
            // 当作第一天来
            indexDayObj = Constants.ONE_STR;
        }
        Integer indexDay = Integer.valueOf(indexDayObj);
        AttendanceSchedulingDO attendanceSchedulingDO = this.getSchedulingByIndexDay(activationGroup.getId(), indexDay);
        // -- 当前没有班次 - 不需要考勤
        if (attendanceSchedulingDO == null || Constants.ONE.equals(attendanceSchedulingDO.getRestFlag()) || attendanceSchedulingDO.getAttendanceGroupShiftId() == null) {
            return vo.setTodayNeedAttendance(AttendanceGroupDO.FALSE);
        }
        vo.setAttendanceGroupShiftId(attendanceSchedulingDO.getAttendanceGroupShiftId());
        attendanceService.calculatePunch(dto, vo);
        return vo;
    }


}