DirectMessageController.java

package com.wavii.controller;

import com.wavii.dto.dm.DirectConversationDto;
import com.wavii.dto.dm.DirectMessageDto;
import com.wavii.model.User;
import com.wavii.service.ChatRealtimeBroadcaster;
import com.wavii.service.DirectMessageService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.security.core.annotation.AuthenticationPrincipal;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.List;
import java.util.Map;
import java.util.UUID;

@RestController
@RequestMapping("/api/messages/direct")
@RequiredArgsConstructor
@Slf4j
public class DirectMessageController {

    private final DirectMessageService directMessageService;
    private final ChatRealtimeBroadcaster chatRealtimeBroadcaster;

    @GetMapping("/conversations")
    public ResponseEntity<List<DirectConversationDto>> getConversations(
            @AuthenticationPrincipal User me
    ) {
        return ResponseEntity.ok(directMessageService.getConversations(me));
    }

    @GetMapping("/{userId}")
    public ResponseEntity<List<DirectMessageDto>> getConversation(
            @AuthenticationPrincipal User me,
            @PathVariable UUID userId
    ) {
        if (me == null) {
            return ResponseEntity.status(HttpStatus.UNAUTHORIZED).<List<DirectMessageDto>>build();
        }
        try {
            return ResponseEntity.ok(directMessageService.getConversation(me, userId));
        } catch (Exception e) {
            log.error("Error fetching conversation for user {}: {}", me.getId(), e.getMessage());
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).<List<DirectMessageDto>>build();
        }
    }

    @PostMapping("/{userId}")
    public ResponseEntity<DirectMessageDto> sendMessage(
            @AuthenticationPrincipal User me,
            @PathVariable UUID userId,
            @RequestBody Map<String, String> body
    ) {
        if (me == null) {
            return ResponseEntity.status(HttpStatus.UNAUTHORIZED).<DirectMessageDto>build();
        }
        String content = body.get("content");
        if (content == null || content.isBlank()) {
            return ResponseEntity.badRequest().<DirectMessageDto>build();
        }
        try {
            DirectMessageDto saved = directMessageService.sendMessage(me, userId, content);
            chatRealtimeBroadcaster.broadcast(
                    chatRealtimeBroadcaster.directRoom(me.getId(), userId),
                    saved
            );
            return ResponseEntity.status(201).body(saved);
        } catch (Exception e) {
            log.error("Error sending direct message from {} to {}: {}", me.getId(), userId, e.getMessage());
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).<DirectMessageDto>build();
        }
    }
}