package com.yaoyuan.jiscuss.service.impl;

import com.yaoyuan.jiscuss.entity.Message;
import com.yaoyuan.jiscuss.repository.MessageRepository;
import com.yaoyuan.jiscuss.service.IMessageService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Date;
import java.util.List;

@Service
public class MessageServiceImpl implements IMessageService {

    @Autowired
    private MessageRepository messageRepository;

    private String buildConversationId(Integer a, Integer b) {
        return Math.min(a, b) + "_" + Math.max(a, b);
    }

    @Transactional
    @Override
    public Message send(Integer senderId, Integer receiverId, String content) {
        Message msg = new Message();
        msg.setSenderId(senderId);
        msg.setReceiverId(receiverId);
        msg.setContent(content);
        msg.setIsRead(false);
        msg.setCreateTime(new Date());
        msg.setConversationId(buildConversationId(senderId, receiverId));
        return messageRepository.save(msg);
    }

    @Transactional(readOnly = true)
    @Override
    public List<Message> getConversation(Integer userId, Integer otherId) {
        String convId = buildConversationId(userId, otherId);
        List<Message> msgs = messageRepository.findByConversationIdOrderByCreateTimeDesc(convId);
        // reverse to get oldest-first order
        java.util.Collections.reverse(msgs);
        return msgs;
    }

    @Transactional(readOnly = true)
    @Override
    public List<Message> getInbox(Integer userId) {
        // Fetch sent and received separately, merge, then deduplicate by conversationId
        List<Message> sent = messageRepository.findBySenderIdOrderByCreateTimeDesc(userId);
        List<Message> received = messageRepository.findByReceiverIdOrderByCreateTimeDesc(userId);

        // Merge both lists, sort by createTime descending
        java.util.List<Message> all = new java.util.ArrayList<>();
        all.addAll(sent);
        all.addAll(received);
        all.sort((a, b) -> {
            if (a.getCreateTime() == null) return 1;
            if (b.getCreateTime() == null) return -1;
            return b.getCreateTime().compareTo(a.getCreateTime());
        });

        // Keep only the latest message per conversation
        java.util.LinkedHashMap<String, Message> seen = new java.util.LinkedHashMap<>();
        for (Message m : all) {
            String cid = (m.getConversationId() != null && !m.getConversationId().isEmpty())
                    ? m.getConversationId()
                    : Math.min(m.getSenderId(), m.getReceiverId()) + "_" + Math.max(m.getSenderId(), m.getReceiverId());
            seen.putIfAbsent(cid, m);
        }
        return new java.util.ArrayList<>(seen.values());
    }

    @Transactional(readOnly = true)
    @Override
    public long countUnread(Integer userId) {
        return messageRepository.countByReceiverIdAndIsReadFalse(userId);
    }

    @Transactional
    @Override
    public void markConversationRead(Integer userId, Integer otherId) {
        messageRepository.markConversationReadForUser(buildConversationId(userId, otherId), userId);
    }
}
