package jnpf.attendance.service.impl;

import cn.hutool.core.collection.CollUtil;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import jnpf.attendance.mapper.FtbAttendanceLineSchedulingPayrollHoursMapper;
import jnpf.attendance.service.AttendanceLineSchedulingPayrollHoursService;
import jnpf.base.service.SuperServiceImpl;
import jnpf.entity.attendance.FtbAttendanceLineSchedulingPayrollHours;
import org.springframework.stereotype.Service;

import java.util.Date;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * 划线排班计薪工时Service实现
 *
 * @author jnpf
 * @since 2026-02-27
 */
@Service
public class AttendanceLineSchedulingPayrollHoursServiceImpl extends SuperServiceImpl<FtbAttendanceLineSchedulingPayrollHoursMapper, FtbAttendanceLineSchedulingPayrollHours> implements AttendanceLineSchedulingPayrollHoursService {

    @Override
    public List<FtbAttendanceLineSchedulingPayrollHours> listByUserIdAndGroupId(String userId, String groupId, Date startDay, Date endDay) {
        if (CollUtil.isEmpty(CollUtil.newArrayList(userId)) || Objects.isNull(groupId) || Objects.isNull(startDay) || Objects.isNull(endDay)) {
            return CollUtil.newArrayList();
        }
        return lambdaQuery()
                .eq(FtbAttendanceLineSchedulingPayrollHours::getUserId, userId)
                .eq(FtbAttendanceLineSchedulingPayrollHours::getGroupId, groupId)
                .ge(FtbAttendanceLineSchedulingPayrollHours::getDay, startDay)
                .le(FtbAttendanceLineSchedulingPayrollHours::getDay, endDay)
                .eq(FtbAttendanceLineSchedulingPayrollHours::getDeleteMark, 0)
                .list();
    }

    @Override
    public List<FtbAttendanceLineSchedulingPayrollHours> listByUserIdsAndGroupId(List<String> userIds, String groupId, Date startDay, Date endDay) {
        if (CollUtil.isEmpty(userIds) || Objects.isNull(groupId) || Objects.isNull(startDay) || Objects.isNull(endDay)) {
            return CollUtil.newArrayList();
        }
        return lambdaQuery()
                .in(FtbAttendanceLineSchedulingPayrollHours::getUserId, userIds)
                .eq(FtbAttendanceLineSchedulingPayrollHours::getGroupId, groupId)
                .ge(FtbAttendanceLineSchedulingPayrollHours::getDay, startDay)
                .le(FtbAttendanceLineSchedulingPayrollHours::getDay, endDay)
                .eq(FtbAttendanceLineSchedulingPayrollHours::getDeleteMark, 0)
                .list();
    }

    @Override
    public List<FtbAttendanceLineSchedulingPayrollHours> listByGroupId(String groupId, Date startDay, Date endDay) {
        if (Objects.isNull(groupId) || Objects.isNull(startDay) || Objects.isNull(endDay)) {
            return CollUtil.newArrayList();
        }
        return lambdaQuery()
                .eq(FtbAttendanceLineSchedulingPayrollHours::getGroupId, groupId)
                .ge(FtbAttendanceLineSchedulingPayrollHours::getDay, startDay)
                .le(FtbAttendanceLineSchedulingPayrollHours::getDay, endDay)
                .eq(FtbAttendanceLineSchedulingPayrollHours::getDeleteMark, 0)
                .list();
    }

    @Override
    public boolean saveOrUpdateBatch(List<FtbAttendanceLineSchedulingPayrollHours> payrollHoursList) {
        if (CollUtil.isEmpty(payrollHoursList)) {
            return false;
        }
        return super.saveOrUpdateBatch(payrollHoursList);
    }

    @Override
    public boolean deleteByUserIdAndGroupId(String userId, String groupId, Date day) {
        if (Objects.isNull(userId) || Objects.isNull(groupId) || Objects.isNull(day)) {
            return false;
        }
        LambdaUpdateWrapper<FtbAttendanceLineSchedulingPayrollHours> updateWrapper = new LambdaUpdateWrapper<>();
        updateWrapper.eq(FtbAttendanceLineSchedulingPayrollHours::getUserId, userId)
                .eq(FtbAttendanceLineSchedulingPayrollHours::getGroupId, groupId)
                .eq(FtbAttendanceLineSchedulingPayrollHours::getDay, day)
                .set(FtbAttendanceLineSchedulingPayrollHours::getDeleteMark, 1);
        return update(updateWrapper);
    }

    @Override
    public boolean deleteByGroupId(String groupId, Date startDay, Date endDay) {
        if (Objects.isNull(groupId) || Objects.isNull(startDay) || Objects.isNull(endDay)) {
            return false;
        }
        LambdaUpdateWrapper<FtbAttendanceLineSchedulingPayrollHours> updateWrapper = new LambdaUpdateWrapper<>();
        updateWrapper.eq(FtbAttendanceLineSchedulingPayrollHours::getGroupId, groupId)
                .ge(FtbAttendanceLineSchedulingPayrollHours::getDay, startDay)
                .le(FtbAttendanceLineSchedulingPayrollHours::getDay, endDay)
                .set(FtbAttendanceLineSchedulingPayrollHours::getDeleteMark, 1);
        return update(updateWrapper);
    }
    @Override
    public FtbAttendanceLineSchedulingPayrollHours listByUserIdsAndDays(String userId, String groupId, Date day) {
        return listByUserIdsAndDays(List.of(userId),List.of(groupId),List.of(day)).stream().findFirst().orElse(null);
    }
    @Override
    public List<FtbAttendanceLineSchedulingPayrollHours> listByUserIdsAndDays(List<String> userIds, String groupId, List<Date> days) {
       return listByUserIdsAndDays(userIds,List.of(groupId),days);
    }
    @Override
    public List<FtbAttendanceLineSchedulingPayrollHours> listByUserIdsAndDays(List<String> userIds, List<String> groupIds, List<Date> days) {
        if (CollUtil.isEmpty(userIds) || CollUtil.isEmpty(groupIds) || CollUtil.isEmpty(days)) {
            return CollUtil.newArrayList();
        }
        return lambdaQuery()
                .in(FtbAttendanceLineSchedulingPayrollHours::getUserId, userIds)
                .in(FtbAttendanceLineSchedulingPayrollHours::getGroupId, groupIds)
                .in(FtbAttendanceLineSchedulingPayrollHours::getDay, days)
                .eq(FtbAttendanceLineSchedulingPayrollHours::getDeleteMark, 0)
                .list();
    }

    @Override
    public boolean savePayrollHoursList(List<FtbAttendanceLineSchedulingPayrollHours> payrollHoursList) {
        if (CollUtil.isEmpty(payrollHoursList)) {
            return false;
        }
        
        // 从集合中提取groupId、userIds和days
        String groupId = payrollHoursList.get(0).getGroupId();
        if (Objects.isNull(groupId)) {
            return false;
        }
        
        // 验证所有记录的groupId是否相同
        boolean allSameGroupId = payrollHoursList.stream().allMatch(item -> Objects.equals(item.getGroupId(), groupId));
        if (!allSameGroupId) {
            return false;
        }
        
        // 提取唯一的用户ID集合
        List<String> userIds = payrollHoursList.stream()
                .map(FtbAttendanceLineSchedulingPayrollHours::getUserId)
                .filter(Objects::nonNull)
                .distinct()
                .collect(Collectors.toList());
        
        // 提取唯一的日期集合
        List<Date> days = payrollHoursList.stream()
                .map(FtbAttendanceLineSchedulingPayrollHours::getDay)
                .filter(Objects::nonNull)
                .distinct()
                .collect(Collectors.toList());
        
        if (CollUtil.isEmpty(userIds) || CollUtil.isEmpty(days)) {
            return false;
        }
        
        // 先清除指定考勤组、用户集合和日期集合的计薪工时数据
        LambdaUpdateWrapper<FtbAttendanceLineSchedulingPayrollHours> updateWrapper = new LambdaUpdateWrapper<>();
        updateWrapper.in(FtbAttendanceLineSchedulingPayrollHours::getUserId, userIds)
                .eq(FtbAttendanceLineSchedulingPayrollHours::getGroupId, groupId)
                .in(FtbAttendanceLineSchedulingPayrollHours::getDay, days)
                .set(FtbAttendanceLineSchedulingPayrollHours::getDeleteMark, 1);
        update(updateWrapper);
        
        // 保存新的计薪工时数据
        return saveBatch(payrollHoursList.stream().filter(vo->Objects.nonNull(vo.getPayrollHours())).collect(Collectors.toList()));
    }
}
