package jnpf.attendance.service;

import jnpf.attendance.dto.GroupUpdateByUserDTO;
import jnpf.base.service.SuperService;
import jnpf.entity.AttendanceGroupUser;
import jnpf.exception.HandleException;
import jnpf.message.model.permission.PermissionRelationOrganizeUserListDTO;
import jnpf.model.attendance.dto.DayStatisticsPageListDto;
import jnpf.model.attendance.dto.GroupUserQueryDto;
import jnpf.model.attendance.dto.JoinUserDto;
import jnpf.model.attendance.dto.UserSortModel;
import jnpf.model.attendance.model.OrganizeUserConsumerDTO;
import jnpf.model.attendance.vo.AttendanceGroupUserVo;
import jnpf.model.attendance.vo.GroupUserLineScheduleVo;
import jnpf.model.attendance.vo.SecondmentDateVo;
import jnpf.model.attendance.vo.attendance.ClockInExportVo;
import jnpf.model.attendance.vo.attendance.JoinGroupVo;
import jnpf.model.common.DateRangeDto;
import jnpf.permission.eum.v2.UserWorkStatusEnums;
import jnpf.permission.vo.v2.user.UserBoundVO;
import org.apache.commons.lang3.tuple.MutablePair;

import java.util.Date;
import java.util.List;
import java.util.Map;

public interface AttendanceUserService extends SuperService<AttendanceGroupUser> {

    /**
     * 根据考勤组查询成员列表
     *
     * @param groupId 考勤组ID
     * @param name 用户名称
     * @param type 用户类型
     * @param userIds 用户ID列表
     * @return 用户列表
     */
    List<AttendanceGroupUserVo> queryUsersByGroupId(String groupId, String name, Integer type, List<String> userIds, Date start,Date end);

    List<String> getUserIds(List<String> organizeList, List<String> userIdList, Date start, Date end, Integer scopeOfAdaptation);
    List<AttendanceGroupUser> getUserIdsAndGroupIds(List<String> organizeList, List<String> userIdList, Date start, Date end, Integer scopeOfAdaptation);

    /**
     * 对用户排序模型进行排序
     * 该方法用于根据特定的排序规则对用户排序模型对象进行排序操作
     * 它改变用户排序模型对象的顺序，以便后续处理或显示时符合预期的排序逻辑
     *
     * @param userSortModel 用户排序模型对象，包含需要被排序的数据和排序规则
     *                      这个参数不应为null，否则排序操作将抛出异常
     */
    void sort(UserSortModel userSortModel);

    /**
     * 根据用户和考勤组ID列表查询关联信息
     *
     * @param groupIds 考勤组ID列表
     * @return 关联信息列表
     */
    List<AttendanceGroupUser> queryByUsersGroupIds(List<String> groupIds);

    /**
     * 根据所有用户和考勤组ID列表查询关联信息
     *
     * @param groupIds 考勤组ID列表
     * @return 关联信息列表
     */
    List<AttendanceGroupUser> queryByAllUsersGroupIds(List<String> groupIds);

    /**
     * 查询所有用户和考勤组的关联信息
     *
     * @return 关联信息列表
     */
    List<AttendanceGroupUser> queryAll();

    /**
     * 查询所有非外派人员的考勤组用户信息
     * 此方法用于获取系统中所有不属于外派人员的考勤组用户列表它没有接受任何参数，
     * 表示将返回数据库中符合条件的所有用户信息
     *
     * @return 非外派人员的考勤组用户列表如果列表为空，表示没有符合条件的用户
     */
    List<AttendanceGroupUser> queryAllForNotSecondment();

    /**
     * 根据用户ID列表查询用户和考勤组的关联信息
     *
     * @param userIds 用户ID列表
     * @return 关联信息列表
     */
    List<AttendanceGroupUser> queryByUsersIds(List<String> userIds);

    /**
     * 根据用户ID列表查询所有用户的考勤组关联信息
     *
     * @param userIds 用户ID列表
     * @return 关联信息列表
     */
    List<AttendanceGroupUser> queryAllByUsersIds(List<String> userIds);

    /**
     * 根据时间范围、用户ID列表和考勤组ID列表查询用户和考勤组的关联信息
     *
     * @param start 开始时间
     * @param end 结束时间
     * @param userIds 用户ID列表
     * @param groupIds 考勤组ID列表
     * @return 关联信息列表
     */
    List<AttendanceGroupUser> queryByUsersAndGroup(Date start, Date end, List<String> userIds, List<String> groupIds);

    /**
     * 根据时间范围、用户ID列表和考勤组ID列表查询用户和考勤组的关联信息，并过滤借调人员
     *
     * @param start 开始时间
     * @param end 结束时间
     * @param userIds 用户ID列表
     * @param groupIds 考勤组ID列表
     * @return 关联信息列表
     */
    List<AttendanceGroupUser> queryByUsersAndGroupFilterSecondment(Date start, Date end, List<String> userIds, List<String> groupIds);

    List<AttendanceGroupUser> queryByUsersAndGroupFilterSecondment(Date start, Date end, List<String> userIds, List<String> groupIds, Boolean isContainsDeleteGroup);

    /**
     * 根据用户和小组过滤条件查询特定时间段内的出勤记录
     * 此方法主要用于查询属于特定用户组的用户在指定时间范围内的出勤信息，
     * 并可以根据需要选择是否包括已删除的小组中的用户
     *
     * @param start 开始日期，查询范围的起始时间
     * @param end 结束日期，查询范围的结束时间
     * @param userIds 用户ID列表，用于指定需要查询的用户
     * @param groupIds 小组ID列表，用于指定用户所属的小组
     * @param isContainsDeleteGroup 是否包含已删除小组的标志，
     *                             如果为true，则结果中包含属于已删除小组的用户；
     *                             如果为false，则结果中不包含属于已删除小组的用户
     * @return 返回符合查询条件的出勤记录列表
     */
    List<AttendanceGroupUser> getAttendanceGroupUsersOfSecondment(Date start, Date end, List<String> userIds, List<String> groupIds, boolean isContainsDeleteGroup);

    List<AttendanceGroupUser> getAttendanceGroupUsers(Date start, Date end, List<AttendanceGroupUser> attendanceGroupUsers);

    /**
     * 获取借调人员的考勤组信息
     *
     * @param start 开始时间
     * @param end 结束时间
     * @param userIds 用户ID列表
     * @param groupIds 考勤组ID列表
     * @return 考勤组信息列表
     */
    List<AttendanceGroupUser> getAttendanceGroupUsersOfSecondment(Date start, Date end, List<String> userIds, List<String> groupIds);

    /**
     * 查询系统用户列表
     *
     * @param orgId 组织ID
     * @param name 用户名称
     * @return 用户列表
     */
    List<AttendanceGroupUserVo> querySysUserList(String orgId, String name);

    void orgUpdateHandle(List<PermissionRelationOrganizeUserListDTO> userList);

    void addUsers(List<PermissionRelationOrganizeUserListDTO> userList, Boolean isOnboarding);

    void removeUsers(List<PermissionRelationOrganizeUserListDTO> userList, Boolean isTurnover);

    /**
     * 用户加入考勤组
     *
     * @param joinUserDto 加入用户DTO
     * @throws HandleException 处理异常
     */
    void joinUsers(JoinUserDto joinUserDto) throws HandleException;

    /**
     * 批量删除用户以发送通知
     *
     * @param joinUserDto 加入用户DTO
     */
    void batchDeleteUsersForSendNotice(JoinUserDto joinUserDto);

    /**
     * 批量删除考勤组成员
     *
     * @param joinUserDto 加入用户DTO
     */
    void batchDeleteUsers(JoinUserDto joinUserDto);

    /**
     * 检查用户是否已经加入考勤组
     *
     * @param userId 用户ID
     * @return 考勤组ID列表
     * @throws HandleException 处理异常
     */
    List<String> checkUserGroup(String userId) throws HandleException;

    /**
     * 批量获取用户加入考勤组的周期
     *
     * @param dateRangeDto 日期范围DTO
     * @param groupIds 考勤组ID列表
     * @param userIds 用户ID列表
     * @return 用户周期映射
     * @throws Exception 获取异常
     */
    Map<String, Map<String, List<String>>> batchGetUserCycleList(DateRangeDto dateRangeDto, List<String> groupIds, List<String> userIds) throws Exception;

    /**
     * 借调考勤组变动通知
     *
     * @param tenantId 租户ID
     * @return 处理结果
     */
    Boolean userGroupUpdateBySecondNotice(String tenantId);


    /**
     * 花名册考勤组变更
     * @param groupUpdateByUserDTO 考勤组变更DTO
     */
    void groupUpdateByPersonnel(GroupUpdateByUserDTO groupUpdateByUserDTO);

    /**
     * 指定考勤组成员列表
     *
     * @param id 考勤组Id
     * @param isPermissions 是否带权限
     */
    List<AttendanceGroupUserVo> getGroupUserList(String id, Boolean isPermissions);

    /**
     * 获取指定考勤组中当前处于借调的用户原本所属考勤组信息
     * @param groupId 考勤组Id
     */
    List<AttendanceGroupUser> getSelfUsersBeLongToGroup(String groupId);

    /**
     * 获取指定日期员工所在考勤组集合
     * @param groupUserQueryDto 查询参数DTO
     */
    List<ClockInExportVo> getUsersDayByGroupIds(GroupUserQueryDto groupUserQueryDto, DayStatisticsPageListDto req);

    /**
     * 带权限查询指定考勤组及班组人员信息
     * @param groupId 考勤组ID
     * @param workGroupId 班组ID
     * @return 用户信息集合
     */
    List<UserBoundVO> getUserBoundVO(String groupId, String workGroupId);

    /**
     * 批量获取带权限查询指定考勤组及班组人员信息
     * @param groupIds 考勤组ID集合
     * @param workStatusEnums 用户工作状态枚举集合
     * @return 用户信息集合
     */
    List<UserBoundVO> batchGetUserBoundVO(List<String> groupIds, List<UserWorkStatusEnums> workStatusEnums);

    /**
     * 获取用户当前所属考勤组
     */
    String getUserNowGroup();

    /**
     * 根据查询条件和分组信息获取签到导出数据列表
     *
     * @param groupUserQueryDto 查询条件，包含需要查询的分组用户相关信息
     * @param usersByGroupVos   已按分组查询到的用户数据列表，用于进一步处理和生成签到导出数据
     * @return 返回一个ClockInExportVo对象的列表，包含根据查询条件和分组信息生成的签到导出数据
     */
    List<ClockInExportVo> getClockInExportVoList(GroupUserQueryDto groupUserQueryDto, List<ClockInExportVo> usersByGroupVos);

    /**
     * 检查用户是否已经加入考勤组
     * @param userIds 用户ID列表
     */
    List<JoinGroupVo> checkUserJoinGroupToObject(String userIds);

    /**
     * 根据群组ID列表获取用户ID列表
     * 本函数旨在通过一组群组ID来收集所有相关的用户ID这些用户ID代表了属于给定群组的所有用户
     * 它主要用于需要了解特定群组包含哪些用户的应用场景中
     *
     * @param groupIds 群组ID列表，用于查询相关的用户ID
     * @return 包含所有与给定群组相关的用户ID的列表
     */
    List<String> getGroupUserIds(List<String> groupIds);

    List<AttendanceGroupUserVo> getGroupNowAllUserList(String groupId);

    /**
     * 按考勤组查询成员列表，并标识每位成员是否允许划线排班
     * <p>
     * 成员通过 {@link #getAttendanceGroupUsersOfSecondment(Date, Date, List, List)} 拉取，
     * 每位成员是否允许划线排班由考勤组划线排班配置（员工类型/工作性质/岗位/指定成员）综合判定，
     * 与排班界面 {@code canLineSchedule} 标识的口径保持一致。
     *
     * @param groupId 考勤组ID
     * @return 成员列表，包含 userId、userName、positionId、positionName、canLineSchedule
     */
    List<GroupUserLineScheduleVo> listLineScheduleUsersByGroupId(String groupId);
}
