package jnpf.attendance.service;

import jnpf.attendance.dto.AttendanceUserGroupVo;
import jnpf.attendance.dto.AttendanceUserListGroupVO;
import jnpf.base.service.SuperService;
import jnpf.entity.AttendanceGroup;
import jnpf.entity.AttendanceGroupUser;
import jnpf.entity.attendance.AppointPermission;
import jnpf.exception.HandleException;
import jnpf.exception.QueryException;
import jnpf.model.attendance.dto.*;
import jnpf.model.attendance.vo.AttendanceGroupChargeVo;
import jnpf.model.attendance.vo.AttendanceGroupVo;
import jnpf.model.attendance.vo.AttendanceOrgOrGroupVo;
import jnpf.model.attendance.vo.attendance.GroupLockVo;

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

/**
 * 打卡服务
 *
 * @author yanwenfu
 * @create 2023-11-21
 */
public interface AttendanceGroupService extends SuperService<AttendanceGroup> {

    /**
     * 新增考勤组
     */
    int save(SaveAttendanceGroupDto saveAttendanceGroupDto) throws Exception;

    /**
     * 根据用户ID和申请时间范围获取考勤组ID列表
     *
     * @param userId 用户ID
     * @param applyStart 申请开始时间
     * @param applyEnd 申请结束时间
     * @return java.util.List<java.lang.String> 考勤组ID列表
     * @throws HandleException 处理异常
     */
    List<String> getGroupIdByUserId(String userId, Date applyStart, Date applyEnd) throws HandleException;

    /**
     * 根据用户列表和时间范围获取考勤组ID列表
     *
     * @param users 用户列表
     * @param start 开始时间
     * @param end 结束时间
     * @return java.util.List<java.lang.String> 考勤组ID列表
     */
    List<String> getGroupIdByUserId(List<AttendanceGroupUser> users, Date start, Date end);

    /**
     * 删除考勤组
     *
     * @param id 考勤组ID
     * @param parentId 父考勤组ID
     */
    void delete(String id, String parentId);

    /**
     * 切换考勤组状态
     *
     * @param dto 考勤组状态DTO
     */
    void exchangeGroupStatus(AttendanceGroupStatusDto dto);

    /**
     * 获取考勤组及其子组ID列表
     *
     * @param groupId 考勤组ID
     * @param settingType 设置类型
     * @return java.util.List<java.lang.String> 考勤组ID列表
     */
    List<String> getSelfAndChildrenGroupIds(String groupId, Integer settingType);

    /**
     * 查询本组及(继承)子组考勤组成员
     *
     * @param groupId 考勤组id
     * @return java.util.List<java.lang.String> 考勤组成员列表
     */
    List<String> getSelfAndChildrenMembers(String groupId);

    /**
     * 查询考勤组列表
     *
     * @param groupName 考勤组名称
     * @return java.util.List<AttendanceGroupVo> 考勤组列表
     */
    List<AttendanceGroupVo> queryList(String groupName);

    /**
     * 查询包括已删除的考勤组列表
     *
     * @param groupIds 考勤组ID列表
     * @return java.util.List<AttendanceGroup> 考勤组列表
     */
    List<AttendanceGroup> queryListIncludeDeleteByIds(List<String> groupIds);

    /**
     * 根据ID列表查询考勤组列表
     *
     * @param groupIds 考勤组ID列表
     * @return java.util.List<AttendanceGroup> 考勤组列表
     */
    List<AttendanceGroup> queryListByIds(List<String> groupIds);

    /**
     * 根据所有ID查询考勤组列表
     *
     * @return java.util.List<AttendanceGroup> 考勤组列表
     */
    List<AttendanceGroup> queryAllListByIds();

    /**
     * 查询我管理的考勤组
     *
     * @param keyword 搜索关键字
     * @return java.util.List<AttendanceGroupVo> 我管理的考勤组列表
     */
    List<AttendanceGroupVo> queryManagerGroupList(String keyword);

    /**
     * 根据考勤组名称模糊查询考勤组列表（带权限控制）
     * 返回用户有管理权限的考勤组，支持名称模糊查询
     *
     * @param groupName 考勤组名称（支持模糊查询）
     * @return java.util.List<AttendanceGroupVo> 考勤组列表
     */
    List<AttendanceGroupVo> searchGroupByName(String groupName);

    /**
     * 查询下拉列表考勤组
     *
     * @return java.util.List<AttendanceGroup> 下拉列表考勤组
     */
    List<AttendanceGroup> queryDropList();

    /**
     * 查询下拉列表考勤组
     *
     * @return java.util.List<AttendanceGroup> 下拉列表考勤组
     */
    AttendanceGroup queryByGroupId(String groupId);

    /**
     * 查询我的考勤组列表
     *
     * @return java.util.List<AttendanceGroup> 我的考勤组列表
     */
    List<AttendanceGroup> queryMyGroups();

    /**
     * 考勤组管理 获取我管理的考勤组（树状结构展示）
     * @return java.util.List<AttendanceGroupVo> 我管理的考勤组树状列表
     */
    List<AttendanceGroupVo> groupManagerList(GroupQueryDto groupQueryDto);

    /**
     * 获取启用状态的考勤组ID列表
     *
     * @param groupId 考勤组ID
     * @return java.util.List<java.lang.String> 启用状态的考勤组ID列表
     */
    List<String> getEnableGroupIds(String groupId);

    /**
     * 借调开始
     *
     * @param attendanceSecondedDto 借调信息DTO
     * @throws HandleException 处理异常
     */
    void secondedStart(AttendanceSecondedDto attendanceSecondedDto) throws HandleException;

    /**
     * 获取一个默认考勤组
     *
     * @return AttendanceGroupVo 默认考勤组信息
     */
    AttendanceGroupVo getDefaultGroup();

    /**
     * 切换考勤组
     *
     * @param groupId 考勤组id
     */
    void handoffGroup(String groupId);

    /**
     * 获取考勤组设置状态
     *
     * @param groupId 考勤组ID
     * @param aFalse 布尔值，表示是否为默认状态
     * @return AttendanceGroupStatusDto 考勤组状态DTO
     */
    AttendanceGroupStatusDto groupSettingStatus(String groupId, Boolean aFalse);

    /**
     * 获取我有排班权限的考勤组列表
     *
     * @return java.util.List<AttendanceGroupVo> 我有排班权限的考勤组列表
     */
    List<AttendanceGroupVo> schedulingGroupList();

    /**
     * 获取我有排班权限的考勤组列表（非固定班次）
     *
     * @return java.util.List<AttendanceGroupVo> 我有排班权限的考勤组列表（非固定班次）
     */
    List<AttendanceGroupVo> schedulingGroupListByNotFixed();

    /**
     * 获取我有余额管理权限的考勤组列表
     *
     * @return java.util.List<AttendanceGroupVo> 我有余额管理权限的考勤组列表
     */
    List<AttendanceGroupVo> balanceManagement();

    /**
     * 获取我有借调审批权限的考勤组列表
     *
     * @return java.util.List<AttendanceGroupVo> 我有借调审批权限的考勤组列表
     */
    List<AttendanceGroupVo> secondedApprovalGroupList();

    /**
     * 获取切换考勤组列表以树结构展示
     *
     * @return java.util.List<AttendanceGroupVo> 切换考勤组树结构列表
     */
    List<AttendanceGroupVo> handoffGroupTreeList();

    /**
     * 通过组织Id找到组织下的考勤组
     *
     * @param orgId 组织Id
     * @return java.util.List<AttendanceGroupVo> 组织下的考勤组列表
     */
    List<AttendanceGroupVo> groupListByOrgId(String orgId);

    /**
     * 通过考勤组Id获取绑定的组织名称（拼接好的）
     *
     * @param groupId 考勤组Id
     * @return AttendanceGroupVo 考勤组绑定的组织名称信息
     */
    AttendanceGroupVo getGroupBindingOrg(String groupId, String workGroupId);

    AttendanceGroupVo getGroupBindingOrgForLine(String groupId, String workGroupId);

    /**
     * 绑定考勤组的组织
     *
     * @param attendanceGroupOrgDto 考勤组和组织信息
     */
    void updateGroupOrg(AttendanceGroupOrgDto attendanceGroupOrgDto);

    /**
     * 查询用户所在考勤组
     *
     * @param userIds 用户ids
     * @return java.util.List<AttendanceUserGroupVo> 用户所在考勤组列表
     */
    List<AttendanceUserGroupVo> getAttendanceUserGroup(List<String> userIds);

    /**
     * 锁定考勤组
     *
     * @param groupId 考勤组id
     */
    void lockGroup(String groupId);


    void oldDataProcessing(String tenantId);

    Map<String, String> batchSaveGroupByOrgIds(String tenantId, List<String> orgIds);

    /**
     * 获取组织下所有考勤组
     *
     * @param organizeId 组织ID
     * @return java.util.List<AttendanceGroup> 组织下的所有考勤组列表
     */
    List<AttendanceGroup> getByOrgId(String organizeId);

    /**
     * 获取组织下所有考勤组
     *
     * @param organizeIds 组织ID
     * @return java.util.List<AttendanceGroup> 组织下的所有考勤组列表
     */
    List<AttendanceGroup> getByOrgIds(List<String> organizeIds);

    /**
     * 查询用户当前考勤组锁定信息
     *
     * @param userId 用户id
     * @return jnpf.model.attendance.vo.attendance.GroupLockVo 用户当前考勤组锁定信息
     * @throws QueryException 查询异常
     */
    GroupLockVo getUserCurrentGroupLockInfo(String userId) throws QueryException;

    /**
     * 查询当前考勤组锁定信息
     *
     * @param groupId 考勤组id
     * @return jnpf.model.attendance.vo.attendance.GroupLockVo 当前考勤组锁定信息
     */
    GroupLockVo getGroupLockInfo(String groupId);

    /**
     * 根据用户ID列表获取考勤组信息
     *
     * @param userIds 用户ID列表
     * @return java.util.List<AttendanceUserListGroupVO> 用户考勤组信息列表
     */
    List<AttendanceUserListGroupVO> getAttendanceUserListGroupVO(List<String> userIds);

    /**
     * 根据组织名称和考勤组名称获取考勤组信息
     *
     * @param organizeName 组织名称
     * @param groupName 考勤组名称
     * @return AttendanceGroupVo 考勤组信息
     */
    AttendanceGroupVo getAttendanceGroupByNameOrganizeAndGroup(String organizeName, String groupName);

    /**
     * 获取审批考勤组列表
     * @param name 考勤组名称模糊搜索
     */
    List<AttendanceGroupVo> viewApprovalGroupList(String name);

    /**
     * 获取用户管理的考勤组信息
     *
     * @return java.util.Map<java.lang.String, java.util.List < java.lang.String>> 用户管理的考勤组信息映射表
     */
    Map<String, List<String>> userManagerGroupInfo();

    /**
     * 获取组织下所有考勤组
     *
     * @param orgIds 组织ID列表
     * @return List<AttendanceGroup>
     */
    List<AttendanceGroup> getGroupListByOrgIds(List<String> orgIds);

    /**
     * 查询用户是否拥有指定考勤组的指定权限
     * @param permissionCode 参数
     */
    boolean appointPermission(AppointPermission permissionCode);

    /**
     * 获取指定考勤组的设置（是否继承上级）
     * @param groupId 考勤组Id
     */
    AttendanceGroup getGroupSetting(String groupId);

    /**
     * V1.9
     * 获取我管理的考勤组（树状结构展示）
     * @param groupQueryDto 参数
     */
    List<AttendanceGroupVo> groupMyManagerList(GroupQueryDto groupQueryDto);

    /**
     * V1.9
     * 获取我管理的考勤组（树状结构展示）排除固定班
     */
    List<AttendanceGroupVo> schedulingGroupListByNotFixedNew();

    /**
     * V1.9
     * 切换考勤组查询我管理的考勤组
     */
    List<AttendanceGroupVo> handoffGroupTreeListNew();

    /**
     * V1.9 获取默认考勤组
     */
    AttendanceGroupVo getDefaultGroupNew();

    /**
     * V1.9 获取我管理的考勤组
     */
    List<AttendanceGroupVo> schedulingGroupListNew();

    /**
     * V1.9 余额考勤组列表
     */
    List<AttendanceGroupVo> balanceManagementNew();

    /**
     * V1.9 查询我有借调权限的考勤组管理列表
     */
    List<AttendanceGroupVo> secondedApprovalGroupListNew();

    /**
     * V1.9 获取审批考勤组列表
     * @param name 考勤组名称模糊搜索
     */
    List<AttendanceGroupVo> viewApprovalGroupListNew(String name);

    /**
     * 获取指定用户管理的考勤组
     * @param userId 用户Id
     * @param b  是否排除固定排班
     * @return List<String> 考勤组Id
     */
    List<String> getGroupIdsByManagePermission(String userId, boolean b);

    /**
     * 检查调度是否有效
     * 此方法用于确定当前调度状态是否允许继续执行或需要停止
     * 它不接受任何参数
     *
     * @return boolean 表示调度是否有效的布尔值如果返回true，表示调度可以继续进行；
     *         如果返回false，表示调度需要停止或重新评估
     */
    boolean checkScheduling();

    /**
     * 获取权限组列表
     * 此方法用于获取指定职位模块下的权限组列表
     *
     * @param positionModuleName 职位模块名称
     * @return String 返回权限组列表的字符串表示
     */
    List<AttendanceGroupVo> getPermissionsGroupList(String positionModuleName);

    /**
     * 查询考勤组列表(带权限)
     * @return java.util.List<jnpf.model.attendance.vo.AttendanceGroupVo>
     */
    List<AttendanceGroupVo> queryGroupListNew(String loginUserId, GroupQueryDto groupQueryDto);

    /**
     *  获取组织(考勤组)列表
     * @param keyword 关键字
     * @return 组织下的所有考勤组列表
     */
    List<AttendanceOrgOrGroupVo> getOrgOrGroupList(String keyword);

    /**
     * 设置考勤组负责人
     *
     * @param dto 考勤组负责人信息
     * @return Boolean
     */
    Boolean setGroupCharge(AttendanceGroupChargeDto dto);

    /**
     * 获取考勤组负责人信息
     *
     * @param groupId 考勤组ID
     * @return 考勤组负责人信息
     */
    AttendanceGroupChargeVo getGroupChargeInfo(String groupId);

    /**
     * 移除考勤组负责人
     *
     * @param groupId 考勤组ID
     * @param removeUserIds 移除的用户ID列表
     */
    void removeManager(String groupId, List<String> removeUserIds);

    /**
     * 根据用户ID查询当前时间所在考勤组（包含借调）
     *
     * @param userId 用户ID
     * @return java.util.List<AttendanceGroup> 考勤组列表
     */
    List<AttendanceGroup> getUserCurrentGroups(String userId);
}
