package kr.lunaticbum.back.lun.controllers

import kr.lunaticbum.back.lun.model.MessageService
import kr.lunaticbum.back.lun.model.ResultMV
import org.springframework.http.ResponseEntity
import org.springframework.security.access.prepost.PreAuthorize
import org.springframework.security.core.annotation.AuthenticationPrincipal
import org.springframework.security.core.userdetails.UserDetails
import org.springframework.web.bind.annotation.*
import reactor.core.publisher.Mono

// 쪽지 전송 시 Body 데이터를 받기 위한 DTO
data class MessageRequest(val receiverId: String, val title: String, val content: String)

@RestController
@RequestMapping("/messages")
@PreAuthorize("isAuthenticated()") // 모든 메시지 기능은 로그인한 사용자만 가능
class MessageController(private val messageService: MessageService) {

    /**
     * 안 읽은 쪽지 개수를 확인하는 API (헤더 아이콘 표시용)
     */
    @GetMapping("/unread-count")
    fun getUnreadCount(@AuthenticationPrincipal userDetails: UserDetails): Mono<Map<String, Long>> {
        return messageService.getUnreadMessageCount(userDetails.username)
            .map { count -> mapOf("count" to count) }
    }

    /**
     * 쪽지함 페이지를 보여주는 핸들러
     */
    @GetMapping
    fun getInboxPage(@AuthenticationPrincipal userDetails: UserDetails): Mono<ResultMV> {
        val vm = ResultMV("content/messages/inbox")
        return messageService.getMessagesForUser(userDetails.username)
            .collectList()
            .map { messages ->
                vm.modelMap["messages"] = messages
                vm.modelMap["pageTitle"] = "내 쪽지함"
                vm
            }
    }

    /**
     * 쪽지를 보내는 API
     */
    @PostMapping("/send")
    fun sendMessage(
        @AuthenticationPrincipal userDetails: UserDetails,
        @RequestBody request: MessageRequest
    ): Mono<ResponseEntity<String>> {
        return messageService.sendMessage(
            userDetails.username,
            request.receiverId,
            request.title,
            request.content
        ).map { ResponseEntity.ok("메시지를 보냈습니다.") }
    }

    /**
     * 특정 쪽지를 읽음 처리하는 API
     */
    @PostMapping("/{messageId}/read")
    fun markAsRead(
        @PathVariable messageId: String,
        @AuthenticationPrincipal userDetails: UserDetails
    ): Mono<ResponseEntity<Void>> {
        return messageService.markMessageAsRead(messageId, userDetails.username)
            .map { ResponseEntity.ok().build<Void>() }
            .defaultIfEmpty(ResponseEntity.notFound().build())
    }
}