package cn.iocoder.yudao.module.company.service.impl;

import cn.hutool.core.util.ObjectUtil;
import cn.iocoder.yudao.common.BaseConstants;
import cn.iocoder.yudao.common.DictBaseConstants;
import cn.iocoder.yudao.module.company.entity.CompanyQuals;
import cn.iocoder.yudao.module.company.mapper.CompanyQualsMapper;
import cn.iocoder.yudao.module.company.service.CompanyQualsService;
import cn.iocoder.yudao.module.company.vo.CompanyQualsRespVO;
import cn.iocoder.yudao.module.company.vo.CompanyRespVO;
import cn.iocoder.yudao.module.system.api.dict.DictDataApi;
import cn.iocoder.yudao.module.system.api.dict.dto.DictDataRespDTO;
import cn.iocoder.yudao.module.system.api.notify.NotifyMessageSendApi;
import cn.iocoder.yudao.module.system.api.notify.dto.NotifySendSingleToUserReqDTO;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.time.LocalDate;
import java.time.ZoneId;
import java.time.temporal.ChronoUnit;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Service
public class CompanyQualsServiceImpl extends ServiceImpl<CompanyQualsMapper, CompanyQuals> implements CompanyQualsService {

    @Resource
    private DictDataApi dataApi;

    @Resource
    private NotifyMessageSendApi sendApi;

    /**
     * 新增企业资质信息
     *
     * @param companyQualsRespVO 企业资质对象
     * @author vinjor-M
     * @date 9:56 2024/8/2
     **/
    @Override
    public void saveDataObj(CompanyQualsRespVO companyQualsRespVO) {
        this.save(companyQualsRespVO);
    }

    /**
     * 更新企业资质信息
     *
     * @param companyQualsRespVO 企业资质对象
     * @author vinjor-M
     * @date 9:56 2024/8/2
     **/
    @Override
    public void updateDataObj(CompanyQualsRespVO companyQualsRespVO) {
        this.updateById(companyQualsRespVO);
    }

    /**
     * 删除企业资质
     *
     * @param id 企业资质id
     * @author vinjor-M
     * @date 16:33 2024/8/3
     **/
    @Override
    public void removeDataObj(String id) {
        this.removeById(id);
    }

    /**
     * 企业资质临期提醒
     *
     * @author 小李
     * @date 8:54 2024/8/14
     **/
    @Override
    public void noticeCompanyQualsExpired(List<CompanyRespVO> companyRespVOS) {
        // 构建分页条件
        LambdaQueryWrapper<CompanyQuals> queryWrapper = new LambdaQueryWrapper<>();
        Page<CompanyQuals> page = new Page<>(1, BaseConstants.BATCH_SIZE);
        // 获取临期判定时间
        List<DictDataRespDTO> dictDataList = dataApi.getDictDataList(DictBaseConstants.COMPANY_QUALS_EXPIRED);
        Long ruleDay = null;
        if (ObjectUtil.isNotEmpty(dictDataList)) {
            ruleDay = Long.valueOf(dictDataList.get(0).getValue());
        }
        while (ObjectUtil.isNotEmpty(ruleDay)) {
            // 查询一页数据
            Page<CompanyQuals> qualsPage = baseMapper.selectPage(page, queryWrapper);
            // 分类出临期和过期的数据
            // 这里重新赋值是因为不重新赋值用不了，我也不知道为什么，看到这里的人知道的话可以给我讲讲
            Long finalRuleDay = ruleDay;
            qualsPage.getRecords().forEach(item -> {
                LocalDate currentDate = LocalDate.now();
                LocalDate endDate = item.getEndDate().toInstant().atZone(ZoneId.systemDefault()).toLocalDate();

                // 计算离当前时间还有多少天
                Long day = ChronoUnit.DAYS.between(currentDate, endDate);
                // day 小于0是过期了 小于等于finalRuleDay是临期了 其他就正常的
                if (day < 0) {
                    sendMessage(item, BaseConstants.QUALS_EXPIRED, companyRespVOS, day);
                } else if (day <= finalRuleDay) {
                    sendMessage(item, BaseConstants.QUALS_INTERIM_PERIOD, companyRespVOS, day);
                }
            });

            // 没有下一页了就退出
            if (!qualsPage.hasNext()) {
                break;
            }

            // 翻页
            page.setCurrent(page.getCurrent() + 1);
        }
    }

    /**
     * 发送站内信
     *
     * @param data           要发送的数据
     * @param templateCode   发送用什么模板
     * @param companyRespVOS 企业和其管理员数据集
     * @param day            资质的到期时间到今天还有多少天
     * @author 小李
     * @date 9:58 2024/8/14
     **/
    private void sendMessage(CompanyQuals data, String templateCode, List<CompanyRespVO> companyRespVOS, Long day) {
        // 获取记录的企业管理员的id
        List<CompanyRespVO> collect = companyRespVOS.stream().filter(company -> company.getId() == data.getCorpId()).collect(Collectors.toList());
        if (ObjectUtil.isNotEmpty(collect)) {
            Long userId = collect.get(0).getUserDTO().getId();

            // 准备发送参数
            Map<String, Object> templateParams = new HashMap<>();
            // 什么资质
            templateParams.put("qualsName", data.getQualsName());
            // 还有多少天过期或已过期多少天，可能是负数，绝对值一下
            templateParams.put("day", Math.abs(day));

            // 发送
            sendApi.sendSingleMessageToAdmin(new NotifySendSingleToUserReqDTO()
                    .setUserId(userId)
                    .setTemplateCode(templateCode).setTemplateParams(templateParams));
        }
    }
}
