package com.emonster.taroaichat.web.rest;

import com.emonster.taroaichat.service.ChatService;
import com.emonster.taroaichat.service.dto.ChatBeginInterpretationDTO;
import com.emonster.taroaichat.service.dto.ChatCompleteReadingDTO;
import com.emonster.taroaichat.service.dto.ChatMessageDTO;
import com.emonster.taroaichat.service.dto.ChatSendMessageDTO;
import com.emonster.taroaichat.service.dto.ChatStartReadingDTO;
import com.emonster.taroaichat.service.sse.SseService;
import jakarta.validation.Valid;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.mvc.method.annotation.SseEmitter;

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

/**
 * REST controller for managing chat sessions and Server-Sent Events.
 */
@RestController
@RequestMapping("/api/v1/chat")
public class ChatController {

    private static final Logger log = LoggerFactory.getLogger(ChatController.class);

    private final ChatService chatService;
    private final SseService sseService;

    public ChatController(ChatService chatService, SseService sseService) {
        this.chatService = chatService;
        this.sseService = sseService;
    }

    /**
     * {@code GET  /stream/:sessionId} : Establish SSE connection for real-time updates.
     *
     * @param sessionId the session ID
     * @param lastEventId the last event ID received by client (for reconnection)
     * @return the SSE emitter
     */
    @GetMapping(value = "/stream/{sessionId}", produces = MediaType.TEXT_EVENT_STREAM_VALUE)
    public SseEmitter streamChat(
        @PathVariable Long sessionId,
        @RequestHeader(value = "Last-Event-ID", required = false) String lastEventId
    ) {
        log.debug("REST request to establish SSE connection for session: {}, lastEventId: {}", sessionId, lastEventId);
        
        String sseSessionId = String.valueOf(sessionId);
        SseEmitter emitter = sseService.createEmitter(sseSessionId);
        
        // Send initial connection event with chat history
        // If lastEventId is provided, we could filter messages after that point
        chatService.joinSession(sessionId, sseSessionId, lastEventId);
        
        return emitter;
    }

    /**
     * {@code POST  /send} : Send a message in the chat session.
     *
     * @param dto the message to send
     * @return the saved message
     */
    @PostMapping("/send")
    public ResponseEntity<Map<String, Object>> sendMessage(@Valid @RequestBody ChatSendMessageDTO dto) {
        log.debug("REST request to send message: {}", dto);
        
        ChatMessageDTO savedMessage = chatService.sendMessage(dto);
        
        Map<String, Object> response = new HashMap<>();
        response.put("success", true);
        response.put("messageId", savedMessage.getId());
        response.put("timestamp", savedMessage.getCreatedDate());
        
        return ResponseEntity.ok(response);
    }

    /**
     * {@code POST  /start-reading} : Start a tarot reading within a chat session.
     *
     * @param dto the reading parameters
     * @return success response
     */
    @PostMapping("/start-reading")
    public ResponseEntity<Map<String, Object>> startReading(@Valid @RequestBody ChatStartReadingDTO dto) {
        log.debug("REST request to start tarot reading: {}", dto);
        
        chatService.startReading(dto);
        
        Map<String, Object> response = Map.of(
            "success", true,
            "message", "Reading initiated"
        );
        
        return ResponseEntity.ok(response);
    }

    /**
     * {@code GET  /history/:sessionId} : Get chat history for a session.
     *
     * @param sessionId the session ID
     * @return the chat history
     */
    @GetMapping("/history/{sessionId}")
    public ResponseEntity<List<ChatMessageDTO>> getChatHistory(@PathVariable Long sessionId) {
        log.debug("REST request to get chat history for session: {}", sessionId);
        
        List<ChatMessageDTO> history = chatService.getChatHistory(sessionId);
        return ResponseEntity.ok(history);
    }

    /**
     * {@code POST  /begin-interpretation} : Begin tarot reading interpretation.
     *
     * @param dto the begin interpretation parameters
     * @return success response
     */
    @PostMapping("/begin-interpretation")
    public ResponseEntity<Map<String, Object>> beginInterpretation(@Valid @RequestBody ChatBeginInterpretationDTO dto) {
        log.debug("REST request to begin interpretation: {}", dto);
        
        chatService.beginInterpretation(dto.getSessionId());
        
        Map<String, Object> response = Map.of(
            "success", true,
            "message", "Interpretation begun"
        );
        
        return ResponseEntity.ok(response);
    }

    /**
     * {@code POST  /complete-reading} : Complete tarot reading.
     *
     * @param dto the complete reading parameters
     * @return success response
     */
    @PostMapping("/complete-reading")
    public ResponseEntity<Map<String, Object>> completeReading(@Valid @RequestBody ChatCompleteReadingDTO dto) {
        log.debug("REST request to complete reading: {}", dto);
        
        chatService.completeReading(dto.getSessionId());
        
        Map<String, Object> response = Map.of(
            "success", true,
            "message", "Reading completion initiated"
        );
        
        return ResponseEntity.ok(response);
    }

    /**
     * {@code POST  /summary} : Smart complete reading - checks for missing interpretations and fills them.
     *
     * @param dto the complete reading parameters
     * @return success response
     */
    @PostMapping("/summary")
    public ResponseEntity<Map<String, Object>> smartCompleteReading(@Valid @RequestBody ChatCompleteReadingDTO dto) {
        log.debug("REST request to smart complete reading: {}", dto);
        
        chatService.smartCompleteReading(dto.getSessionId());
        
        Map<String, Object> response = Map.of(
            "success", true,
            "message", "Smart reading completion initiated"
        );
        
        return ResponseEntity.ok(response);
    }

    /**
     * {@code POST  /typing} : Send typing indicator.
     *
     * @param sessionId the session ID
     * @return success response
     */
    @PostMapping("/typing")
    public ResponseEntity<Map<String, Object>> sendTypingIndicator(@RequestParam Long sessionId) {
        log.debug("REST request to send typing indicator for session: {}", sessionId);
        
        // TODO: Implement typing indicator logic if needed
        
        Map<String, Object> response = Map.of("success", true);
        return ResponseEntity.ok(response);
    }
}