package cn.iocoder.yudao.module.system.job.birthday;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.json.JSONObject;
import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
import cn.iocoder.yudao.framework.tenant.core.job.TenantJob;
import cn.iocoder.yudao.module.system.api.subscribe.SubscribeMessageSendApi;
import cn.iocoder.yudao.module.system.convert.notice.NoticeConvert;
import cn.iocoder.yudao.module.system.dal.dataobject.laborcontract.LaborContractDO;
import cn.iocoder.yudao.module.system.dal.dataobject.user.AdminUserDO;
import cn.iocoder.yudao.module.system.dal.mysql.user.AdminUserMapper;
import cn.iocoder.yudao.module.system.service.laborcontract.LaborContractService;
import cn.iocoder.yudao.module.system.service.permission.PermissionService;
import cn.iocoder.yudao.module.system.service.user.AdminUserService;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.xxl.job.core.biz.model.ReturnT;
import com.xxl.job.core.context.XxlJobContext;
import com.xxl.job.core.handler.annotation.XxlJob;
import io.netty.util.internal.StringUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertList;

@Component
@Slf4j
@EnableScheduling
public class BirthdayJob {

    @Resource
    private AdminUserMapper adminUserMapper;

    @Resource
    private AdminUserService userService;

    @Resource
    private PermissionService permissionService;

    @Resource
    private SubscribeMessageSendApi subscribeMessageSendApi;

    @Resource
    private LaborContractService laborContractService;


    @XxlJob("birthdayJob")
    @TenantJob // --- ⚠️ 这个注解 会将租户列表拉出来 完了后逐个租户执行 定时任务需要注意
    public ReturnT<String> execute() {

        //获取参数
        XxlJobContext xxlJobContext = XxlJobContext.getXxlJobContext();
        String jobParam = xxlJobContext.getJobParam();
        if (!StringUtil.isNullOrEmpty(jobParam)) {
            // 解析参数
            JSONObject object = new JSONObject(jobParam);
            // 获取角色id
            Long roleId = object.getLong("roleId");
            // 获取提醒时长
            Integer remindDuration = object.getInt("remindDuration");

            Set<Long> userIds = permissionService.getUserRoleIdListByRoleId(CollectionUtils.singleton(roleId));
            //获得用户组中 用户信息
            List<AdminUserDO> userDOs = userService.getUserList(userIds);

            // 生日提醒
            birthdayRemind(userDOs);

            // 转正提醒
            PositiveReminders(remindDuration);

            // 合同到期提醒
            ContractReminders(userDOs);
        }

        // 返回执行成功
        return ReturnT.SUCCESS;
    }

    /**
     * 合同到期提醒
     */
    private void ContractReminders(List<AdminUserDO> userDOs) {

        LocalDate now = LocalDate.now();
        List<LaborContractDO> laborContractDOS = laborContractService.getListByEndTime(now);
        if (CollectionUtil.isNotEmpty(laborContractDOS)) {

            // 修改合同状态为过期
            laborContractService.updateLaborContractList(convertList(laborContractDOS, LaborContractDO::getId), 2);

            for (AdminUserDO adminUserDO : userDOs) {
                if( adminUserDO.getOpenId() != null && !adminUserDO.getOpenId().isEmpty()) {

                    subscribeMessageSendApi.sendCompanyNotice(NoticeConvert.INSTANCE.convertBirthday(
                            "contract", adminUserDO.getOpenId(), "formal"));
                }
            }
        }
    }

    /**
     * 转正提醒
     */
    private void PositiveReminders(Integer remindDuration) {

        // 获得提醒日期
        LocalDate remindDate = LocalDate.now().plusDays(remindDuration == null ? 7 : remindDuration);

        // 查询所有试用人员
        List<AdminUserDO> userDOS = userService.getUserListByUserStaffing(5);
        List<Long> userIds = convertList(userDOS, AdminUserDO::getId);

        List<LaborContractDO> laborContractDOS = laborContractService.getListByUserIds(userIds);
        List<Long> contractUserIds = laborContractDOS.stream().filter(item -> remindDate.isEqual(item.getSigningDate().plusMonths(item.getProbationPeriodTime())))
                .map(LaborContractDO::getUserId)
                .collect(Collectors.toList());

        // 过滤需要提醒的用户
        List<AdminUserDO> positiveUserList = userDOS.stream().filter(item -> contractUserIds.contains(item.getId())).collect(Collectors.toList());
        for (AdminUserDO adminUserDO : positiveUserList) {
            if( adminUserDO.getOpenId() != null && !adminUserDO.getOpenId().isEmpty()) {

                subscribeMessageSendApi.sendCompanyNotice(NoticeConvert.INSTANCE.convertBirthday(
                        "regular", adminUserDO.getOpenId(), "formal"));
            }
        }

        log.info("转正提醒，人员为{}", convertList(positiveUserList, AdminUserDO::getNickname));
    }

    /**
     * 生日提醒
     */
    private void birthdayRemind(List<AdminUserDO> userDOs) {

        String time = LocalDateTime.now().format(DateTimeFormatter.ofPattern("MM-dd"));
        // -- 获取当天月日 生日的人员列表
        List<AdminUserDO> list = adminUserMapper.selectList(new LambdaQueryWrapper<AdminUserDO>()
                .like(AdminUserDO::getBirthdayDay, time));
        if (!list.isEmpty()) {

            for (AdminUserDO adminUserDO : userDOs) {
                if( adminUserDO.getOpenId() != null && !adminUserDO.getOpenId().isEmpty()) {

                    subscribeMessageSendApi.sendCompanyNotice(NoticeConvert.INSTANCE.convertBirthday(
                            "birthday", adminUserDO.getOpenId(), "formal"));
                }
            }

            log.info("生日提醒，生日为{}，人员为{}", time, convertList(list, AdminUserDO::getNickname));
        }
    }
}
