using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using MediatR;
using ChatService.API.Application.Commands.Messages;
using ChatService.API.Application.Queries.Messages;

namespace ChatService.API.Controllers;

/// <summary>
/// EN: Controller for message management.
/// VI: Controller để quản lý tin nhắn.
/// </summary>
[ApiController]
[Route("api/[controller]")]
[Authorize]
public class MessagesController : ControllerBase
{
    private readonly IMediator _mediator;
    private readonly ILogger<MessagesController> _logger;

    public MessagesController(IMediator mediator, ILogger<MessagesController> logger)
    {
        _mediator = mediator;
        _logger = logger;
    }

    /// <summary>
    /// EN: Send an encrypted message.
    /// VI: Gửi tin nhắn đã mã hóa.
    /// </summary>
    [HttpPost]
    [ProducesResponseType(typeof(SendMessageResult), StatusCodes.Status200OK)]
    [ProducesResponseType(StatusCodes.Status400BadRequest)]
    [ProducesResponseType(StatusCodes.Status404NotFound)]
    public async Task<IActionResult> SendMessage([FromBody] SendMessageRequest request)
    {
        var command = new SendMessageCommand(
            request.ConversationId,
            request.SenderId,
            request.EncryptedContent,
            request.Nonce,
            request.AuthTag,
            request.MessageType,
            request.Metadata,
            request.ReplyToMessageId);

        try
        {
            var result = await _mediator.Send(command);
            return Ok(result);
        }
        catch (InvalidOperationException ex)
        {
            return NotFound(ex.Message);
        }
    }

    /// <summary>
    /// EN: Get messages in a conversation.
    /// VI: Lấy tin nhắn trong cuộc hội thoại.
    /// </summary>
    [HttpGet("conversation/{conversationId:guid}")]
    [ProducesResponseType(typeof(GetMessagesResult), StatusCodes.Status200OK)]
    [ProducesResponseType(StatusCodes.Status403Forbidden)]
    public async Task<IActionResult> GetMessages(
        Guid conversationId,
        [FromQuery] Guid userId,
        [FromQuery] int page = 1,
        [FromQuery] int pageSize = 50,
        [FromQuery] DateTime? before = null)
    {
        var query = new GetMessagesQuery(conversationId, userId, page, pageSize, before);

        try
        {
            var result = await _mediator.Send(query);
            return Ok(result);
        }
        catch (UnauthorizedAccessException ex)
        {
            return Forbid(ex.Message);
        }
    }

    /// <summary>
    /// EN: Mark messages as read.
    /// VI: Đánh dấu tin nhắn đã đọc.
    /// </summary>
    [HttpPost("read")]
    [ProducesResponseType(typeof(MarkMessagesReadResult), StatusCodes.Status200OK)]
    [ProducesResponseType(StatusCodes.Status404NotFound)]
    public async Task<IActionResult> MarkAsRead([FromBody] MarkReadRequest request)
    {
        var command = new MarkMessagesReadCommand(
            request.ConversationId,
            request.UserId,
            request.LastReadMessageId,
            request.ReadUpTo);

        try
        {
            var result = await _mediator.Send(command);
            return Ok(result);
        }
        catch (InvalidOperationException ex)
        {
            return NotFound(ex.Message);
        }
    }
}

#region Request DTOs

public record SendMessageRequest(
    Guid ConversationId,
    Guid SenderId,
    string EncryptedContent,
    string Nonce,
    string? AuthTag = null,
    string MessageType = "text",
    string? Metadata = null,
    Guid? ReplyToMessageId = null
);

public record MarkReadRequest(
    Guid ConversationId,
    Guid UserId,
    Guid? LastReadMessageId = null,
    DateTime? ReadUpTo = null
);

#endregion
