package de.cannamanage.api.controller;

import de.cannamanage.api.dto.notification.ComposeNotificationRequest;
import de.cannamanage.domain.entity.NotificationSend;
import de.cannamanage.domain.enums.TargetType;
import de.cannamanage.service.NotificationService;
import de.cannamanage.service.repository.NotificationSendRepository;
import jakarta.validation.Valid;
import lombok.RequiredArgsConstructor;
import org.springframework.data.domain.PageRequest;
import org.springframework.http.ResponseEntity;
import org.springframework.security.core.annotation.AuthenticationPrincipal;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.web.bind.annotation.*;

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

/**
 * Admin notification compose endpoints.
 * Requires SEND_NOTIFICATIONS permission (checked via StaffPermissionChecker).
 */
@RestController
@RequestMapping("/api/v1/notifications")
@RequiredArgsConstructor
public class NotificationComposeController {

    private final NotificationService notificationService;
    private final NotificationSendRepository notificationSendRepository;

    /**
     * Compose and send a notification (broadcast or targeted).
     */
    @PostMapping("/compose")
    public ResponseEntity<Map<String, Object>> composeAndSend(
            @Valid @RequestBody ComposeNotificationRequest request,
            @AuthenticationPrincipal UserDetails user) {

        UUID authorId = UUID.fromString(user.getUsername());
        NotificationSend send;

        if (request.targetType() == TargetType.ALL) {
            send = notificationService.sendBroadcast(
                    request.title(), request.message(), request.link(), authorId);
        } else {
            if (request.recipientIds() == null || request.recipientIds().isEmpty()) {
                return ResponseEntity.badRequest().body(Map.of("error", "recipientIds required for SELECTED target type"));
            }
            send = notificationService.sendToSelected(
                    request.title(), request.message(), request.link(), authorId, request.recipientIds());
        }

        return ResponseEntity.ok(Map.of(
                "id", send.getId(),
                "targetType", send.getTargetType().name(),
                "targetCount", send.getTargetCount(),
                "sentAt", send.getSentAt().toString()
        ));
    }

    /**
     * List sent notifications (paginated).
     */
    @GetMapping("/sends")
    public ResponseEntity<?> listSends(
            @RequestParam(defaultValue = "0") int page,
            @RequestParam(defaultValue = "20") int size) {

        var sends = notificationSendRepository.findAllByOrderBySentAtDesc(PageRequest.of(page, size));
        var items = sends.getContent().stream().map(s -> Map.of(
                "id", (Object) s.getId(),
                "title", s.getTitle(),
                "targetType", s.getTargetType().name(),
                "targetCount", s.getTargetCount(),
                "readCount", s.getReadCount(),
                "sentAt", s.getSentAt().toString()
        )).toList();

        return ResponseEntity.ok(Map.of(
                "sends", items,
                "totalElements", sends.getTotalElements(),
                "totalPages", sends.getTotalPages()
        ));
    }
}
