package pl.polskalokalnie.message;

import java.util.List;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Service;
import org.springframework.web.server.ResponseStatusException;
import pl.polskalokalnie.moderation.TextModerationService;
import pl.polskalokalnie.notification.NotificationService;
import pl.polskalokalnie.user.AppUser;
import pl.polskalokalnie.user.Role;
import pl.polskalokalnie.user.UserRepository;

@Service
public class MessageService {

    private final MessageRepository messageRepository;
    private final UserRepository userRepository;
    private final TextModerationService textModerationService;
    private final NotificationService notificationService;

    public MessageService(
            MessageRepository messageRepository,
            UserRepository userRepository,
            TextModerationService textModerationService,
            NotificationService notificationService
    ) {
        this.messageRepository = messageRepository;
        this.userRepository = userRepository;
        this.textModerationService = textModerationService;
        this.notificationService = notificationService;
    }

    public AppUser resolveAdmin() {
        return userRepository.findFirstByRole(Role.ADMIN)
                .orElseThrow(() -> new ResponseStatusException(HttpStatus.NOT_FOUND, "Brak konta administratora"));
    }

    public List<MessageResponse> getConversation(Long currentUserId, Long otherUserId) {
        messageRepository.markConversationRead(currentUserId, otherUserId);
        return messageRepository.findConversation(currentUserId, otherUserId).stream()
                .map(message -> MessageResponse.from(message, currentUserId))
                .toList();
    }

    public MessageResponse send(Long senderId, Long recipientId, String content) {
        textModerationService.validateOrThrow(content);

        Message message = new Message();
        message.setSenderId(senderId);
        message.setRecipientId(recipientId);
        message.setContent(content.trim());
        Message saved = messageRepository.save(message);

        notifyRecipient(senderId, recipientId, saved.getContent());

        return MessageResponse.from(saved, senderId);
    }

    // Powiadomienie dla odbiorcy kazdej wiadomosci: admin->user ("Wiadomosc od obslugi"),
    // user->admin traktujemy jako zapytanie/wiadomosc do obslugi.
    private void notifyRecipient(Long senderId, Long recipientId, String content) {
        AppUser recipient = userRepository.findById(recipientId).orElse(null);
        if (recipient == null) {
            return;
        }
        AppUser sender = userRepository.findById(senderId).orElse(null);
        String senderName = sender != null && sender.getFullName() != null && !sender.getFullName().isBlank()
                ? sender.getFullName()
                : "użytkownika";
        String preview = content.length() > 90 ? content.substring(0, 90) + "…" : content;

        if (recipient.getRole() == Role.ADMIN) {
            notificationService.create(recipient.getEmail(), "messages", "message",
                    "Nowa wiadomość od użytkownika",
                    senderName + ": " + preview,
                    "messages", null);
        } else {
            notificationService.create(recipient.getEmail(), "messages", "mail",
                    "Wiadomość od obsługi Mieszko",
                    preview,
                    "messages:admin", null);
        }
    }

    public long countUnreadFrom(Long recipientId, Long senderId) {
        return messageRepository.countByRecipientIdAndSenderIdAndReadFalse(recipientId, senderId);
    }
}
