package cn.iocoder.yudao.module.system.service.holiday.holidayuserrecord;

import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.module.system.api.holiday.dto.CreateUserHolidayDTO;
import cn.iocoder.yudao.module.system.api.holiday.dto.OvertimeIncreasesHolidayDTO;
import cn.iocoder.yudao.module.system.controller.admin.holiday.holidaysetting.dto.RecalculateAssignedDTO;
import cn.iocoder.yudao.module.system.controller.admin.holiday.holidayuserrecord.vo.HolidayUserRecordPageReqVO;
import cn.iocoder.yudao.module.system.controller.admin.holiday.holidayuserrecord.vo.HolidayUserRecordSaveReqVO;
import cn.iocoder.yudao.module.system.dal.dataobject.holiday.holidaybalancesetting.HolidayBalanceSettingDO;
import cn.iocoder.yudao.module.system.dal.dataobject.holiday.holidaysetting.HolidaySettingDO;
import cn.iocoder.yudao.module.system.dal.dataobject.holiday.holidaysettingrange.HolidaySettingRangeDO;
import cn.iocoder.yudao.module.system.dal.dataobject.holiday.holidayuserrecord.HolidayUserRecordDO;
import cn.iocoder.yudao.module.system.dal.dataobject.holiday.holidayworkingage.HolidayWorkingAgeDO;
import cn.iocoder.yudao.module.system.dal.dataobject.user.AdminUserDO;

import javax.validation.Valid;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Map;

/**
 * 员工假期记录 Service 接口
 *
 * @author 艾楷
 */
public interface HolidayUserRecordService {

    /**
     * 创建员工假期记录 （用于管理员操作用户假期）
     *
     * @param createReqVO 创建信息
     * @return 编号
     */
    void createHolidayUserRecord(@Valid HolidayUserRecordSaveReqVO createReqVO);

    /**
     * 创建用户请假(用于用户主动请假)
     *
     * @param dto
     */
    void createUserHoliday(CreateUserHolidayDTO dto);

    /**
     * 假期逾期
     *
     * @param holidayUserRecords
     */
    void beOverdue(List<HolidayUserRecordDO> holidayUserRecords);

    /**
     * 获得员工假期记录
     *
     * @param userId           编号
     * @param holidaySettingId
     * @return 员工假期记录
     */
    List<HolidayUserRecordDO> getHolidayUserRecord(Long userId, Long holidaySettingId);

    /**
     * 获得员工假期记录分页
     *
     * @param pageReqVO 分页查询
     * @return 员工假期记录分页
     */
    PageResult<HolidayUserRecordDO> getHolidayUserRecordPage(HolidayUserRecordPageReqVO pageReqVO);

    /**
     * 设置完假期后 - 初始化用户的假期 发放
     */
    void init(HolidaySettingDO holidaySetting, List<HolidaySettingRangeDO> holidaySettingRangeDOS, HolidayBalanceSettingDO holidayBalanceSettingDO, List<HolidayWorkingAgeDO> holidayWorkingAgeDOS);

    /**
     * 发放假期
     *
     * @param holidaySetting
     * @param holidaySettingRangeDOS
     * @param holidayBalanceSettingDO
     * @param holidayWorkingAgeDOS
     */
    void grant(HolidaySettingDO holidaySetting, List<HolidaySettingRangeDO> holidaySettingRangeDOS, HolidayBalanceSettingDO holidayBalanceSettingDO, List<HolidayWorkingAgeDO> holidayWorkingAgeDOS, Boolean recordZero);

    /**
     * 清空假期余额
     *
     * @param holidaySettingId
     * @param holidaySettingRangeDOS 为null 的话则代表清空所有用户的
     */
    void clear(Long holidaySettingId, List<HolidaySettingRangeDO> holidaySettingRangeDOS);

    /**
     * 重新计算分配假期
     *
     * @param dto
     */
    void recalculateAssigned(RecalculateAssignedDTO dto);

    /**
     * 假期有效期计算
     *
     * @param now                     当前时间
     * @param usersIds                用户ids
     * @param holidayBalanceSettingDO 假期设置
     * @return
     */
    Map<Long, LocalDateTime> validityPeriodCalculation(LocalDateTime now, List<Long> usersIds, HolidayBalanceSettingDO holidayBalanceSettingDO);


    /**
     * 假期有效期计算
     *
     * @param now                     当前时间
     * @param userId                  用户id
     * @param holidayBalanceSettingDO 假期设置
     * @return
     */
    Map<Long, LocalDateTime> validityPeriodCalculation(LocalDateTime now, Long userId, HolidayBalanceSettingDO holidayBalanceSettingDO);

    Map<Long, BigDecimal> getQuotaMap(List<AdminUserDO> users, HolidayBalanceSettingDO holidayBalanceSettingDO, List<HolidayWorkingAgeDO> holidayWorkingAgeDOS);

    /**
     * 获取过期的假期 （还没有进行扣减的） 剩余余额大于0的
     *
     * @param now
     * @return
     */
    List<HolidayUserRecordDO> getHolidayBeOverdue(LocalDateTime now);

    /**
     * 获取过期提醒列表
     *
     * @param now
     * @return
     */
    List<HolidayUserRecordDO> getHolidayRemind(LocalDateTime now);

    /**
     * 修改状态为已提醒
     *
     * @param list
     */
    void editReminder(List<HolidayUserRecordDO> list);

    /**
     * 加班增加余额
     *
     * @param dto
     */
    void overtimeIncreasesHoliday(OvertimeIncreasesHolidayDTO dto);
}
