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

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.ObjectUtil;
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.notify.domain.*;
import com.jeeplus.notify.mapper.NotifyMapper;
import com.jeeplus.notify.mapper.PluginNotifyCommentsMapper;
import com.jeeplus.notify.mapper.PluginNotifyOfficesMapper;
import com.jeeplus.notify.mapper.PluginNotifyUserMapper;
import com.jeeplus.notify.service.dto.NotifyDTO;
import com.jeeplus.notify.service.dto.PluginNotifyOfficesDTO;
import com.jeeplus.notify.service.mapstruct.NotifyRecordWrapper;
import com.jeeplus.notify.service.mapstruct.NotifyWrapper;
import com.jeeplus.sys.constant.CommonConstants;
import com.jeeplus.sys.domain.User;
import com.jeeplus.sys.mapper.UserMapper;
import com.jeeplus.sys.service.dto.UserDTO;
import com.jeeplus.sys.utils.StringUtils;
import com.jeeplus.sys.utils.UserUtils;
import com.jeeplus.test.cw.common.CommonUtils;
import com.jeeplus.test.cw.workClientInfo.domain.CwWorkClientBase;
import com.jeeplus.test.cw.workClientInfo.service.dto.CwWorkClientBaseDTO;
import com.jeeplus.test.cw.workClientInfo.service.mapstruct.CwWorkClientBaseWrapper;
import com.jeeplus.test.editor.domain.EditorFiles;
import com.jeeplus.test.editor.service.EditorFilesService;
import com.jeeplus.test.editor.service.dto.EditorFilesDTO;
import com.jeeplus.test.knowledge.domain.KnowledgeShareComment;
import com.jeeplus.test.oss.service.OssService;
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.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.UUID;
import java.util.stream.Collectors;

/**
 * 通知通告Service
 *
 * @author jeeplus
 * @version 2021-05-16
 */
@Service
@Transactional
public class NotifyService extends ServiceImpl <NotifyMapper, Notify> {

    @Autowired
    private NotifyRecordService notifyRecordService;

    @Resource
    private OssService ossService;

    @Resource
    private PluginNotifyOfficesMapper pluginNotifyOfficesMapper;

    @Resource
    private PluginNotifyUserMapper pluginNotifyUserMapper;

    @Resource
    private EditorFilesService editorFilesService;

    @Resource
    private UserMapper userMapper;

    @Resource
    private PluginNotifyCommentsMapper commentsMapper;

    @Resource
    private NotifyMapper notifyMapper;

    /**
     * 根据id获取通知
     */
    public NotifyDTO getById(String id) {
        return baseMapper.getById ( id );
    }

    /**
     * 自定义分页检索
     *
     * @param page
     * @param queryWrapper
     * @return
     */
    public IPage <NotifyDTO> findPage(Page <NotifyDTO> 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 <NotifyDTO> myNotifyDataFindPage(Page <NotifyDTO> 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 NotifyDTO getDetail(String id) {
        NotifyDTO notifyDTO = baseMapper.getById ( id );
        if (ObjectUtil.isNotEmpty(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);
            }
            if (CollectionUtil.isNotEmpty(notifyDTO.getComments())){
                notifyDTO.getComments().stream().forEach(item -> {
                    item.setDeff(CommonUtils.timeDef(item.getCreateDate()));
                });
            }
            return notifyDTO;
        } else {
            return new NotifyDTO();
        }
    }

    // 通知审核通过时，向通知接收人发送通知
    // 根据所选接收部门以及所选接收用户，获取通知的接收人
    public String pushNotifyRecord(String id) {
        NotifyDTO detail = this.getDetail(id);
        List<String> uIds = new ArrayList<>();
        List<NotifyRecord> 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)) {
                    List<User> userList = userMapper.selectList(new LambdaQueryWrapper<User>().in(User::getOfficeId, officeIds));
                    if (CollectionUtil.isNotEmpty(userList)) {
                        userList.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 -> {
                NotifyRecord notifyRecord = new NotifyRecord();
                notifyRecord.setUserId(userId);
                notifyRecord.setNotifyId(id);
                notifyRecord.setReadFlag("0");
                notifyRecordList.add(notifyRecord);
            });
        }
        notifyRecordService.remove(new LambdaQueryWrapper<NotifyRecord>().eq(NotifyRecord::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(NotifyDTO notifyDTO) {
        Notify notify = NotifyWrapper.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());
                });
            }
            // 附件
            ossService.saveOrUpdateFileList(notifyDTO.getWorkAttachmentDtoList(),notify.getId(),"plugin_notify");
            // 部门信息
            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(NotifyDTO notifyDTO){
        this.saveForm(notifyDTO);
        return ResponseEntity.ok("保存成功");
    }

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

    /**
     * 更新阅读状态
     */
    public void updateReadFlag(String id) {
        notifyRecordService.lambdaUpdate ( ).eq ( NotifyRecord::getNotifyId, id )
                .eq ( NotifyRecord::getUserId, UserUtils.getCurrentUserDTO ( ).getId ( ) ).ne ( NotifyRecord::getReadFlag, CommonConstants.YES )
                .set ( NotifyRecord::getReadDate, new Date ( ) ).set ( NotifyRecord::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 ( NotifyRecord::getNotifyId, id )
                        .eq ( NotifyRecord::getUserId, UserUtils.getCurrentUserDTO ( ).getId ( ) ).ne ( NotifyRecord::getReadFlag, CommonConstants.YES )
                        .set ( NotifyRecord::getReadDate, new Date ( ) ).set ( NotifyRecord::getReadFlag, CommonConstants.YES ).update ( );
            }
        }
    }

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