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

import java.util.*;
import java.util.stream.Collectors;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.lang.Validator;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import cn.iocoder.yudao.module.constant.InspectionConstants;
import cn.iocoder.yudao.module.infra.dal.dataobject.file.FileDO;
import cn.iocoder.yudao.module.inspection.entity.InspectionFile;
import cn.iocoder.yudao.module.inspection.entity.InspectionStaff;
import cn.iocoder.yudao.module.inspection.service.IInspectionFileService;
import cn.iocoder.yudao.module.inspection.vo.EquipmentCountVo;
import cn.iocoder.yudao.module.inspection.vo.ImportEquipmentVo;
import cn.iocoder.yudao.module.inspection.vo.InspectionEqInfoImportVo;
import cn.iocoder.yudao.module.inspection.vo.StaffImportExcelVO;
import cn.iocoder.yudao.module.system.api.dict.DictDataApi;
import cn.iocoder.yudao.module.system.api.dict.dto.DictDataRespDTO;
import com.baomidou.dynamic.datasource.annotation.DSTransactional;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import cn.iocoder.yudao.util.DateUtils;
import cn.iocoder.yudao.module.inspection.entity.WarnMessage;
import cn.iocoder.yudao.module.inspection.service.IWarnMessageService;
import io.prometheus.client.CollectorRegistry;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import cn.iocoder.yudao.module.inspection.mapper.InspectionEquInfoMapper;
import cn.iocoder.yudao.module.inspection.entity.InspectionEquInfo;
import cn.iocoder.yudao.module.inspection.service.IInspectionEquInfoService;

/**
 * equInfoService业务层处理
 *
 * @author zcy
 * @date 2023-10-13
 */
@Service
public class InspectionEquInfoServiceImpl extends ServiceImpl<InspectionEquInfoMapper, InspectionEquInfo> implements IInspectionEquInfoService {
    @Autowired
    private IWarnMessageService messageService;
    private CollectorRegistry collectorRegistry;

    @Autowired
    private IInspectionFileService inspectionFileService;

    @Autowired
    private DictDataApi dictDataApi;

    /**
     * 查询equInfo
     *
     * @param id equInfo主键
     * @return equInfo
     */
    @Override
    public InspectionEquInfo selectInspectionEquInfoById(Long id) {
        InspectionEquInfo inspectionEquInfo = baseMapper.selectInspectionEquInfoById(id);

        //查询文件表文件夹id是否存在
        if (ObjectUtil.isNotEmpty(inspectionEquInfo.getFolderId())) {
            InspectionFile folder = inspectionFileService.getOne(Wrappers.<InspectionFile>lambdaQuery().eq(InspectionFile::getId, inspectionEquInfo.getFolderId()));
            if (ObjectUtil.isNull(folder)) {
                inspectionEquInfo.setFolderId(null);
            }
        }

        return inspectionEquInfo;
    }

    /**
     * 查询equInfo列表
     *
     * @param inspectionEquInfo equInfo
     * @return equInfo
     */
    @Override
    public IPage<InspectionEquInfo> selectInspectionEquInfoList(Page page, InspectionEquInfo inspectionEquInfo) {
        return baseMapper.selectInspectionEquInfoList(page, inspectionEquInfo);
    }

    /**
     * 新增equInfo
     *
     * @param inspectionEquInfo equInfo
     * @return 结果
     */
    @Override
    public int insertInspectionEquInfo(InspectionEquInfo inspectionEquInfo) {
        int insert = baseMapper.insert(inspectionEquInfo);
        if (ObjectUtil.isNotEmpty(inspectionEquInfo.getNextCheckTime())) {
            //同时处理提醒信息
            WarnMessage warnMessage = new WarnMessage();
            warnMessage.setTitle("设备检测即将到期");
            warnMessage.setContent("名为:" + inspectionEquInfo.getEquName() + "的设备即将到设定的检测时间,请及时处理相关事项！");
            warnMessage.setIsRead("0");
            warnMessage.setPartnerId(inspectionEquInfo.getPartnerId());
            warnMessage.setType("equ");
            warnMessage.setObjectId(inspectionEquInfo.getId());
            // 创建Calendar对象
            Calendar calendar = Calendar.getInstance();
            calendar.setTime(inspectionEquInfo.getNextCheckTime());
            calendar.add(Calendar.MONTH, -1);
            Date newDate = calendar.getTime();
            warnMessage.setWarnTime(newDate);
            messageService.save(warnMessage);
        }
        //文件处理
        if (CollUtil.isNotEmpty(inspectionEquInfo.getFileList())) {
            addFile(inspectionEquInfo.getFileList(), inspectionEquInfo.getEquName(), null, inspectionEquInfo.getId());
        }
        return insert;
    }

    /**
     * 修改equInfo
     *
     * @param inspectionEquInfo equInfo
     * @return 结果
     */
    @Override
    @DSTransactional
    public int updateInspectionEquInfo(InspectionEquInfo inspectionEquInfo) {
        LambdaQueryWrapper<WarnMessage> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(WarnMessage::getType, "equ").eq(WarnMessage::getObjectId, inspectionEquInfo.getId());
        List<WarnMessage> list = messageService.list(queryWrapper);
        if (CollUtil.isNotEmpty(list)) {
            //更新处理
            List<Long> ids = list.stream().map(WarnMessage::getId).collect(Collectors.toList());
            messageService.removeBatchByIds(ids);
        }
        if (ObjectUtil.isNotEmpty(inspectionEquInfo.getNextCheckTime())) {
            //同时处理提醒信息
            WarnMessage warnMessage = new WarnMessage();
            warnMessage.setTitle("设备检测即将到期");
            warnMessage.setContent("名为:" + inspectionEquInfo.getEquName() + "的设备即将到设定的检测时间,请及时处理相关事项！");
            warnMessage.setIsRead("0");
            warnMessage.setPartnerId(inspectionEquInfo.getPartnerId());
            warnMessage.setType("equ");
            warnMessage.setObjectId(inspectionEquInfo.getId());
            // 创建Calendar对象
            Calendar calendar = Calendar.getInstance();
            calendar.setTime(inspectionEquInfo.getNextCheckTime());
            calendar.add(Calendar.MONTH, -1);
            Date newDate = calendar.getTime();
            warnMessage.setWarnTime(newDate);
            messageService.save(warnMessage);
        }

        if (CollUtil.isNotEmpty(inspectionEquInfo.getFileList())) {
            addFile(inspectionEquInfo.getFileList(), inspectionEquInfo.getEquName(), inspectionEquInfo.getFolderId(), inspectionEquInfo.getId());
        }
        return baseMapper.updateById(inspectionEquInfo);
    }

    /**
     * 批量删除equInfo
     *
     * @param ids 需要删除的equInfo主键
     * @return 结果
     */
    @Override
    public int deleteInspectionEquInfoByIds(Long[] ids) {
        return baseMapper.deleteBatchIds(Arrays.asList(ids));
    }

    /**
     * 删除equInfo信息
     *
     * @param id equInfo主键
     * @return 结果
     */
    @Override
    public int deleteInspectionEquInfoById(Long id) {
        LambdaQueryWrapper<WarnMessage> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(WarnMessage::getType, "file").eq(WarnMessage::getObjectId, id);
        WarnMessage one = messageService.getOne(queryWrapper);
        if (ObjectUtil.isNotEmpty(one)) {
            //更新处理
            messageService.removeById(one.getId());
        }
        return baseMapper.deleteById(id);
    }

    /**
     * 导入设备信息
     *
     * @param list 设备信息集合
     * @return 结果
     */
    @Override
    public Map<String, Object> importStaff(List<InspectionEqInfoImportVo> list) {
        if (CollUtil.isEmpty(list)) {
            throw new RuntimeException("导入数据为空");
        }
        Map<String, Object> resultMap = new HashMap<>();

        // 校验导入信息
        ImportEquipmentVo importEquipmentVo = validImportEquipment(list);
        // 保存信息
        int saveNum = saveImportStaff(importEquipmentVo.getSuccessList());
        resultMap.put("successList", importEquipmentVo.getSuccessList());
        resultMap.put("failList", importEquipmentVo.getFailList());
        return resultMap;
    }

    @Override
    public Long addDeviceFolder(Long id, String servicePackageId, String defaultKey) {
        InspectionEquInfo inspectionEquInfo = this.getById(id);
        if (ObjectUtil.isNotEmpty(inspectionEquInfo)) {
            Long folderId = inspectionFileService.addFolderForDevice(inspectionEquInfo.getEquName(), defaultKey, servicePackageId);
            //修改文件夹id
            this.update(Wrappers.<InspectionEquInfo>lambdaUpdate().eq(InspectionEquInfo::getId, id).set(InspectionEquInfo::getFolderId, folderId));
            return folderId;
        }
        return null;
    }

    /**
     * 添加设备文件夹
     *
     * @param id 设备id
     * @return 文件夹id
     */
    @Override
    public Long addFolder(Long id) {
        InspectionEquInfo inspectionEquInfo = this.getById(id);
        if (ObjectUtil.isNotEmpty(inspectionEquInfo)) {
            Long folderId = inspectionFileService.addFolder(inspectionEquInfo.getEquName(), InspectionConstants.INSPECTION_STAFF_EQUIPMENT_KEY);
            //修改文件夹id
            this.update(Wrappers.<InspectionEquInfo>lambdaUpdate().eq(InspectionEquInfo::getId, id).set(InspectionEquInfo::getFolderId, folderId));
            return folderId;
        }
        return null;
    }

    /**
     * 查询设备统计信息
     *
     * @return
     */
    @Override
    public List<EquipmentCountVo> queryEquipmentCountByCategory() {
        return baseMapper.queryEquipmentCountByCategory();
    }

    @Override
    public List<EquipmentCountVo> queryEquipmentCountByPackageId(String servicePackageId, String dictType) {
        return baseMapper.queryEquipmentCountByPackageId(servicePackageId, dictType);
    }

    /**
     * 保存导入的设备信息
     *
     * @param successList 设备信息集合
     * @return 结果
     */
    private int saveImportStaff(List<InspectionEqInfoImportVo> successList) {
        // 批量保存设备信息
        List<InspectionEquInfo> inspectionEquInfos = BeanUtil.copyToList(successList, InspectionEquInfo.class);
        this.saveBatch(inspectionEquInfos);

        List<WarnMessage> warnMessages = new ArrayList<>();
        for (InspectionEquInfo inspectionEqInfoImportVo : inspectionEquInfos) {
            if (ObjectUtil.isNotEmpty(inspectionEqInfoImportVo.getNextCheckTime())) {
                //同时处理提醒信息
                WarnMessage warnMessage = new WarnMessage();
                warnMessage.setTitle("设备检测即将到期");
                warnMessage.setContent("名为:" + inspectionEqInfoImportVo.getEquName() + "的设备即将到设定的检测时间,请及时处理相关事项！");
                warnMessage.setIsRead("0");
                warnMessage.setPartnerId(inspectionEqInfoImportVo.getPartnerId());
                warnMessage.setType("equ");
                warnMessage.setObjectId(inspectionEqInfoImportVo.getId());
                // 创建Calendar对象
                Calendar calendar = Calendar.getInstance();
                calendar.setTime(inspectionEqInfoImportVo.getNextCheckTime());
                calendar.add(Calendar.MONTH, -1);
                Date newDate = calendar.getTime();
                warnMessage.setWarnTime(newDate);

                warnMessages.add(warnMessage);
            }
            //批量保存提醒信息
            if (CollUtil.isNotEmpty(warnMessages)) {
                messageService.saveBatch(warnMessages);
            }
        }
        return 0;
    }

    /**
     * 验证导入的设备信息
     *
     * @param list 设备信息集合
     * @return 结果
     */
    private ImportEquipmentVo validImportEquipment(List<InspectionEqInfoImportVo> list) {
        List<InspectionEqInfoImportVo> successList = new ArrayList<>();
        List<InspectionEqInfoImportVo> failList = new ArrayList<>();

        //查询设备类别
        // 查询设备类型
        List<DictDataRespDTO> eqType = dictDataApi.getDictDataList("ins_equ_type");
        Map<String, String> typeMap = eqType.stream().collect(Collectors.toMap(DictDataRespDTO::getLabel, DictDataRespDTO::getValue));

        //去除示例数据
        if ("示例设备".equals(list.get(0).getEquName())) {
            list.remove(0);
        }

        for (InspectionEqInfoImportVo inspectionEqInfoImportVo : list) {
            //判断设备名称是否为空
            if (ObjectUtil.isEmpty(inspectionEqInfoImportVo.getEquName())) {
                inspectionEqInfoImportVo.setReason("设备名称不能为空");
                failList.add(inspectionEqInfoImportVo);
                continue;
            }
            // 判断设备类别是否为空
            if (ObjectUtil.isEmpty(inspectionEqInfoImportVo.getType())) {
                inspectionEqInfoImportVo.setReason(inspectionEqInfoImportVo.getEquName() + "设备类别不能为空");
                failList.add(inspectionEqInfoImportVo);
                continue;
            }
            if (ObjectUtil.isEmpty(typeMap.get(inspectionEqInfoImportVo.getType()))) {
                inspectionEqInfoImportVo.setReason(inspectionEqInfoImportVo.getEquName() + "请在下拉框中选择设备类型");
                failList.add(inspectionEqInfoImportVo);
                continue;
            }else {
                inspectionEqInfoImportVo.setType(typeMap.get(inspectionEqInfoImportVo.getType()));
            }
            // 如果邮箱不为空判断是否正确
            if (ObjectUtil.isNotEmpty(inspectionEqInfoImportVo.getEmail())) {
                if (!Validator.isEmail(inspectionEqInfoImportVo.getEmail())) {
                    inspectionEqInfoImportVo.setReason(inspectionEqInfoImportVo.getEquName() + "的邮箱格式不正确");
                    failList.add(inspectionEqInfoImportVo);
                    continue;
                }
            }
            successList.add(inspectionEqInfoImportVo);
        }
        ImportEquipmentVo importEquipmentVo = new ImportEquipmentVo();
        importEquipmentVo.setSuccessList(successList);
        importEquipmentVo.setFailList(failList);
        return importEquipmentVo;
    }

    /**
     * 添加设备附件
     *
     * @param fileList 文件集合
     * @param equName  设备
     * @param fatherId 父级文件夹id
     */
    public void addFile(List<FileDO> fileList, String equName, Long fatherId, Long eqId) {
        if (ObjectUtil.isEmpty(fatherId)) {
            //添加文件夹
            InspectionFile inspectionFile = new InspectionFile();
            inspectionFile.setFileName(equName + InspectionConstants.INSPECTION_FOLDER_SUFFIX);
            inspectionFile.setType(InspectionConstants.INSPECTION_FOLDER);

            fatherId = inspectionFileService.insertInspectionFile(inspectionFile).getId();

            //更新设备表中的文件夹id
            this.update(Wrappers.<InspectionEquInfo>lambdaUpdate()
                    .eq(InspectionEquInfo::getId, eqId)
                    .set(InspectionEquInfo::getFolderId, fatherId));
        } else {
            //删除文件下的所有文件
            inspectionFileService.remove(Wrappers.<InspectionFile>lambdaQuery()
                    .eq(InspectionFile::getFatherId, fatherId)
                    .eq(InspectionFile::getType, InspectionConstants.INSPECTION_FILE)
                    .eq(InspectionFile::getIsStaffFile, InspectionConstants.INSPECTION_IS_STAFF_FILE));
        }

        //添加文件
        List<InspectionFile> fileDOList = new ArrayList<>();
        for (FileDO fileDO : fileList) {
            InspectionFile file = new InspectionFile();
            file.setFileName(removeFileExtension(fileDO.getName()));
            file.setFilePath(fileDO.getUrl());
            file.setType(InspectionConstants.INSPECTION_FILE);
            file.setFatherId(fatherId);
            file.setIsStaffFile(InspectionConstants.INSPECTION_IS_STAFF_FILE);

            fileDOList.add(file);
        }

        //批量插入文件
        inspectionFileService.insertBatchInspectionFile(fileDOList);
    }

    /**
     * 去除文件名中的后缀
     *
     * @param filename
     * @return
     */
    public String removeFileExtension(String filename) {
        if (filename == null) {
            return null; // 或者你可以选择返回一个空字符串，取决于你的业务需求
        }
        int lastDotIndex = filename.lastIndexOf('.');
        if (lastDotIndex == -1) {
            return filename; // 如果没有找到点，则返回原文件名
        }
        return filename.substring(0, lastDotIndex);
    }
}
