package jnpf.attendance.service;

import com.baomidou.mybatisplus.extension.service.IService;
import com.github.pagehelper.PageInfo;
import jnpf.attendance.dto.*;
import jnpf.base.vo.PageListVO;
import jnpf.entity.attendance.AttendanceDayStatistics;
import jnpf.exception.LoginException;
import jnpf.model.attendance.dto.*;
import jnpf.model.attendance.event.StatisticsBatchClearDto;
import jnpf.model.attendance.event.StatisticsSingleDto;
import jnpf.model.attendance.event.StatisticsSingleHistoryDto;
import jnpf.model.attendance.vo.attendance.*;
import jnpf.permission.vo.v2.user.UserBoundVO;
import org.apache.commons.lang3.tuple.MutablePair;

import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Set;

/**
 * 考勤日度统计表
 *
 * @author shitou
 * @email shitou@niujiekeji.com
 * @date 2024-06-24 09:33:43
 */
public interface AttendanceDayStatisticsService extends IService<AttendanceDayStatistics> {

    /**
     * 获取有权限的用户列表
     *
     * @param filterList 筛选条件
     * @param startDate 开始时间
     * @param endDate 结束时间
     * @param userIdsFilter 用户ID
     * @param workStatus 用户状态
     * @return 用户列表
     */
    List<UserBoundVO> getUserIdArr(List<GroupFilterDto> filterList, String startDate, String endDate, List<String> userIdsFilter, String workStatus);

    /**
     * 获取日度统计数据。
     * 根据请求参数（DayStatisticsDataDto）查询并返回日度统计数据的列表。
     *
     * @param req 请求参数，包含查询条件等。
     * @return 返回日度统计数据的列表（List<DayStatisticsDataVo>）。
     */
    List<DayStatisticsDataVo> getDayStatisticsData(DayStatisticsDataDto req);

    /**
     * 获取日度统计数据的分页列表。
     * 根据请求参数（DayStatisticsPageListDto）分页查询并返回日度统计数据的列表。
     *
     * @param req 请求参数，包含分页信息和查询条件等。
     * @return 返回分页的日度统计数据列表（PageInfo<DayStatisticsPageListVo>）。
     */
    PageInfo<DayStatisticsPageListVo> getDayPageList(DayStatisticsPageListDto req);

    /**
     * 执行日度统计数据的导出操作。
     * 根据请求参数（DayStatisticsExportDto）生成并导出日度统计数据的文件。
     *
     * @param req 请求参数，包含导出所需的条件和选项。
     */
    void dayDataExport(DayStatisticsExportDto req);

    /**
     * 获取月度统计数据。
     * 根据请求参数（MouthStatisticsDataDto）查询并返回月度统计数据的列表。
     * 注意：方法名中的"Mouth"可能是笔误，应为"Month"。
     *
     * @param req 请求参数，包含查询条件等。
     * @return 返回月度统计数据的列表（List<DayStatisticsDataVo>，这里可能是类型复用或错误，通常应为特定的月度数据类型）。
     */
    List<DayStatisticsDataVo> getMonthStatisticsData(MouthStatisticsDataDto req);

    /**
     * 获取月度统计数据的分页列表。
     * 根据请求参数（MonthStatisticsPageListDto）分页查询并返回月度统计数据的列表。
     *
     * @param req 请求参数，包含分页信息和查询条件等。
     * @return 返回分页的月度统计数据列表（PageInfo<MonthStatisticsPageListVo>）。
     * @throws Exception 抛出异常以处理可能出现的错误情况。
     */
    PageInfo<MonthStatisticsPageListVo> getMonthPageList(MonthStatisticsPageListDto req) throws Exception;

    /**
     * 执行月度统计数据的导出操作。
     * 根据请求参数（MonthStatisticsExportDto）生成并导出月度统计数据的文件。
     *
     * @param req 请求参数，包含导出所需的条件和选项。
     */
    void monthDataExport(MonthStatisticsExportDto req);

    /**
     * 获取排班格子统计数据。
     * 根据请求参数（LatticeStatisticsVoDto）查询并返回排班格子统计数据。
     *
     * @param req 请求参数，包含查询条件等。
     * @return 返回排班格子统计数据（LatticeStatisticsVo）。
     */
    LatticeStatisticsVo getLatticeStatistics(LatticeStatisticsVoDto req);

    /**
     * 用户加入时生成空白统计数据。
     * 当用户加入指定组时，为该用户生成初始的空白统计数据。
     *
     * @param groupId 组ID，指定用户加入的组。
     * @param userIds 用户ID列表，包含加入组的用户。
     */
    void userJoinHandleData(String tenantId, String groupId, List<String> userIds);

    /**
     * 用户加入时生成空白统计数据。
     * 当用户加入指定组时，为该用户生成初始的空白统计数据。
     *
     * @param date    加入时间
     * @param groupId 组ID，指定用户加入的组。
     * @param userIds 用户ID列表，包含加入组的用户。
     */
    void userJoinHandleData(String tenantId, Date date, String groupId, List<String> userIds);

    /**
     * 用户日统计数据初始化。
     * 初始化用户日统计数据的相关操作，如重置统计记录等。
     *
     * @return 返回操作是否成功的布尔值。
     */
    Boolean handleDataForJob(String tenantId);

    /**
     * 批量清除日统计数据。
     * 根据给定的组ID、用户ID和日期，清除用户的日统计数据。
     *
     * @param courseEventDTO 批量清除用户日统计数据所需的参数。
     */
    void batchStatisticDataClear(StatisticsBatchClearDto courseEventDTO);

    /**
     * 组织重构考勤数据变更
     *
     * @param tenantId 租户id
     * @param start 开始时间
     */
    void regenerateDayData(String tenantId, Date start);

    /**
     * 处理历史数据
     *
     * @param tenantId 租户id
     * @param start 开始时间
     * @param end 结束时间
     */
    void processHistoricalData(String tenantId, Date start, Date end);

    /**
     * 生成用户日统计数据。
     *
     * @param singleDto 单个用户日统计数据变更参数
     */
    void statisticDataChange(StatisticsSingleDto singleDto) throws LoginException;

    /**
     * 生成用户日统计数据。
     *
     * @param singleDto 单个用户日统计数据变更参数
     */
    void statisticDataChangeHistory(StatisticsSingleHistoryDto singleDto) throws LoginException;

    /**
     * 发送个人考勤日报通知。
     * 根据给定的租户ID，发送个人考勤日报通知。
     *
     * @param tenantId 租户ID。
     * @return 返回操作是否成功的布尔值。
     */
    Boolean dayStatisticsNotice(String tenantId);

    /**
     * 发送个人统计月报通知。
     * 根据给定的租户ID，发送个人统计月报通知。
     *
     * @param tenantId 租户ID。
     * @return 返回操作是否成功的布尔值。
     */
    Boolean monthStatisticsNotice(String tenantId);

    /**
     * 发送连续未排班通知。
     * 根据给定的租户ID，发送连续未排班通知。
     *
     * @param tenantId 租户ID。
     */
    void consentUnscheduledNotice(String tenantId);

    /**
     * 发送团队统计月报通知。
     * 根据给定的租户ID，发送团队统计月报通知。
     *
     * @param tenantId 租户ID。
     * @return 返回操作是否成功的布尔值。
     */
    Boolean teamMonthStatisticsNotice(String tenantId);

    /**
     * 计算考勤组平均工时(实际出勤工时)
     *
     * @param dto 筛选条件
     * @return 考勤平均工时
     */
    List<AttendanceCountAvgHoursVo> countAttendanceAvgHours(AttendanceCountAvgHoursDto dto);


    /**
     * 获取多考勤组月度统计数据
     *
     * @param dto 筛选条件
     * @return 月度统计数据
     */
    MonthStatsDetailsVo getAttendanceAvgHoursDetails(MonthStatsDetailsDto dto);

    /**
     * 获取多考勤组月度人均工时折线图
     *
     * @param dto 筛选条件
     * @return 考勤组月度人均工时折线图
     */
    List<MonthStatsPerCapitaVo> getAttendanceMonthPerCapita(MonthStatsDetailsDto dto);

    /**
     * 获取多考勤组月度日常情况
     *
     * @param dto 筛选条件
     * @return 考勤组月度日常情况
     */
    List<MonthStatsDailySituationVo> getAttendanceDailySituation(MonthStatsDetailsDto dto);

    /**
     * 获取多考勤组月度考勤工时排行
     *
     * @param dto 筛选条件
     * @return 考勤组月度考勤工时排行
     */
    List<MonthStatsHoursRankingVo> getAttendanceHoursRanking(MonthStatsDetailsDto dto);

    /**
     * 获取多考勤组月度全勤情况
     *
     * @param dto 筛选条件
     * @return 考勤组月度出勤情况
     */
    List<MonthStatsFullSituationVo> getAttendanceFullSituation(MonthStatsDetailsDto dto);

    /**
     * 获取多考勤组月度异常情况
     *
     * @param dto 筛选条件
     * @return 考勤组月度异常情况
     */
    MonthStatsAbnormalConditionVo getAttendanceAbnormalCondition(MonthStatsDetailsDto dto);

    /**
     * 获取多考勤组月度加班情况
     *
     * @param dto 筛选条件
     * @return 考勤组月度加班情况
     */
    List<MonthStatsOvertimeSituationVo> getAttendanceOvertimeSituation(MonthStatsDetailsDto dto);

    /**
     * 获取当月考勤确认数据
     *
     * @param userIds    用户ID列表
     * @param month 考勤月份
     * @return 考勤组月度加班情况
     */
    List<MonthConfirmStatisticsListVo> getConfirmDetailsInfoByMonth(List<String> userIds, String month);

    /**
     * 考勤封账-分页列表
     *
     * @param dto 考勤封账分页列表参数
     * @return 考勤封账分页列表结果
     */
    PageInfo<MonthSealPageListVo> sealPageList(MonthSealPageListDto dto);

    /**
     * 考勤封账/批量|单个封账
     *
     * @param dto 考勤封账参数
     * @return 考勤封账结果
     */
    Boolean sealSubmit(MonthSealSubmitDto dto);

    /**
     * 考勤封账/解封
     * @param dto 用户ID
     * @return 解封结果
     */
    Boolean unSealSubmit(MonthUnSealSubmitDto dto);

    /**
     * 批量查询用户在指定月份是否封账
     *
     * @param userIdList 用户ID集合
     * @param month      月份(yyyy-MM)
     * @return 是否封账
     */
    Map<String, Boolean> selectUserIsSeal(List<String> userIdList, String month);

    /**
     * 批量查询用户在指定日期范围内是否存在封账记录
     *
     * @param userIdList 用户ID集合
     * @param start      范围开始（含当日）
     * @param end        范围结束（含当日）
     * @return 是否封账
     */
    Map<String, Boolean> selectUserIsSealByDateRange(List<String> userIdList, Date start, Date end);

    /**
     * 按天查询用户在日期范围内的已封存日期集合(跨月场景使用)
     * 返回每个用户已被封存的日期(yyyy-MM-dd)集合，用于在排班视图中按天判断锁定状态
     *
     * @param userIdList 用户ID集合
     * @param start      范围开始（含当日）
     * @param end        范围结束（含当日）
     * @return userId -> 已封存日期字符串集合(yyyy-MM-dd)
     */
    Map<String, Set<String>> selectUserDailySealByDateRange(List<String> userIdList, Date start, Date end);

    /**
     * 薪酬考勤数据支持(薪酬)
     *
     * @param dto 薪酬考勤数据支持参数
     * @return 薪酬考勤数据支持结果
     */
    Map<String, SalaryAttendanceSupportVo> salaryAttendanceSupport(SalaryAttendanceSupportDto dto);

    /**
     * 考勤统计数据列表(薪酬)
     *
     * @param dto 考勤统计数据列表参数
     * @return 考勤统计数据列表结果
     */
    List<DayStatisticsPageListVo> attendanceStaList(SalaryAttendanceSupportDto dto);

    /**
     * 获取考勤统计数据列表
     *
     * @param dto 获取考勤统计数据列表参数
     * @return 考勤统计数据列表结果
     */
    List<DayStatisticsVo> getAttendanceDayStaList(DayStatisticsDto dto);

    /**
     * 获取考勤组维度统计数据
     *
     * @param dto 筛选条件
     * @return 考勤组维度统计数据
     */
    Map<String, List<DateDimensionsRangeVo>> getDimensionsAttendanceCountMap(DimensionsAttendanceCountDto dto);

    /**
     * 获取考勤组维度统计数据-日维度
     *
     * @param dto 筛选条件
     * @return 考勤组维度统计数据
     */
    Map<String, Map<Date, Integer>> getDimensionsAttendanceDayCountMap(DimensionsAttendanceDayCountDto dto);

    /**
     * 日度计薪统计-分页列表
     *
     * @param req 筛选条件
     * @return 考勤组维度统计数据
     */
    PageInfo<DayPayrollStatisticsPageListVo> getDayPayrollPageList(DayPayrollStatisticsPageListDto req);

    /**
     * 月度计薪统计-分页列表
     *
     * @param req 筛选条件
     * @return 考勤组维度统计数据
     */
    PageInfo<MonthPayrollStatisticsPageListVo> getMonthPayrollPageList(MonthPayrollStatisticsPageListDto req) throws Exception;

    /**
     * 考勤平均工时趋势-分页列表
     *
     * @param pageDto 筛选条件
     * @return 分页列表
     */
    PageListVO<AverageTrendPageListVo> averageWorkHoursTrendPageList(PersonnelApiInfoPageListDto pageDto);

    /**
     * 考勤平均工时趋势-导出
     *
     * @param response 响应
     * @param pageDto      筛选条件
     */
    void averageWorkHoursTrendExport(HttpServletResponse response, PersonnelApiInfoPageListDto pageDto) throws Exception;

    /**
     * 考勤人均工时趋势-分页列表
     *
     * @param pageDto 筛选条件
     * @return 分页列表
     */
    PageListVO<PersonnelTrendPageListVo> personWorkHoursTrendPageList(PersonnelApiInfoSinglePageListDto pageDto);

    /**
     * 考勤人均工时趋势-导出
     *
     * @param response 响应
     * @param pageDto  筛选条件
     */
    void personWorkHoursTrendExport(HttpServletResponse response, PersonnelApiInfoSinglePageListDto pageDto) throws Exception;

    /**
     * 考勤日常情况-分页列表
     *
     * @param pageDto 筛选条件
     * @return 分页列表
     */
    PageListVO<DailySituationPageListVo> dailySituationPageList(PersonnelApiInfoSinglePageListDto pageDto);

    /**
     * 考勤日常情况-导出
     *
     * @param response 响应
     * @param pageDto  筛选条件
     */
    void dailySituationExport(HttpServletResponse response, PersonnelApiInfoSinglePageListDto pageDto) throws Exception;

    /**
     * 考勤工时排行-分页列表
     *
     * @param pageDto 筛选条件
     * @return 分页列表
     */
    PageListVO<WorkHoursRankingPageListVo> workHoursRankingPageList(PersonnelApiInfoSinglePageListDto pageDto);

    /**
     * 考勤工时排行-导出
     *
     * @param response 响应
     * @param pageDto  筛选条件
     */
    void workHoursRankingExport(HttpServletResponse response, PersonnelApiInfoSinglePageListDto pageDto) throws Exception;

    /**
     * 考勤全勤情况-分页列表
     *
     * @param pageDto 筛选条件
     * @return 分页列表
     */
    PageListVO<FullAttendanceStatusPageListVo> fullAttendanceStatusPageList(PersonnelApiInfoSinglePageListDto pageDto);

    /**
     * 考勤全勤情况-导出
     *
     * @param response 响应
     * @param pageDto  筛选条件
     */
    void fullAttendanceStatusExport(HttpServletResponse response, PersonnelApiInfoSinglePageListDto pageDto) throws Exception;

    /**
     * 考勤异常情况-分页列表
     *
     * @param pageDto 筛选条件
     * @return 分页列表
     */
    PageListVO<ExceptionSituationPageListVo> exceptionSituationPageList(PersonnelApiInfoSinglePageListDto pageDto);

    /**
     * 考勤考勤异常情况-导出
     *
     * @param response 响应
     * @param pageDto  筛选条件
     */
    void exceptionSituationExport(HttpServletResponse response, PersonnelApiInfoSinglePageListDto pageDto) throws Exception;

    /**
     * 考勤加班情况-分页列表
     *
     * @param pageDto 筛选条件
     * @return 分页列表
     */
    PageListVO<OvertimeSituationPageListVo> overtimeSituationPageList(PersonnelApiInfoSinglePageListDto pageDto);

    /**
     * 考勤加班情况-导出
     *
     * @param response 响应
     * @param pageDto  筛选条件
     */
    void overtimeSituationExport(HttpServletResponse response, PersonnelApiInfoSinglePageListDto pageDto) throws Exception;

    /**
     * 查询用户考勤统计信息
     *
     * @param dto 筛选条件
     * @return 考勤统计信息
     */
    QueryStatisticsInfoVo queryUserStatisticsInfo(QueryStatisticsInfoDto dto);

    /**
     * 查询考勤组的考勤情况
      *
      * @param dto 筛选条件
      * @return 考勤组维度统计信息
     */
    QueryGroupStatisticsVo queryGroupStatistics(QueryGroupStatisticsDto dto);

    /**
     * 查询用户的加班情况
     *
     * @param dto 筛选条件
     * @return 用户加班信息
     */
    QueryUserOvertimeVo queryUserOvertime(QueryStatisticsInfoDto dto);

    /**
     * 查询用户工作状况
     *
     * @param dto 筛选条件
     * @return Map<用户ID, Map<日期,是否排班>>
     */
    Map<String, UserWorkSituationVo> queryUserWorkSituation(UserWorkSituationDto dto);
}

