package com.kym.service.impl;

import cn.dev33.satoken.stp.StpUtil;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.kym.common.utils.IDGenerator;
import com.kym.entity.AdminUser;
import com.kym.entity.Message;
import com.kym.entity.common.PageBean;
import com.kym.entity.queryParams.MessageQueryParams;
import com.kym.entity.vo.MessageVo;
import com.kym.mapper.MessageMapper;
import com.kym.service.AdminUserService;
import com.kym.service.MessageService;
import com.kym.service.mybatisplus.MyBaseServiceImpl;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 消息通知服务实现类
 *
 * @author skyline
 * @since 2024-01-15
 */
@Service
public class MessageServiceImpl extends MyBaseServiceImpl<MessageMapper, Message> implements MessageService {

    private final AdminUserService adminUserService;

    public MessageServiceImpl(AdminUserService adminUserService) {
        this.adminUserService = adminUserService;
    }

    @Override
    @Transactional
    public void sendMessage(MessageVo vo) {
        Message message = new Message();
        BeanUtils.copyProperties(vo, message);

        // 设置发送者信息
        Long senderId = StpUtil.getLoginIdAsLong();
        String senderName = StpUtil.getSession().getString("username");
        message.setSenderId(senderId)
                .setSenderName(senderName)
                .setStatus(0)
                .setBaseId(IDGenerator.INS().nextId());

        // 设置接收者名称
        if (vo.getReceiverId() != null) {
            AdminUser receiver = adminUserService.getById(vo.getReceiverId());
            if (receiver != null) {
                message.setReceiverName(receiver.getNickname());
            }
        }

        save(message);
    }

    @Override
    @Transactional
    public void batchSendMessage(MessageVo vo) {
        if (vo.getReceiverIds() == null || vo.getReceiverIds().isEmpty()) {
            return;
        }

        Long senderId = StpUtil.getLoginIdAsLong();
        String senderName = StpUtil.getSession().getString("username");

        List<Message> messages = new ArrayList<>();
        for (Long receiverId : vo.getReceiverIds()) {
            Message message = new Message();
            message.setTitle(vo.getTitle())
                    .setContent(vo.getContent())
                    .setType(vo.getType())
                    .setSenderId(senderId)
                    .setSenderName(senderName)
                    .setReceiverId(receiverId)
                    .setStatus(0)
                    .setPriority(vo.getPriority() != null ? vo.getPriority() : 0)
                    .setBizType(vo.getBizType())
                    .setBizId(vo.getBizId())
                    .setIsPush(vo.getIsPush() != null ? vo.getIsPush() : 0)
                    .setBaseId(IDGenerator.INS().nextId());

            // 设置接收者名称
            AdminUser receiver = adminUserService.getById(receiverId);
            if (receiver != null) {
                message.setReceiverName(receiver.getNickname());
            }

            messages.add(message);
        }

        saveBatch(messages);
    }

    @Override
    public PageBean<Message> listMessage(MessageQueryParams params) {
        com.github.pagehelper.PageHelper.startPage(params.getPageNum(), params.getPageSize());
        MessageQueryParams queryParams = new MessageQueryParams();
        queryParams.setReceiverId(params.getReceiverId());
        queryParams.setType(params.getType());
        queryParams.setStatus(params.getStatus());
        queryParams.setTitle(params.getTitle());
        queryParams.setPriority(params.getPriority());
        
        List<Message> list = lambdaQuery()
                .ne(Message::getStatus, 2)
                .eq(params.getReceiverId() != null, Message::getReceiverId, params.getReceiverId())
                .eq(params.getType() != null, Message::getType, params.getType())
                .eq(params.getStatus() != null, Message::getStatus, params.getStatus())
                .like(params.getTitle() != null, Message::getTitle, params.getTitle())
                .eq(params.getPriority() != null, Message::getPriority, params.getPriority())
                .orderByDesc(Message::getPriority)
                .orderByDesc(Message::getCreateTime)
                .list();
        return new PageBean<>(list);
    }

    @Override
    public Message getMessageDetail(Long messageId) {
        Message message = getById(messageId);
        // 自动标记已读
        if (message != null && message.getStatus() == 0) {
            message.setStatus(1);
            message.setReadTime(LocalDateTime.now());
            updateById(message);
        }
        return message;
    }

    @Override
    @Transactional
    public void markAsRead(Long messageId) {
        Message message = getById(messageId);
        if (message != null && message.getStatus() == 0) {
            message.setStatus(1);
            message.setReadTime(LocalDateTime.now());
            updateById(message);
        }
    }

    @Override
    @Transactional
    public void batchMarkAsRead(List<Long> messageIds) {
        if (messageIds == null || messageIds.isEmpty()) {
            return;
        }

        List<Message> messages = listByIds(messageIds);
        LocalDateTime now = LocalDateTime.now();
        for (Message message : messages) {
            if (message.getStatus() == 0) {
                message.setStatus(1);
                message.setReadTime(now);
            }
        }
        updateBatchById(messages);
    }

    @Override
    @Transactional
    public void markAllAsRead(Long receiverId, Integer type) {
        baseMapper.batchMarkRead(receiverId, type);
    }

    @Override
    @Transactional
    public void deleteMessage(Long messageId) {
        Message message = getById(messageId);
        if (message != null) {
            message.setStatus(2); // 已删除
            updateById(message);
        }
    }

    @Override
    @Transactional
    public void batchDeleteMessage(List<Long> messageIds) {
        if (messageIds == null || messageIds.isEmpty()) {
            return;
        }

        List<Message> messages = listByIds(messageIds);
        for (Message message : messages) {
            message.setStatus(2); // 已删除
        }
        updateBatchById(messages);
    }

    @Override
    public int getUnreadCount(Long receiverId) {
        return baseMapper.countUnread(receiverId);
    }

    @Override
    public Map<Integer, Integer> getUnreadCountByType(Long receiverId) {
        Map<Integer, Integer> result = new HashMap<>();
        // 类型：1-系统通知，2-站内信，3-待办事项，4-公告通知
        for (int type = 1; type <= 4; type++) {
            result.put(type, baseMapper.countUnreadByType(receiverId, type));
        }
        return result;
    }

    @Override
    public List<Message> getLatestUnread(Long receiverId, int limit) {
        MessageQueryParams params = new MessageQueryParams();
        params.setReceiverId(receiverId);
        params.setStatus(0);
        params.setPageNum(1);
        params.setPageSize(limit);

        IPage<Message> page = new Page<>(1, limit);
        return baseMapper.selectMessagePage(page, params).getRecords();
    }
}
