package org.nl.system.service.notice.impl;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.ObjectUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.nl.common.domain.query.PageQuery;
import org.nl.common.enums.NoticeEnum;
import org.nl.common.exception.BadRequestException;
import org.nl.common.mnt.websocket.MsgType;
import org.nl.common.mnt.websocket.SocketMsg;
import org.nl.common.mnt.websocket.WebSocketServer;
import org.nl.common.utils.SecurityUtils;
import org.nl.system.service.dict.dao.Dict;
import org.nl.system.service.dict.dao.mapper.SysDictMapper;
import org.nl.system.service.notice.ISysNoticeService;
import org.nl.system.service.notice.dao.mapper.SysNoticeMapper;
import org.nl.system.service.notice.dao.SysNotice;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.io.IOException;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.function.Consumer;

/**
* @description 服务实现
* @author lyd
* @date 2023-05-09
**/
@Slf4j
@Service
public class SysNoticeServiceImpl extends ServiceImpl<SysNoticeMapper, SysNotice> implements ISysNoticeService {

    @Autowired
    private SysNoticeMapper sysNoticeMapper;

    @Autowired
    private SysDictMapper dictMapper;

    @Resource
    private WebSocketServer webSocketServer;

    @Override
    public IPage<SysNotice> queryAll(Map whereJson, PageQuery page){
        String notice_title = ObjectUtil.isNotEmpty(whereJson.get("notice_title"))?whereJson.get("notice_title").toString():null;
        String notice_type = ObjectUtil.isNotEmpty(whereJson.get("notice_type"))?whereJson.get("notice_type").toString():null;
        String have_read = ObjectUtil.isNotEmpty(whereJson.get("have_read"))?whereJson.get("have_read").toString():null;
        String deal_status = ObjectUtil.isNotEmpty(whereJson.get("deal_status"))?whereJson.get("deal_status").toString():null;
        LambdaQueryWrapper<SysNotice> lam = new LambdaQueryWrapper<>();
        lam.like(ObjectUtil.isNotEmpty(notice_title), SysNotice::getNotice_title, notice_title)
                .eq(ObjectUtil.isNotEmpty(notice_type), SysNotice::getNotice_type, notice_type)
                .eq(ObjectUtil.isNotEmpty(have_read), SysNotice::getHave_read, have_read)
                .eq(ObjectUtil.isNotEmpty(deal_status), SysNotice::getDeal_status, deal_status)
                .orderByAsc(SysNotice::getHave_read)
                .orderByDesc(SysNotice::getCreate_time);
        IPage<SysNotice> pages = new Page<>(page.getPage() + 1, page.getSize());
        sysNoticeMapper.selectPage(pages, lam);
        return pages;
    }

    @Override
    public void create(SysNotice entity) {
        String now = DateUtil.now();

        entity.setNotice_id(IdUtil.getSnowflake(1, 1).nextIdStr());
        entity.setCreate_time(now);
        sysNoticeMapper.insert(entity);
    }

    @Override
    public void update(SysNotice entity) {
        SysNotice dto = sysNoticeMapper.selectById(entity.getNotice_id());
        if (dto == null) throw new BadRequestException("被删除或无权限，操作失败!");
        sysNoticeMapper.updateById(entity);
    }

    @Override
    public void deleteAll(Set<String> ids) {
        // 真删除
        sysNoticeMapper.deleteBatchIds(ids);
    }

    @Override
    public Integer countByReceiveNotRead() {
        List<SysNotice> sysNotices = sysNoticeMapper.selectList(new LambdaQueryWrapper<SysNotice>().eq(SysNotice::getHave_read, NoticeEnum.HAVE_READ_OFF.getValue()));
        return ObjectUtil.isNotEmpty(sysNotices)?sysNotices.size():0;
    }

    @Override
    public LinkedList<List<SysNotice>> pageByReceive() {
        LinkedList<List<SysNotice>> result = new LinkedList<>();
        List<Dict> dictList = dictMapper.selectList(new LambdaQueryWrapper<Dict>()
                .eq(Dict::getCode, "notice_type")
                .orderByAsc(Dict::getDict_sort));
        dictList.forEach(dict -> {
            List<SysNotice> sysNotices = sysNoticeMapper.selectList(new LambdaQueryWrapper<SysNotice>()
                    .eq(SysNotice::getNotice_type, dict.getValue())
                    .eq(SysNotice::getHave_read, NoticeEnum.HAVE_READ_OFF.getValue())
                    .orderByDesc(SysNotice::getCreate_time)
                    .last("LIMIT 0,3"));
            result.add(sysNotices);
        });
        return result;
    }

    @Override
    public void read(String id) {
        SysNotice notice = this.getById(id);
        if (ObjectUtil.isEmpty(notice)) {
            throw new BadRequestException("该信息不存在!");
        }
        notice.setHave_read(NoticeEnum.HAVE_READ_ON.getValue());
        notice.setRead_time(DateUtil.now());
        sysNoticeMapper.updateById(notice);
    }

    @Override
    public void deal(String id) {
        SysNotice notice = this.getById(id);
        if (ObjectUtil.isEmpty(notice)) {
            throw new BadRequestException("该信息不存在!");
        }
        // 设置处理
        notice.setDeal_status(NoticeEnum.DEAL_STATUS_YES.getValue());
        // 判断是否读取
        if (notice.getHave_read().equals(NoticeEnum.HAVE_READ_OFF.getValue())) {
            // 标记已读并设置读取时间
            notice.setHave_read(NoticeEnum.HAVE_READ_ON.getValue());
            notice.setRead_time(DateUtil.now());
        }
        sysNoticeMapper.updateById(notice);
    }

    @Override
    public void changeRead(JSONObject jsonObject) {
        JSONArray data = jsonObject.getJSONArray("data");
        String haveRead = jsonObject.getString("have_read");
        List<SysNotice> sysNotices = JSON.parseArray(data.toJSONString(), SysNotice.class);
        sysNotices.forEach(sysNotice -> sysNotice.setHave_read(haveRead));
        this.updateBatchById(sysNotices);
    }

    @Override
    public void createNotice(String msg, String title, String type) {
        log.info("创建消息通知-信息：{}, 标题：{}, 类型：{}", msg, title, type);
        // 获取标题相同的信息
        List<SysNotice> sysNotices = sysNoticeMapper.selectList(new LambdaQueryWrapper<SysNotice>()
                .eq(SysNotice::getNotice_title, title)
                .eq(SysNotice::getHave_read, NoticeEnum.HAVE_READ_OFF.getValue()));
        if (ObjectUtil.isNotEmpty(sysNotices)) return;
        SysNotice noticeDto = SysNotice.builder()
                .notice_id(IdUtil.getSnowflake(1, 1).nextIdStr())
                .notice_type(type)
                .notice_title(title)
                .notice_content(msg)
                .deal_status(NoticeEnum.DEAL_STATUS_NO.getValue())
                .have_read(NoticeEnum.HAVE_READ_OFF.getValue())
                .create_time(DateUtil.now())
                .build();
        // 插入
        sysNoticeMapper.insert(noticeDto);
        JSONObject res = new JSONObject();
        res.put("data", "notice_message_update");
        SocketMsg messageInfo = new SocketMsg(res, MsgType.INFO);
        try {
            webSocketServer.sendInfo(messageInfo, "messageInfo");
        } catch (IOException e) {
            throw new BadRequestException("消息发送失败");
        }
    }



}
