/**
 * Copyright &copy; 2021-2026 <a href="http://www.jeeplus.org/">JeePlus</a> All rights reserved.
 */
package com.jeeplus.business.notify.service;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.extra.spring.SpringUtil;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;


import com.jeeplus.business.editor.domain.EditorFiles;
import com.jeeplus.business.editor.service.EditorFilesService;
import com.jeeplus.business.editor.service.dto.EditorFilesDTO;
import com.jeeplus.business.notify.domain.*;
import com.jeeplus.business.notify.mapper.*;
import com.jeeplus.business.notify.service.dto.JyNotifyDTO;
import com.jeeplus.business.notify.service.dto.PluginNotifyCommentsDTO;
import com.jeeplus.business.notify.service.dto.PluginNotifyOfficesDTO;
import com.jeeplus.business.notify.service.dto.WorkAttachmentDto;
import com.jeeplus.business.notify.service.mapstruct.JyNotifyWrapper;
import com.jeeplus.business.project.domain.JyProjectEiaQualificationFile;
import com.jeeplus.common.TokenProvider;
import com.jeeplus.common.constant.CommonConstants;
import com.jeeplus.common.utils.CommonUtils;
import com.jeeplus.sys.domain.WorkAttachmentInfo;
import com.jeeplus.sys.feign.IUserApi;
import com.jeeplus.sys.feign.IWorkAttachmentApi;
import com.jeeplus.sys.service.dto.UserDTO;
import com.jeeplus.utils.StringUtils;
import org.apache.poi.ss.formula.functions.T;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.*;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.Collectors;

/**
 * 通知通告Service
 *
 * @author jeeplus
 * @version 2021-05-16
 */
@Service
@Transactional
public class JyNotifyService extends ServiceImpl <JyNotifyMapper, JyNotify> {

    @Autowired
    private JyNotifyRecordService notifyRecordService;


    @Resource
    private PluginNotifyOfficesMapper pluginNotifyOfficesMapper;

    @Resource
    private PluginNotifyUserMapper pluginNotifyUserMapper;

    @Resource
    private EditorFilesService editorFilesService;



    @Resource
    private PluginNotifyCommentsMapper commentsMapper;

    @Autowired
    private JyNotifyMapper notifyMapper;

    @Autowired
    private JyNotifyLogMapper jyNotifyLogMapper;
    /**
     * 根据id获取通知
     */
    public JyNotifyDTO getById(String id) {
        return baseMapper.getById ( id );
    }

    /**
     * 自定义分页检索
     *
     * @param page
     * @param queryWrapper
     * @return
     */
    public IPage <JyNotifyDTO> findPage(Page <JyNotifyDTO> page, String currentUserId, boolean isSelf, String readFlag, QueryWrapper queryWrapper) {
        queryWrapper.eq ( "a.del_flag", 0 ); // 排除已经删除
        return baseMapper.findList ( page, currentUserId, isSelf, readFlag, queryWrapper );
    }

    /**
     * 自定义分页检索
     *
     * @param page
     * @param queryWrapper
     * @return
     */
    public IPage <JyNotifyDTO> myNotifyDataFindPage(Page <JyNotifyDTO> page, String currentUserId, boolean isSelf, String readFlag, QueryWrapper queryWrapper) {
        queryWrapper.eq ( "a.del_flag", 0 ); // 排除已经删除
        return baseMapper.myNotifyDataFindList ( page, currentUserId, isSelf, readFlag, queryWrapper );
    }

    /**
     * 获取通知发送记录
     *
     * @param id
     * @return
     */
    public JyNotifyDTO getDetail(String id) {
        JyNotifyDTO notifyDTO = notifyMapper.getById ( id );
        if (ObjectUtil.isNotEmpty(notifyDTO)) {
            this.saveLog(notifyDTO);
            List notifyRecordList = notifyRecordService.findListByNotifyId ( id );
            if (CollectionUtil.isNotEmpty(notifyRecordList)) {
                notifyDTO.setNotifyRecordDTOList ( notifyRecordList );
            }
            // 1. 将富文本中的临时图片地址更换为新的
            // 2. 获取富文本中的图片信息
            if(StringUtils.isNotBlank(notifyDTO.getContent())){
                String newContent = editorFilesService.getNewContent(notifyDTO.getContent(), id);
                notifyMapper.updateContentById(newContent,id);
                notifyDTO.setContent(newContent);
                List<EditorFiles> list = editorFilesService.list(new QueryWrapper<EditorFiles>().lambda().eq(EditorFiles::getSourceId, id));
                List<EditorFilesDTO> editorFilesDTOList = new ArrayList<>();
                list.stream().forEach(item->{
                    EditorFilesDTO editorFilesDTO = new EditorFilesDTO();
                    editorFilesDTO.setSourceId(item.getSourceId());
                    editorFilesDTO.setTemporaryUrl(item.getTemporaryUrl());
                    editorFilesDTO.setUrl(item.getUrl());
                    editorFilesDTOList.add(editorFilesDTO);
                });
                notifyDTO.setEditorFilesDTOList(editorFilesDTOList);
            }
            //获取评论信息
            List<PluginNotifyCommentsDTO> commentsDTOList=commentsMapper.findNotifyAll(id);
            if (CollectionUtil.isNotEmpty(commentsDTOList)){
                commentsDTOList.stream().forEach(item -> {
                    item.setDeff(CommonUtils.timeDef(item.getCreateTime()));
                });
            }
            notifyDTO.setComments(commentsDTOList);
            return notifyDTO;
        } else {
            return new JyNotifyDTO();
        }
    }

    // 通知审核通过时，向通知接收人发送通知
    // 根据所选接收部门以及所选接收用户，获取通知的接收人
    public String pushNotifyRecord(String id) {
        JyNotifyDTO detail = this.getDetail(id);
        List<String> uIds = new ArrayList<>();
        List<JyNotifyRecord> notifyRecordList = new ArrayList<>();
        if (ObjectUtil.isNotEmpty(detail)) {
            if (CollectionUtil.isNotEmpty(detail.getPluginNotifyOfficesDTOList())){
                List<String> officeIds = detail.getPluginNotifyOfficesDTOList().stream().filter(item -> {
                    if (StringUtils.isNotBlank(item.getOfficeId())) {
                        return true;
                    }
                    return false;
                }).map(PluginNotifyOfficesDTO::getOfficeId).collect(Collectors.toList());

                if (CollectionUtil.isNotEmpty(officeIds)) {
                    officeIds.stream().forEach(office->{
                        List<UserDTO> listByOfficeId = SpringUtil.getBean(IUserApi.class).findListByOfficeId(office);
                        if (CollectionUtil.isNotEmpty(listByOfficeId)) {
                            listByOfficeId.stream().forEach(user -> {
                                if(StringUtils.isNotBlank(user.getId())){
                                    uIds.add(user.getId());
                                }
                            });
                        }
                    });

                }
            }
            if (CollectionUtil.isNotEmpty(detail.getPluginNotifyUserDTOList())){
                detail.getPluginNotifyUserDTOList().stream().forEach(userDTO -> {
                    if (StringUtils.isNotBlank(userDTO.getUserId())) {
                        uIds.add(userDTO.getUserId());
                    }
                });
            }
        }
        if (CollectionUtil.isNotEmpty(uIds)) {
            List<String> userIds = uIds.stream().distinct().collect(Collectors.toList());
            userIds.stream().forEach(userId -> {
                JyNotifyRecord notifyRecord = new JyNotifyRecord();
                notifyRecord.setUserId(userId);
                notifyRecord.setNotifyId(id);
                notifyRecord.setReadFlag("0");
                notifyRecordList.add(notifyRecord);
            });
        }
        notifyRecordService.remove(new LambdaQueryWrapper<JyNotifyRecord>().eq(JyNotifyRecord::getNotifyId,id));
        if (CollectionUtil.isNotEmpty(notifyRecordList)) {
            notifyRecordService.saveBatch(notifyRecordList);
        }
        return "通知发送完成";
    }


    /**
     * 获取通知数目
     *
     * @return
     */
    public Long findCount(String currentUserId, boolean isSelf, String readFlag) {
        return baseMapper.findCount ( currentUserId, isSelf, readFlag );
    }

    /**
     * 保存通知
     *
     * @param notifyDTO
     * @return
     */
    public String saveForm(JyNotifyDTO notifyDTO) {
        UserDTO userDTO = SpringUtil.getBean ( IUserApi.class ).getByToken(TokenProvider.getCurrentToken());
        JyNotify notify = JyNotifyWrapper.INSTANCE.toEntity ( notifyDTO );
        super.saveOrUpdate ( notify );
        notifyDTO.setId ( notify.getId () );
        if (ObjectUtil.isNotEmpty(notifyDTO)) {
            //富文本内容
            editorFilesService.remove(new QueryWrapper<EditorFiles>().lambda().eq(EditorFiles::getSourceId,notify.getId ()));
            if (CollectionUtil.isNotEmpty(notifyDTO.getEditorFilesDTOList())) {
                notifyDTO.getEditorFilesDTOList().stream().forEach(item->{
                    editorFilesService.saveUrl(item.getTemporaryUrl(),item.getUrl(),notify.getId());
                });
            }
            // 附件
            if (ObjectUtil.isNotEmpty(notifyDTO.getWorkAttachmentDtoList())) {
                SpringUtil.getBean ( IWorkAttachmentApi.class ).deleteByAttachmentId(notifyDTO.getId());
                AtomicInteger sort = new AtomicInteger(1);
                notifyDTO.getWorkAttachmentDtoList().stream().forEach(item->{
                    //保存附件信息
                    WorkAttachmentInfo workAttachmentDto = new WorkAttachmentInfo();
                    workAttachmentDto.setName(item.getName());
                    workAttachmentDto.setSize(item.getSize());
                    workAttachmentDto.setUrl(item.getUrl());
                    Map<String,String> map = new HashMap<>();
                    String workAttachmentDtoInfo = JSON.toJSONString(workAttachmentDto);
                    String userDTOInfo = JSON.toJSONString(userDTO);
                    String attachmentId = notifyDTO.getId();
                    String attachmentFlag = "jyNotify";
                    String sortInfo = Integer.toString(sort.get());
                    map.put("workAttachmentDtoInfo",workAttachmentDtoInfo);
                    map.put("userDTOInfo",userDTOInfo);
                    map.put("attachmentId",attachmentId);
                    map.put("attachmentFlag",attachmentFlag);
                    map.put("sortInfo",sortInfo);
                    String fileId = SpringUtil.getBean ( IWorkAttachmentApi.class ).saveFile(map);
                    sort.getAndIncrement();
                });
            }
            // 部门信息
            pluginNotifyOfficesMapper.delete(new QueryWrapper<PluginNotifyOffices>().lambda().eq(PluginNotifyOffices::getNotifyId,notify.getId()));
            if (ObjectUtil.isNotEmpty(notifyDTO.getPluginNotifyOfficesDTOList())){
                notifyDTO.getPluginNotifyOfficesDTOList().stream().forEach(item->{
                    PluginNotifyOffices pluginNotifyOffices = new PluginNotifyOffices();
                    pluginNotifyOffices.setOfficeId(item.getOfficeId());
                    pluginNotifyOffices.setNotifyId(notify.getId());
                    pluginNotifyOfficesMapper.insert(pluginNotifyOffices);
                });
            }
            // 用户信息
            pluginNotifyUserMapper.delete(new QueryWrapper<PluginNotifyUser>().lambda().eq(PluginNotifyUser::getNotifyId,notify.getId()));
            if (ObjectUtil.isNotEmpty(notifyDTO.getPluginNotifyUserDTOList())){
                notifyDTO.getPluginNotifyUserDTOList().stream().forEach(item->{
                    PluginNotifyUser pluginNotifyUser = new PluginNotifyUser();
                    pluginNotifyUser.setUserId(item.getUserId());
                    pluginNotifyUser.setNotifyId(notify.getId());
                    pluginNotifyUserMapper.insert(pluginNotifyUser);
                });
            }
            // 审核通过的时候，向用户发送通知
            if (StringUtils.isNotBlank(notifyDTO.getStatus())) {
                if ("5".equals(notifyDTO.getStatus())) {
                    this.pushNotifyRecord(notify.getId());
                }
            }
        }
        return notify.getId ();
    }

    public ResponseEntity saveNotify(JyNotifyDTO notifyDTO){
        this.saveForm(notifyDTO);
        return ResponseEntity.ok("保存成功");
    }

    public String updateStatusById(JyNotifyDTO notifyDTO) {
        baseMapper.updateStatusById(notifyDTO.getId(),notifyDTO.getStatus());
        return "操作成功";
    }

    /**
     * 更新阅读状态
     */
    public void updateReadFlag(String id) {
        notifyRecordService.lambdaUpdate ( ).eq ( JyNotifyRecord::getNotifyId, id )
                .eq ( JyNotifyRecord::getUserId, SpringUtil.getBean(IUserApi.class).getByToken(TokenProvider.getCurrentToken())).ne ( JyNotifyRecord::getReadFlag, CommonConstants.YES )
                .set ( JyNotifyRecord::getReadDate, new Date ( ) ).set ( JyNotifyRecord::getReadFlag, CommonConstants.YES ).update ( );
    }

    public String addComment(PluginNotifyComments comment) {
        commentsMapper.insert(comment);
        return "操作完成";
    }

    public String delComment(String id) {
        commentsMapper.deleteById(id);
        return "操作完成";
    }

    /**
     * 关闭通知
     * @param id
     */
    public void closeById(String id) {
        notifyMapper.closeById(id);
    }

    /**
     * 将选定的通告信息改为已读
     * @param idList
     * @return
     */
    public void portionRead(List<String> idList){
        if(null != idList && idList.size()>0){
            for (String id: idList) {
                notifyRecordService.lambdaUpdate ( ).eq ( JyNotifyRecord::getNotifyId, id )
                        .eq ( JyNotifyRecord::getUserId, SpringUtil.getBean(IUserApi.class).getByToken(TokenProvider.getCurrentToken())).ne ( JyNotifyRecord::getReadFlag, CommonConstants.YES )
                        .set ( JyNotifyRecord::getReadDate, new Date ( ) ).set ( JyNotifyRecord::getReadFlag, CommonConstants.YES ).update ( );
            }
        }
    }

    /**
     * 当前登录人的所有有效通告均改为已读
     * @return
     */
    public String readAll() {
        // 获取当前登录人信息
        UserDTO userDTO = SpringUtil.getBean(IUserApi.class).getByToken(TokenProvider.getCurrentToken());
        notifyMapper.readAll(userDTO.getId());
        return "操作成功";
    }

    /**
     * 添加或修改通知日志
     * @param notifyDTO
     * @return
     */
    public String saveLog(JyNotifyDTO notifyDTO) {
        //获取当前登陆人信息
        UserDTO userDTO = SpringUtil.getBean(IUserApi.class).getByToken(TokenProvider.getCurrentToken());
        //通过通知id查询日志中的数据
        JyNotifyLog jyNotifyLogList=jyNotifyLogMapper.getByNotifyId(notifyDTO.getId(),userDTO.getId());
        if (ObjectUtil.isNotEmpty(jyNotifyLogList)){
            //修改
            JyNotifyLog jyNotifyLog = new JyNotifyLog();
            jyNotifyLog.setId(jyNotifyLogList.getId());
            jyNotifyLog.setCount(jyNotifyLogList.getCount()+1);
            jyNotifyLog.setNotifyId(notifyDTO.getId());
            jyNotifyLog.setUpdateById(userDTO.getId());
            jyNotifyLog.setUpdateTime(new Date());
            jyNotifyLogMapper.updateById(jyNotifyLog);
        }else {
            //不存在则进行添加
            JyNotifyLog jyNotifyLog = new JyNotifyLog();
            jyNotifyLog.setCount(1);
            jyNotifyLog.setNotifyId(notifyDTO.getId());
            jyNotifyLog.setCreateById(userDTO.getId());
            jyNotifyLog.setCreateTime(new Date());
            jyNotifyLog.setUpdateById(userDTO.getId());
            jyNotifyLog.setUpdateTime(new Date());
            jyNotifyLogMapper.insert(jyNotifyLog);
        }
        return "操作成功";
    }


    //获取日志信息
    public List<JyNotifyLog> findByNotifyId(Integer size,String id){
        List<JyNotifyLog> notifyLogList=jyNotifyLogMapper.findByNotifyId(size,id);
        return notifyLogList;
    }

    /**
     * 获取日志数量
     * @param id
     * @return
     */
    public Integer findLogCount(String id) {
        Integer count=jyNotifyLogMapper.findLogCount(id);
        return count;
    }
}
