package de.assecutor.votianlt.controller;

import de.assecutor.votianlt.model.Message;
import de.assecutor.votianlt.model.MessageContentType;
import de.assecutor.votianlt.model.MessageOrigin;
import de.assecutor.votianlt.service.MessageService;
import lombok.extern.slf4j.Slf4j;
import org.bson.types.ObjectId;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

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

/**
 * REST API controller for message operations. Provides endpoints for sending
 * messages, retrieving messages, and marking messages as read.
 */
@RestController
@RequestMapping("/api/messages")
@Slf4j
public class MessageApiController {

    private final MessageService messageService;

    public MessageApiController(MessageService messageService) {
        this.messageService = messageService;
    }

    /**
     * Send a general message to a client POST /api/messages/send Body: { "content":
     * "message text", "receiver": "appUserId", "contentType": "TEXT|IMAGE" }
     */
    @PostMapping("/send")
    public ResponseEntity<Message> sendGeneralMessage(@RequestBody Map<String, String> request) {
        try {
            String content = request.get("content");
            String receiver = request.get("receiver");
            MessageContentType contentType = resolveContentType(request.get("contentType"));

            if (content == null || content.isBlank() || receiver == null || receiver.isBlank()) {
                log.warn("Invalid message request: missing required fields");
                return ResponseEntity.badRequest().build();
            }

            Message message = messageService.sendGeneralMessageToClient(content, receiver, contentType);
            log.info("General message sent to AppUser '{}'", receiver);
            return ResponseEntity.ok(message);

        } catch (IllegalArgumentException e) {
            log.warn("Invalid general message request: {}", e.getMessage());
            return ResponseEntity.badRequest().build();
        } catch (Exception e) {
            log.error("Error sending general message: {}", e.getMessage(), e);
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).build();
        }
    }

    /**
     * Send a job-related message to a client POST /api/messages/send-job-message
     * Body: { "content": "message text", "receiver": "appUserId", "jobId": "job
     * id", "jobNumber": "job number", "contentType": "TEXT|IMAGE" }
     */
    @PostMapping("/send-job-message")
    public ResponseEntity<Message> sendJobMessage(@RequestBody Map<String, String> request) {
        try {
            String content = request.get("content");
            String receiver = request.get("receiver");
            String jobIdStr = request.get("jobId");
            String jobNumber = request.get("jobNumber");
            MessageContentType contentType = resolveContentType(request.get("contentType"));

            if (content == null || content.isBlank() || receiver == null || receiver.isBlank() || jobIdStr == null
                    || jobIdStr.isBlank()) {
                log.warn("Invalid job message request: missing required fields");
                return ResponseEntity.badRequest().build();
            }

            ObjectId jobId = new ObjectId(jobIdStr);
            Message message = messageService.sendJobMessageToClient(content, receiver, contentType, jobId, jobNumber);
            log.info("Job-related message sent to AppUser '{}' for job {}", receiver, jobNumber);
            return ResponseEntity.ok(message);

        } catch (IllegalArgumentException e) {
            log.warn("Invalid job message request: {}", e.getMessage());
            return ResponseEntity.badRequest().build();
        } catch (Exception e) {
            log.error("Error sending job message: {}", e.getMessage(), e);
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).build();
        }
    }

    /**
     * Get all messages for a specific receiver GET
     * /api/messages/receiver/{username}
     */
    @GetMapping("/receiver/{username}")
    public ResponseEntity<List<Message>> getMessagesForReceiver(@PathVariable String username) {
        try {
            List<Message> messages = messageService.getMessagesForReceiver(username);
            return ResponseEntity.ok(messages);
        } catch (Exception e) {
            log.error("Error retrieving messages for receiver {}: {}", username, e.getMessage(), e);
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).build();
        }
    }

    /**
     * Get all unread messages for a specific receiver GET
     * /api/messages/receiver/{username}/unread
     */
    @GetMapping("/receiver/{username}/unread")
    public ResponseEntity<List<Message>> getUnreadMessagesForReceiver(@PathVariable String username) {
        try {
            List<Message> messages = messageService.getUnreadMessagesForReceiver(username);
            return ResponseEntity.ok(messages);
        } catch (Exception e) {
            log.error("Error retrieving unread messages for receiver {}: {}", username, e.getMessage(), e);
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).build();
        }
    }

    /**
     * Get unread message count for a specific receiver GET
     * /api/messages/receiver/{username}/unread-count
     */
    @GetMapping("/receiver/{username}/unread-count")
    public ResponseEntity<Map<String, Long>> getUnreadMessageCount(@PathVariable String username) {
        try {
            long count = messageService.getUnreadMessageCount(username);
            return ResponseEntity.ok(Map.of("count", count));
        } catch (Exception e) {
            log.error("Error retrieving unread message count for receiver {}: {}", username, e.getMessage(), e);
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).build();
        }
    }

    /**
     * Get all messages related to a specific job GET /api/messages/job/{jobId}
     */
    @GetMapping("/job/{jobId}")
    public ResponseEntity<List<Message>> getMessagesForJob(@PathVariable String jobId) {
        try {
            ObjectId objectId = new ObjectId(jobId);
            List<Message> messages = messageService.getMessagesForJob(objectId);
            return ResponseEntity.ok(messages);
        } catch (IllegalArgumentException e) {
            log.error("Invalid jobId format: {}", e.getMessage());
            return ResponseEntity.badRequest().build();
        } catch (Exception e) {
            log.error("Error retrieving messages for job {}: {}", jobId, e.getMessage(), e);
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).build();
        }
    }

    /**
     * Get all messages (for admin/overview) GET /api/messages/all
     */
    @GetMapping("/all")
    public ResponseEntity<List<Message>> getAllMessages() {
        try {
            List<Message> messages = messageService.getAllMessages();
            return ResponseEntity.ok(messages);
        } catch (Exception e) {
            log.error("Error retrieving all messages: {}", e.getMessage(), e);
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).build();
        }
    }

    /**
     * Get messages by origin (incoming/outgoing/server) GET
     * /api/messages/origin/{origin}
     */
    @GetMapping("/origin/{origin}")
    public ResponseEntity<List<Message>> getMessagesByOrigin(@PathVariable String origin) {
        try {
            MessageOrigin messageOrigin = MessageOrigin.valueOf(origin.toUpperCase());
            List<Message> messages = messageService.getMessagesByOrigin(messageOrigin);
            return ResponseEntity.ok(messages);
        } catch (IllegalArgumentException e) {
            log.error("Invalid origin: {}", origin);
            return ResponseEntity.badRequest().build();
        } catch (Exception e) {
            log.error("Error retrieving messages by origin {}: {}", origin, e.getMessage(), e);
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).build();
        }
    }

    /**
     * Mark a message as read PUT /api/messages/{messageId}/mark-read
     */
    @PutMapping("/{messageId}/mark-read")
    public ResponseEntity<Void> markMessageAsRead(@PathVariable String messageId) {
        try {
            ObjectId objectId = new ObjectId(messageId);
            messageService.markAsRead(objectId);
            return ResponseEntity.ok().build();
        } catch (IllegalArgumentException e) {
            log.error("Invalid messageId format: {}", e.getMessage());
            return ResponseEntity.badRequest().build();
        } catch (Exception e) {
            log.error("Error marking message as read {}: {}", messageId, e.getMessage(), e);
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).build();
        }
    }

    /**
     * Delete a message DELETE /api/messages/{messageId}
     */
    @DeleteMapping("/{messageId}")
    public ResponseEntity<Void> deleteMessage(@PathVariable String messageId) {
        try {
            ObjectId objectId = new ObjectId(messageId);
            messageService.deleteMessage(objectId);
            return ResponseEntity.ok().build();
        } catch (IllegalArgumentException e) {
            log.error("Invalid messageId format: {}", e.getMessage());
            return ResponseEntity.badRequest().build();
        } catch (Exception e) {
            log.error("Error deleting message {}: {}", messageId, e.getMessage(), e);
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).build();
        }
    }

    private MessageContentType resolveContentType(String rawValue) {
        if (rawValue == null || rawValue.isBlank()) {
            return MessageContentType.TEXT;
        }

        try {
            return MessageContentType.valueOf(rawValue.trim().toUpperCase());
        } catch (IllegalArgumentException ex) {
            throw new IllegalArgumentException("Unsupported contentType: " + rawValue, ex);
        }
    }
}
