package com.rongwei.bscommon.sys.service.impl;

import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.ExcelWriter;
import com.alibaba.excel.write.metadata.WriteSheet;
import com.rongwei.bscommon.sys.dao.CommonDao;
import com.rongwei.bscommon.sys.excel.EquLubricationTaskManagementTemplate;
import com.rongwei.bscommon.sys.excel.EquMaintenanceTaskTemplate;
import com.rongwei.bscommon.sys.service.*;
import com.rongwei.bscommon.sys.utils.StringUtil;
import com.rongwei.bscommon.sys.utils.TimeUtils;
import com.rongwei.bsentity.domain.*;
import com.rongwei.bsentity.dto.EquMaintenanceOrderSumDTO;
import com.rongwei.bsentity.dto.EquipmentDisposeDTO;
import com.rongwei.bsentity.enums.LubricationFrequencyEnum;
import com.rongwei.bsentity.enums.MaintenanceTypeEnum;
import com.rongwei.bsentity.enums.PlantEnum;
import com.rongwei.bsentity.enums.TaskStatusEnum;
import com.rongwei.rwadmincommon.system.domain.SysDictDo;
import com.rongwei.rwadmincommon.system.service.SysDictService;
import com.rongwei.rwcommon.base.R;
import com.rongwei.rwcommon.utils.SecurityUtil;
import com.rongwei.rwcommoncomponent.file.service.SysFileItemService;
import com.rongwei.rwcommonentity.commonservers.domain.SysFileItemDo;
import com.rongwei.safecommon.fegin.CXCommonFeginClient;
import com.rongwei.safecommon.utils.CXCommonUtils;
import com.rongwei.safecommon.utils.SaveConstans;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.mock.web.MockMultipartFile;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.ByteArrayOutputStream;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;

import static com.rongwei.safecommon.utils.SaveConstans.FileName.PLANNING_TASK_FILE_NAME;
import static com.rongwei.safecommon.utils.SaveConstans.NotifyContent.*;
import static com.rongwei.safecommon.utils.SaveConstans.NotifyTitle.*;
import static com.rongwei.safecommon.utils.SaveConstans.NotifyType.*;
import static com.rongwei.safecommon.utils.SaveConstans.RoleCode.*;

/**
 * @author shangmi
 * @title EquipmentSendNotifyServiceImpl
 * @date 2024/1/18 17:20
 * @description 设备消息提醒业务实现类
 */
@Service
@Slf4j
public class EquipmentSendNotifyServiceImpl implements EquipmentSendNotifyService {

    @Autowired
    private EquMaintenanceTaskService maintenanceTaskService;

    @Autowired
    private CXCommonFeginClient commonFeginClient;

    @Autowired
    private SysDictService sysDictService;

    @Autowired
    private EquLubricationTaskManagementService equLubricationTaskManagementService;

    @Autowired
    private EquLubricationTaskDetailService lubricationTaskDetailService;

    @Autowired
    private EquMaintenanceOrderService equMaintenanceOrderService;

    @Autowired
    private AspCheckItemsService aspCheckItemsService;

    @Autowired
    private CommonDao commonDao;

    @Autowired
    private SysFileItemService sysFileItemService;

    /**
     * 根据任务ID发送 提醒
     *
     * @param ids 保养任务ID
     * @return {@link R}
     * @date 2024/1/18 17:16
     * @author shangmi
     */
    @Override
    public R maintainCreateTaskNotify(String ids) {
        if (StringUtils.isBlank(ids)) {
            log.info("任务ID为空");
            return R.ok();
        }
        String[] idList = ids.split(",");
        for (String id : idList) {


            EquMaintenanceTaskDo maintenanceTaskDo = maintenanceTaskService.getById(id);

            if (null == maintenanceTaskDo) {
                log.info("无法通过id:{}获取到任务列表", id);
                return R.ok();
            }

            // 发送人
            List<String> userId = new ArrayList<>();
            if (maintenanceTaskDo.getPrincipalid() != null) {
                userId.addAll(Arrays.asList(maintenanceTaskDo.getPrincipalid().split(",")));
            }
            if (maintenanceTaskDo.getOtherengineersid() != null) {
                userId.addAll(Arrays.asList(maintenanceTaskDo.getOtherengineersid().split(",")));
            }

            if (userId.isEmpty()) {
                log.info("id为{}的任务无提醒人", id);
                return R.ok();
            }
            // 发送标题
            String title = MAINTAIN_SYSTEM_TITLE;
            // 发送内容
            String context = String.format(MAINTAIN_SYSTEM_CONTENT, maintenanceTaskDo.getPlanyear() + "-" + maintenanceTaskDo.getMonth(),
                    maintenanceTaskDo.getWorkshop(), maintenanceTaskDo.getEquipmentname(), maintenanceTaskDo.getEquipmentnumber(),
                    maintenanceTaskDo.getMaintenancesite(), maintenanceTaskDo.getPrincipal(), maintenanceTaskDo.getOtherengineers());
            // 删除提醒
            CXCommonUtils.deleteSendNotify("maintain", id);

            // 发送提醒
            CXCommonUtils.sendNotify(title, context, null, userId.stream().distinct().collect(Collectors.toList()),
                    maintenanceTaskDo.getId(), MAINTAIN, false);
        }
        return R.ok();
    }

    @Override
    public R maintainVerifyTaskNotify(String id) {
        if (StringUtils.isBlank(id)) {
            log.info("任务ID为空");
            return R.ok();
        }
        EquMaintenanceTaskDo maintenanceTaskDo = maintenanceTaskService.getById(id);

        if (null == maintenanceTaskDo) {
            log.info("无法通过id:{}获取到任务列表", id);
            return R.ok();
        }

        // 发送人
        List<String> userId = new ArrayList<>();
        if (maintenanceTaskDo.getAcceptorid() != null) {
            userId.addAll(Arrays.asList(maintenanceTaskDo.getAcceptorid().split(",")));
        }
        if (userId.isEmpty()) {
            log.info("id为{}的任务无提醒人", id);
            return R.ok();
        }
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        // 发送内容
        String context = String.format(ACCEPTANCE_SYSTEM_CONTENT, maintenanceTaskDo.getPlanyear() + "-" + maintenanceTaskDo.getMonth(),
                maintenanceTaskDo.getWorkshop(), maintenanceTaskDo.getEquipmentname(), maintenanceTaskDo.getEquipmentnumber(),
                maintenanceTaskDo.getMaintenancesite(), simpleDateFormat.format(maintenanceTaskDo.getTaskendtime()), maintenanceTaskDo.getPrincipal(),
                maintenanceTaskDo.getOtherengineers());

        // 删除提醒 走前端
//        CXCommonUtils.deleteSendNotify("maintain", id);

        CXCommonUtils.sendNotify(ACCEPTANCE_SYSTEM_TITLE, context, null, userId.stream().distinct().collect(Collectors.toList()),
                maintenanceTaskDo.getId(), ACCEPTMAINTAINTASK, false);
        return R.ok();
    }

    /**
     * 发润滑任务的消息提醒
     *
     * @param equLubricationTaskManagementDos
     * @return
     */
    @Override
    public R sendLubricationTaskNotify(List<EquLubricationTaskManagementDo> equLubricationTaskManagementDos) {
        if (equLubricationTaskManagementDos == null || equLubricationTaskManagementDos.isEmpty()) {
            return R.ok();
        }
        List<SysDictDo> dictsByType = sysDictService.getDictsByType("lubricationFrequency");
        // 获取润滑人ID不为空的数据
        equLubricationTaskManagementDos.stream().filter(info -> StringUtils.isNotBlank(info.getLubricatorid())).forEach(info -> {
            String taskfrequency = "";
            if (StringUtils.isNotBlank(info.getTaskfrequency())) {
                taskfrequency = dictsByType.stream().filter(dictDo -> info.getTaskfrequency().contains(dictDo.getValue()))
                        .map(SysDictDo::getName).collect(Collectors.joining(","));

            }
            // 发送消息提醒
            CXCommonUtils.sendNotify(LUBRICATION_TASK_TITLE,
                    String.format(LUBRICATION_TASK_CONTENT, info.getYear(), info.getMonth(), taskfrequency,
                            info.getEquipmentworkshop(), info.getEquipment(), info.getEquipmentnumber(), info.getLubricator()),
                    null, Arrays.asList(info.getLubricatorid().split(",")), info.getId(), LUBRICATION_TASK, false);
        });
        // 发送消息提醒
        return R.ok();
    }

    @Override
    public R sendLubricationTaskNotifyByIds(Map<String, Object> parameter) {
        String taskIds = parameter.get("taskIds").toString();
        if (StringUtils.isNotBlank(taskIds)) {
            String[] idArray = taskIds.split(",");
            List<EquLubricationTaskManagementDo> equLubricationTaskManagementDos = new ArrayList<>(equLubricationTaskManagementService.listByIds(Arrays.asList(idArray)));
            sendLubricationTaskNotify(equLubricationTaskManagementDos);
        }
        return R.ok();
    }

    @Override
    public void sendPlanningTasksNotify(String belongfactory, Integer taskquantity, String taskId, List<String> userId, String fileItemId) {
        String taskContent = String.format(PLANNING_TASK_CONTENT, belongfactory, taskquantity);
        String notifyId = SecurityUtil.getUUID();
        String formatFileNameAndId = PLANNING_TASK_FILE_NAME + "-;-" + fileItemId;
        // 发送消息提醒
        CXCommonUtils.sendNotify(notifyId, PLANNING_TASK_TITLE,
                taskContent, formatFileNameAndId
                , userId.stream().distinct().collect(Collectors.toList()), taskId, MOBILE_PLANNING_TASK, true);
        SysFileItemDo sysFileItemDo = new SysFileItemDo();
        sysFileItemDo.setId(fileItemId);
        sysFileItemDo.setRelationid(notifyId);
        sysFileItemDo.setFilename(StringUtil.insertSpecificCharacter(PLANNING_TASK_FILE_NAME, TimeUtils.formatDayNumeral(new Date())));
        sysFileItemDo.setModifydate(new Date());
        sysFileItemDo.setModifyusername("系统操作");
        sysFileItemDo.setModifyuserid("0");
        sysFileItemService.updateById(sysFileItemDo);
    }

    /**
     * 设备报废通知提醒
     *
     * @param equipmentDisposeDTO
     */
    @Override
    public void equScrapAuditNotify(EquipmentDisposeDTO equipmentDisposeDTO) {
        String equid = equipmentDisposeDTO.getEquipmentId();
        AspCheckItems aspCheckItems = aspCheckItemsService.getById(equid);

        if (null == aspCheckItems) {
            log.info("无法通过id:{}获取到设备信息", equid);
            return;
        }

        // 发送人
        List<String> userId;
        List<String> useDeptRoleUserIds = commonDao.getRoleUserIds("'lczg','wms','role054'", "so.ID='" + aspCheckItems.getUsedeptid() + "'");
        List<String> factoryRoleUserIds = commonDao.getRoleUserIds("'hoed'", "(so.FULLPID like '," + aspCheckItems.getTenantid() + "%' or so.ID='" + aspCheckItems.getTenantid() + "')");
        if (useDeptRoleUserIds.size() > 0 && factoryRoleUserIds.size() > 0) {
            userId = Stream.of(useDeptRoleUserIds, factoryRoleUserIds).flatMap(Collection::stream).distinct().collect(Collectors.toList());
        } else if (useDeptRoleUserIds.size() == 0) {
            userId = factoryRoleUserIds;
        } else {
            userId = useDeptRoleUserIds;
        }

        if (userId.isEmpty()) {
            log.info("id为{}的任务无提醒人", equipmentDisposeDTO.getId());
            return;
        }
        // 发送内容
        String context = String.format(EQU_SCRAP_CONTENT, equipmentDisposeDTO.getProposer(), equipmentDisposeDTO.getApplicationtime(), aspCheckItems.getUsedeptname(), aspCheckItems.getCheckitemname(), aspCheckItems.getCheckitemcode());

        CXCommonUtils.sendNotify(EQU_SCRAP_TITLE, context, null, userId.stream().distinct().collect(Collectors.toList()),
                equipmentDisposeDTO.getId(), EQU_SCRAP_TASK, true);
    }


    /**
     * 故障停机提醒
     *
     * @param parameter
     * @return
     */
    @Override
    public void sendFaultStopRemind(Map<String, String> parameter) {
        String dataId = parameter.get("id");
        EquMaintenanceOrderDo equMaintenanceOrderDo = equMaintenanceOrderService.getById(dataId);

        if (null == equMaintenanceOrderDo) {
            log.info("无法通过id:{}获取到维修申请信息信息", dataId);
            return;
        }

        // 发送人
        List<String> userId;
        List<String> useDeptRoleUserIds = commonDao.getRoleUserIds("'lczg','wms'", "so.ID='" + equMaintenanceOrderDo.getWorkshopid() + "'");
        List<String> factoryRoleUserIds = commonDao.getRoleUserIds("'hoed','edms'", "(so.FULLPID like '," + equMaintenanceOrderDo.getTenantid() + "%' or so.ID='" + equMaintenanceOrderDo.getTenantid() + "')");
        if (useDeptRoleUserIds.size() > 0 && factoryRoleUserIds.size() > 0) {
            userId = Stream.of(useDeptRoleUserIds, factoryRoleUserIds).flatMap(Collection::stream).distinct().collect(Collectors.toList());
        } else if (useDeptRoleUserIds.size() == 0) {
            userId = factoryRoleUserIds;
        } else {
            userId = useDeptRoleUserIds;
        }

        if (userId.isEmpty()) {
            log.info("id为{}的任务无提醒人", dataId);
            return;
        }
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        // 发送内容
        String context = String.format(FAUL_STOP_CONTEXT, equMaintenanceOrderDo.getEquipmentname(), equMaintenanceOrderDo.getEquipmentnumber(), simpleDateFormat.format(equMaintenanceOrderDo.getIncidenttime()), equMaintenanceOrderDo.getFaultcondition(), equMaintenanceOrderDo.getCreateusername(), simpleDateFormat.format(equMaintenanceOrderDo.getRepairtime()));

        CXCommonUtils.sendNotify(FAUL_STOP_TITLE, context, null, userId.stream().distinct().collect(Collectors.toList()), dataId, FAUL_STOP_REMIND, true);
    }

    /**
     * 设备部位重复故障问题提醒
     *
     * @return
     */
    @Override
    public R deviceRepeatedlyFailsNotify() {
        // 查询维修单汇总数据：根据故障发生时间自动查询每个工厂近3个月内 (以本月在往前倒推三个月至当前时间)所有
        // 除去 无需维修、已关闭  且  维修对象分类 为 档案设备、工装 的 维修任务记录中，
        // 然后根据所属工厂、设备类型、发生部位 分组查询对应分组类型的 数量记录 中 > 1的记录
        List<EquMaintenanceOrderSumDTO> list = equMaintenanceOrderService.selectOrderSummaryData();
        if (list.isEmpty()) {
            log.info("记录为空，则不生成附件，也不生成提醒信息");
            return R.ok();
        }
        // 消息提醒id
        String noticeId = SecurityUtil.getUUID();
        // 生成附件返回对象
        String fileNameAndId = equMaintenanceOrderService.generateDeviceRepeatedlyFailsExcel(list, noticeId);

        // 3.消息提醒
        // 3.1发送人  取车间维修主管、设备部部长、设备部维修主管 角色中所有人员
         List<String> userId = equMaintenanceOrderService.selectRoleList(Arrays.asList(WMS,HOED, EDMS));
        if (userId.isEmpty()) {
            log.info("车间维修主管、设备部部长、设备部维修主管角色无提醒人");
            return R.ok();
        }

        CXCommonUtils.sendNotify(noticeId, DEVICE_REPEATEDLY_FAILS_TITLE, DEVICE_REPEATEDLY_FAILS_CONTEXT, fileNameAndId, userId.stream().distinct().collect(Collectors.toList()),
                null, DEVICE_REPEATEDLY_FAILS_NOTICETYPE, true);


        return R.ok();
    }


    /**
     * 保养/润滑跨月未完成提醒
     *
     * @return {@link R}
     * @date 2024/1/30 15:08
     * @author shangmi
     */
    @Override
    public R previousUnfinishedTaskNotify() {
        // 时间处理
        Calendar calendar = Calendar.getInstance();
        Date date = new Date();
        calendar.setTime(date);
        int month = calendar.get(Calendar.MONTH)+1;
        int year = calendar.get(Calendar.YEAR);
        calendar.set(Calendar.DAY_OF_MONTH,1);
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
        String newDate = simpleDateFormat.format(calendar.getTime());
        // calendar.set(Calendar.MONTH, -11);
        // String oldDate = simpleDateFormat.format(calendar.getTime());
        // 查询距近一年时间内未完成保养/润滑任务
        List<EquMaintenanceTaskDo> maintenanceTaskDoList = maintenanceTaskService.getListByTimeQuantum(year, month, true);
        List<EquLubricationTaskManagementDo> lubricationTaskManagementDoList = equLubricationTaskManagementService
                .getListByTimeQuantum(year, month,true );
        if (maintenanceTaskDoList.size() + lubricationTaskManagementDoList.size() == 0) {
            return R.ok();
        }
        List<EquLubricationTaskDetailDo> lubricationTaskDetailDoList =new ArrayList<>();

        List<String> lubricationIds = lubricationTaskManagementDoList.stream().map(EquLubricationTaskManagementDo::getId).collect(Collectors.toList());
        if(!lubricationIds.isEmpty()){
            lubricationTaskDetailDoList = lubricationTaskDetailService.getDetailByMasterId(lubricationIds);
        }
        // 删除提醒
        CXCommonUtils.deleteSendNotify(PREVIOUS_UNFINISHED_TASK, null);
        // 遍历三个工厂 分别给每个工厂发送提醒
        for (PlantEnum plantEnum : PlantEnum.values()) {
            ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
            // String fileUrl="E:\\Desktop\\test.xlsx";
            String plantId = plantEnum.getId();
            // 赛选出该工厂保养任务信息
            List<EquMaintenanceTaskDo> maintenanceTaskList = maintenanceTaskDoList.stream()
                    .filter(info -> info.getTenantid().equals(plantId)).collect(Collectors.toList());
            // 赛选出该工厂润滑任务信息
            List<EquLubricationTaskManagementDo> lubricationTaskManagementList = lubricationTaskManagementDoList.stream()
                    .filter(info -> plantId.equals(info.getTenantid())).collect(Collectors.toList());
            // 赛选出该工厂下的润滑任务信息
            List<EquLubricationTaskDetailDo> lubricationTaskDetailList = lubricationTaskDetailDoList.stream()
                    .filter(info -> plantId.equals(info.getTenantid())).collect(Collectors.toList());
            if (maintenanceTaskList.size() + lubricationTaskDetailList.size() == 0) {
                continue;
            }
            List<String> userIdList = extractUsersByTask(maintenanceTaskList, lubricationTaskManagementList, plantId);
            // 发送内容
            String context = String.format(PREVIOUS_UNFINISHED_TASK_CONTENT,
                    plantEnum.getName(),
                    maintenanceTaskList.size(),
                    lubricationTaskDetailList.size());

            ExcelWriter excelWriter = EasyExcel.write(byteArrayOutputStream).build();
            // ExcelWriter excelWriter = EasyExcel.write(fileUrl).build();

            List<EquMaintenanceTaskTemplate> equMaintenanceTaskTemplates = maintainDeriveDate(plantEnum, maintenanceTaskList);
            List<EquLubricationTaskManagementTemplate> lubricationTaskManagementTemplates = lubricationDeriveDate(plantEnum, lubricationTaskManagementList, lubricationTaskDetailList);
            generateExcel(excelWriter, equMaintenanceTaskTemplates, lubricationTaskManagementTemplates, Boolean.TRUE);

            excelWriter.finish();

            byte[] byteArray = byteArrayOutputStream.toByteArray();

            MultipartFile multipartFile = new MockMultipartFile("file", newDate + "-保养/润滑跨月未完成.xlsx", "application/vnd.ms-excel", byteArray);

            // 消息提醒id
            String noticeId = SecurityUtil.getUUID();

            R upload = CXCommonUtils.upload(multipartFile, noticeId);
            String fileItemId = "";
            if ("200".equals(upload.getCode())) {
                JSONObject jsonObject = JSONUtil.parseObj(upload.getData());
                // Map<String,String> map = (Map<String, String>) JSON.parse(upload.getData().toString());
                fileItemId = jsonObject.get("filename").toString() + "-;-" + jsonObject.get("id").toString();
                ;
            }


            CXCommonUtils.sendNotify(noticeId, PREVIOUS_UNFINISHED_TASK_TITLE, context,fileItemId , userIdList.stream().distinct().collect(Collectors.toList()),
                    plantId, PREVIOUS_UNFINISHED_TASK, true);
        }

        return R.ok();
    }

    @Override
    public R endUnfinishedTaskNotify() {

        // 时间处理
        Calendar calendar = Calendar.getInstance();
        Date date = new Date();
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
        calendar.setTime(date);
        String newDate = simpleDateFormat.format(date);
        // // int sky = calendar.get(Calendar.DAY_OF_MONTH)-1;
        // calendar.set(Calendar.DAY_OF_MONTH, 1);
        // String oldDate = simpleDateFormat.format(calendar.getTime());
        int year = calendar.get(Calendar.YEAR);
        int month = calendar.get(Calendar.MONTH)+1;
        // 查询距近一年时间内未完成保养/润滑任务
        List<EquMaintenanceTaskDo> maintenanceTaskDoList = maintenanceTaskService.getListByTimeQuantum(year, month, false);
        List<EquLubricationTaskManagementDo> lubricationTaskManagementDoList = equLubricationTaskManagementService
                .getListByTimeQuantum(year, month, false );
        if (maintenanceTaskDoList.size() + lubricationTaskManagementDoList.size() == 0) {
            return R.ok();
        }
        List<EquLubricationTaskDetailDo> lubricationTaskDetailDoList = new ArrayList<>();
        List<String> lubricationIds = lubricationTaskManagementDoList.stream().map(EquLubricationTaskManagementDo::getId).collect(Collectors.toList());
        if (!lubricationIds.isEmpty()){
            lubricationTaskDetailDoList = lubricationTaskDetailService.getDetailByMasterId(lubricationIds);
        }

        // 删除提醒
        CXCommonUtils.deleteSendNotify(END_UNFINISHED_TASK, null);
        // 遍历三个工厂 分别给每个工厂发送提醒
        for (PlantEnum plantEnum : PlantEnum.values()) {
            ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
            // String fileUrl="E:\\Desktop\\test.xlsx";
            String plantId = plantEnum.getId();
            // 赛选出该工厂保养任务信息
            List<EquMaintenanceTaskDo> maintenanceTaskList = maintenanceTaskDoList.stream()
                    .filter(info -> info.getTenantid().equals(plantId)).collect(Collectors.toList());
            // 赛选出该工厂润滑任务信息
            List<EquLubricationTaskManagementDo> lubricationTaskManagementList = lubricationTaskManagementDoList.stream()
                    .filter(info -> plantId.equals(info.getTenantid())).collect(Collectors.toList());
            // 赛选出该工厂下的润滑任务信息
            List<EquLubricationTaskDetailDo> lubricationTaskDetailList = lubricationTaskDetailDoList.stream()
                    .filter(info -> plantId.equals(info.getTenantid())).collect(Collectors.toList());
            if (maintenanceTaskList.size() + lubricationTaskDetailList.size() == 0) {
                continue;
            }
            List<String> userIdList = extractUsersByTask(maintenanceTaskList, lubricationTaskManagementList, plantId);
            // 发送内容
            String context = String.format(END_UNFINISHED_TASK_CONTENT,
                    newDate,
                    plantEnum.getName(),
                    maintenanceTaskList.size(),
                    lubricationTaskDetailList.size());

            ExcelWriter excelWriter = EasyExcel.write(byteArrayOutputStream).build();

            List<EquMaintenanceTaskTemplate> equMaintenanceTaskTemplates = maintainDeriveDate(plantEnum, maintenanceTaskList);
            List<EquLubricationTaskManagementTemplate> lubricationTaskManagementTemplates = lubricationDeriveDate(plantEnum, lubricationTaskManagementList, lubricationTaskDetailList);
            generateExcel(excelWriter, equMaintenanceTaskTemplates, lubricationTaskManagementTemplates, Boolean.TRUE);

            excelWriter.finish();

            byte[] byteArray = byteArrayOutputStream.toByteArray();

            MultipartFile multipartFile = new MockMultipartFile("file", newDate + "-保养/润滑月末未完成.xlsx", SaveConstans.ContentType.XLSX, byteArray);

            // 消息提醒id
            String noticeId = SecurityUtil.getUUID();

            R upload = CXCommonUtils.upload(multipartFile, noticeId);
            String fileItemId = "";
            if ("200".equals(upload.getCode())) {
                JSONObject jsonObject = JSONUtil.parseObj(upload.getData());
                fileItemId = jsonObject.get("filename").toString() + "-;-" + jsonObject.get("id").toString();
                ;
            }
            CXCommonUtils.sendNotify(noticeId, END_UNFINISHED_TASK_TITLE, context,fileItemId , userIdList.stream().distinct().collect(Collectors.toList()),
                    plantId, END_UNFINISHED_TASK, true);
        }

        return R.ok();
    }

    @Override
    public void deletePlanningTasksNotify() {
        CXCommonUtils.deleteSendNotify("mobilePlanningTask", null);
    }


    /**
     * 润滑任务导出数据迁移
     *
     * @param plantEnum                     工厂
     * @param lubricationTaskManagementList 润滑主表
     * @param lubricationTaskDetailList     润滑明细（部位）
     * @return {@link List<EquLubricationTaskManagementTemplate>}
     * @date 2024/1/31 16:55
     * @author shangmi
     */

    private List<EquLubricationTaskManagementTemplate> lubricationDeriveDate(
            PlantEnum plantEnum,
            List<EquLubricationTaskManagementDo> lubricationTaskManagementList,
            List<EquLubricationTaskDetailDo> lubricationTaskDetailList) {
        // 模板数据
        List<EquLubricationTaskManagementTemplate> equLubricationTaskManagementTemplates = new ArrayList<>();
        // 遍历主表
        for (EquLubricationTaskManagementDo lubricationTaskManagementDo : lubricationTaskManagementList) {
            List<EquLubricationTaskDetailDo> lubricationTaskDetailDoList = lubricationTaskDetailList.stream()
                    .filter(info -> lubricationTaskManagementDo.getId().equals(info.getMasterid())).collect(Collectors.toList());
            String[] split = lubricationTaskManagementDo.getTaskfrequency().split(",");
            StringBuilder taskfrequency = new StringBuilder();
            // 遍历润滑周期
            for (int i = 0; i < split.length; i++) {
                taskfrequency.append(LubricationFrequencyEnum.massageOf(split[i]));
                if (i != split.length - 1) {
                    taskfrequency.append(',');
                }
            }

            equLubricationTaskManagementTemplates.addAll(
                    // 遍历子表转移数据
                    lubricationTaskDetailDoList.stream().map(info -> {
                        EquLubricationTaskManagementTemplate lubricationTaskTemplate = new EquLubricationTaskManagementTemplate();
                        BeanUtils.copyProperties(lubricationTaskManagementDo, lubricationTaskTemplate);
                        BeanUtils.copyProperties(info, lubricationTaskTemplate);
                        lubricationTaskTemplate.setPlant(plantEnum.getName());
                        lubricationTaskTemplate.setIslubricationcompleted("y".equals(info.getIslubricationcompleted()) ? "是" : "否");
                        lubricationTaskTemplate.setFrequency(taskfrequency.toString());
                        return lubricationTaskTemplate;
                    }).collect(Collectors.toList())
            );
        }
        return equLubricationTaskManagementTemplates;
    }

    /**
     * 获得提醒用户ID
     *
     * @param maintenanceTaskList           保养任务
     * @param lubricationTaskManagementList 润滑任务
     * @return {@link List<String>}
     * @date 2024/1/31 11:32
     * @author shangmi
     */

    public List<String> extractUsersByTask(List<EquMaintenanceTaskDo> maintenanceTaskList,
                                           List<EquLubricationTaskManagementDo> lubricationTaskManagementList,
                                           String plantId) {

        // 车间ID
        StringBuilder stringBuilder = new StringBuilder();
        // 赛选出所以车间 并去重
        List<String> workshops = Stream.concat(maintenanceTaskList.stream().map(EquMaintenanceTaskDo::getWorkshopid),
                        lubricationTaskManagementList.stream().map(EquLubricationTaskManagementDo::getEquipmentworkshopid))
                .distinct().collect(Collectors.toList());
        // 拼接车间信息
        for (int i = 0; i < workshops.size(); i++) {
            stringBuilder.append("'").append(workshops.get(i)).append("'");
            if (i != workshops.size() - 1) {
                stringBuilder.append(",");
            }
        }
        // 需接收提醒用户ID
        List<String> userIds = commonDao.getRoleUserIds(
                "'lczg','role054'", "so.ID IN (" + stringBuilder + ")"
        );
        userIds.addAll(
                commonDao.getRoleUserIds(
                        "'hoed','equ_byzg'", "(so.FULLPID like '," + plantId + "%' or so.ID='" + plantId + "')"
                )
        );

        return userIds;
    }


    /**
     * 为sheep页塞数据
     *
     * @param excelWriter                        表格
     * @param equMaintenanceTaskTemplates
     * @param lubricationTaskManagementTemplates
     * @return
     * @date 2024/1/31 16:58
     * @author shangmi
     */

    public void generateExcel(
            ExcelWriter excelWriter,
            List<EquMaintenanceTaskTemplate> equMaintenanceTaskTemplates,
            List<EquLubricationTaskManagementTemplate> lubricationTaskManagementTemplates,
            Boolean isTrue) {

        WriteSheet maintainSheet = EasyExcel.writerSheet(0, isTrue ? "保养任务跨月未完成" : "保养任务月末未完成")
                .head(EquMaintenanceTaskTemplate.class).build();
        WriteSheet lubricationSheet = EasyExcel.writerSheet(1, isTrue ? "润滑任务跨月未完成" : "润滑任务月末未完成")
                .head(EquLubricationTaskManagementTemplate.class).build();
        excelWriter.write(equMaintenanceTaskTemplates, maintainSheet);
        excelWriter.write(lubricationTaskManagementTemplates, lubricationSheet);
    }

    /**
     * 保养任务导出数据迁移
     *
     * @param plantEnum           工厂枚举
     * @param maintenanceTaskList 任务数据
     * @return {@link List<EquMaintenanceTaskTemplate>}
     * @date 2024/1/31 15:49
     * @author shangmi
     */

    public List<EquMaintenanceTaskTemplate> maintainDeriveDate(PlantEnum plantEnum, List<EquMaintenanceTaskDo> maintenanceTaskList) {
        return maintenanceTaskList.stream().map(info -> {
            EquMaintenanceTaskTemplate equMaintenanceTaskTemplate = new EquMaintenanceTaskTemplate();
            BeanUtils.copyProperties(info, equMaintenanceTaskTemplate);

            equMaintenanceTaskTemplate.setPlant(plantEnum.getName());
            equMaintenanceTaskTemplate.setMaintenancetype(info.getMaintenancetype()!=null?MaintenanceTypeEnum.typeOf(info.getMaintenancetype()):null);
            equMaintenanceTaskTemplate.setTaskstate(info.getTaskstate()!=null?TaskStatusEnum.massageOf(info.getTaskstate()):null);
            return equMaintenanceTaskTemplate;
        }).collect(Collectors.toList());
    }
}


