package com.yida.data.attendance.service.impl;

import cn.hutool.core.collection.CollUtil;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.yida.data.attendance.mapper.EduAttendanceStaffResultMapper;
import com.yida.data.attendance.service.EduAttendanceStaffResultService;
import com.yida.data.attendance.service.EduAttendanceStaffRuleService;
import com.yida.data.attendance.service.EduAttendanceStaffRuleStaffService;
import com.yida.data.attendance.service.EduAttendanceStaffRuleTimeService;
import com.yida.data.attendance.vo.ListStaffResultPageVO;
import com.yida.data.attendance.vo.StaffDateTimeResultInfo;
import com.yida.data.attendance.vo.StaffTimeResultInfo;
import com.yida.data.common.core.entity.attendance.EduAttendanceStaffResult;
import com.yida.data.common.core.entity.attendance.EduAttendanceStaffRule;
import com.yida.data.common.core.entity.attendance.EduAttendanceStaffRuleStaff;
import com.yida.data.common.core.entity.attendance.EduAttendanceStaffRuleTime;
import com.yida.data.common.core.entity.user.EduStaff;
import com.yida.data.common.core.utils.FebsUtil;
import com.yida.data.attendance.dto.ListStaffResultDTO;
import com.yida.data.user.dto.ListStaffDTO;
import com.yida.data.user.feign.RemoteStaffService;
import com.yida.data.user.feign.RemoteTeacherService;
import java.time.LocalDate;
import java.time.LocalTime;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

/**
 * 教职工考勤-考勤结果 Service实现
 *
 * @author ZYJ
 * @date 2021-09-27 18:56:23
 */
@Service
@RequiredArgsConstructor
@Transactional
public class EduAttendanceStaffResultServiceImpl extends ServiceImpl
    <EduAttendanceStaffResultMapper, EduAttendanceStaffResult> implements EduAttendanceStaffResultService {

    private final EduAttendanceStaffRuleService eduAttendanceStaffRuleService;
    private final EduAttendanceStaffRuleStaffService eduAttendanceStaffRuleStaffService;
    private final EduAttendanceStaffRuleTimeService eduAttendanceStaffRuleTimeService;

    private final RemoteTeacherService remoteTeacherService;
    private final RemoteStaffService remoteStaffService;

    @Override
    public List<StaffTimeResultInfo> listTimeResult(Long staffId, String date) {
        return baseMapper.listTimeResult(staffId, date);
    }

    @Override
    public List<StaffDateTimeResultInfo> listDateTimeResult(Long staffId, String yearMonth) {
        List<StaffDateTimeResultInfo> res = baseMapper.listDateTimeResult(staffId, yearMonth);
        if (CollUtil.isNotEmpty(res)) {
            for (StaffDateTimeResultInfo re : res) {
                re.setWeek(FebsUtil.convertWeekCN(re.getDate().getDayOfWeek().getValue()));
            }
        }
        return res;
    }

    @Override
    public IPage<ListStaffResultPageVO> listResultPage(ListStaffResultDTO dto) {
        IPage<ListStaffResultPageVO> resPage = baseMapper.listResultPage(dto.toPage(), dto);
        List<ListStaffResultPageVO> records = resPage.getRecords();
        if (CollUtil.isNotEmpty(records)) {
            List<Long> staffIds = records.stream().map(x -> x.getStaffId()).collect(Collectors.toList());
            List<EduStaff> staffList = remoteStaffService.listStaff(ListStaffDTO.builder().ids(staffIds).build()).getData();
            for (ListStaffResultPageVO record : records) {
                for (EduStaff staff : staffList) {
                    if (staff.getId().equals(record.getStaffId())) {
                        record.setStaffName(staff.getName());
                        break;
                    }
                }
            }
        }
        return resPage;
    }

    @Override
    public List<EduAttendanceStaffResult> findNotResult(Long staffId) {
        return baseMapper.findNotResult(staffId);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void saveStaffResult() {
        LocalDate today = LocalDate.now();

        List<EduAttendanceStaffRule> ruleList = eduAttendanceStaffRuleService.list();

        List<EduAttendanceStaffResult> resultsList = new ArrayList<>();

        //遍历所有规则
        for (EduAttendanceStaffRule staffRule : ruleList) {
            //查询对应教职工
            List<EduAttendanceStaffRuleStaff> staffList = eduAttendanceStaffRuleStaffService
                .list(Wrappers.lambdaQuery(new EduAttendanceStaffRuleStaff())
                    .eq(EduAttendanceStaffRuleStaff::getRuleId, staffRule.getId()));
            for (EduAttendanceStaffRuleStaff staff : staffList) {
                //查询对应时间段
                List<EduAttendanceStaffRuleTime> timeList = eduAttendanceStaffRuleTimeService
                    .list(Wrappers.lambdaQuery(new EduAttendanceStaffRuleTime())
                        .eq(EduAttendanceStaffRuleTime::getRuleId, staffRule.getId()));
                for (EduAttendanceStaffRuleTime ruleTime : timeList) {
                    EduAttendanceStaffResult result = new EduAttendanceStaffResult();

                    result.setAttendanceDate(today);
                    result.setRuleId(staffRule.getId());
                    result.setStartStiTime(ruleTime.getStartTime());
                    result.setEndStiTime(ruleTime.getEndTime());
                    result.setRuleTimeId(ruleTime.getId());
                    result.setStaffId(staff.getStaffId());
                    result.setSchoolId(staffRule.getSchoolId());
                    resultsList.add(result);
                }

            }
        }

        saveBatch(resultsList);
    }

    @Override
    public EduAttendanceStaffResult findLastResult(Long staffId, LocalTime startTime, LocalTime endTime, LocalDate plusDays) {

        return getOne(Wrappers.lambdaQuery(new EduAttendanceStaffResult())
            .eq(EduAttendanceStaffResult::getAttendanceDate, plusDays)
            .eq(EduAttendanceStaffResult::getStaffId, staffId)
            .eq(EduAttendanceStaffResult::getStartStiTime, startTime)
            .eq(EduAttendanceStaffResult::getEndStiTime, endTime));
    }
}
