using MediatR;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using WhatsAppService.API.Application.Commands;
using WhatsAppService.Domain.AggregatesModel.ConversationAggregate;

namespace WhatsAppService.API.Controllers;

/// <summary>
/// EN: Controller for managing conversations.
/// VI: Controller để quản lý conversations.
/// </summary>
[ApiController]
[Route("api/[controller]")]
[Produces("application/json")]
[Authorize]
public class ConversationsController : ControllerBase
{
    private readonly IMediator _mediator;
    private readonly IConversationRepository _repository;
    private readonly ILogger<ConversationsController> _logger;

    public ConversationsController(
        IMediator mediator,
        IConversationRepository repository,
        ILogger<ConversationsController> logger)
    {
        _mediator = mediator;
        _repository = repository;
        _logger = logger;
    }

    /// <summary>
    /// EN: Get conversations by shop with pagination.
    /// VI: Lấy conversations theo shop với phân trang.
    /// </summary>
    [HttpGet]
    [ProducesResponseType(typeof(object), StatusCodes.Status200OK)]
    public async Task<IActionResult> GetConversations(
        [FromQuery] Guid shopId,
        [FromQuery] string? status,
        [FromQuery] int skip = 0,
        [FromQuery] int take = 20)
    {
        ConversationStatus? statusFilter = null;
        if (!string.IsNullOrEmpty(status))
        {
            statusFilter = ConversationStatus.FromName(status);
        }

        var conversations = await _repository.GetByShopIdAsync(shopId, skip, take, statusFilter);
        
        return Ok(new
        {
            success = true,
            data = conversations.Select(c => new
            {
                id = c.Id,
                customerWaId = c.CustomerWaId,
                status = c.Status.Name,
                assignedAgentId = c.AssignedAgentId,
                lastMessageAt = c.LastMessageAt,
                createdAt = c.CreatedAt,
                expiresAt = c.ExpiresAt,
                messageCount = c.Messages.Count
            })
        });
    }

    /// <summary>
    /// EN: Get conversation by ID with messages.
    /// VI: Lấy conversation theo ID kèm messages.
    /// </summary>
    [HttpGet("{id:guid}")]
    [ProducesResponseType(typeof(object), StatusCodes.Status200OK)]
    [ProducesResponseType(StatusCodes.Status404NotFound)]
    public async Task<IActionResult> GetById(Guid id)
    {
        var conversation = await _repository.GetByIdAsync(id);
        if (conversation == null)
        {
            return NotFound(new { success = false, error = "Conversation not found" });
        }

        return Ok(new
        {
            success = true,
            data = new
            {
                id = conversation.Id,
                customerWaId = conversation.CustomerWaId,
                status = conversation.Status.Name,
                assignedAgentId = conversation.AssignedAgentId,
                lastMessageAt = conversation.LastMessageAt,
                createdAt = conversation.CreatedAt,
                expiresAt = conversation.ExpiresAt,
                messages = conversation.Messages.OrderBy(m => m.Timestamp).Select(m => new
                {
                    id = m.Id,
                    direction = m.Direction,
                    contentType = m.Content.Type,
                    text = m.Content.Text,
                    status = m.Status,
                    timestamp = m.Timestamp
                })
            }
        });
    }

    /// <summary>
    /// EN: Send a message in conversation.
    /// VI: Gửi tin nhắn trong conversation.
    /// </summary>
    [HttpPost("{id:guid}/messages")]
    [ProducesResponseType(typeof(object), StatusCodes.Status200OK)]
    [ProducesResponseType(StatusCodes.Status400BadRequest)]
    public async Task<IActionResult> SendMessage(Guid id, [FromBody] SendMessageRequest request)
    {
        var command = new SendMessageCommand(
            id,
            request.Type,
            request.Text,
            request.MediaUrl,
            request.Caption,
            request.Interactive);

        var result = await _mediator.Send(command);

        if (!result.Success)
        {
            return BadRequest(new { success = false, error = result.Error });
        }

        return Ok(new
        {
            success = true,
            data = new
            {
                messageId = result.MessageId,
                whatsAppMessageId = result.WhatsAppMessageId
            }
        });
    }

    /// <summary>
    /// EN: Close a conversation.
    /// VI: Đóng conversation.
    /// </summary>
    [HttpPost("{id:guid}/close")]
    [ProducesResponseType(StatusCodes.Status204NoContent)]
    [ProducesResponseType(StatusCodes.Status404NotFound)]
    public async Task<IActionResult> Close(Guid id)
    {
        var conversation = await _repository.GetByIdAsync(id);
        if (conversation == null)
        {
            return NotFound(new { success = false, error = "Conversation not found" });
        }

        conversation.Close();
        await _repository.UnitOfWork.SaveEntitiesAsync();

        return NoContent();
    }
}

public record SendMessageRequest(
    string Type,
    string? Text,
    string? MediaUrl,
    string? Caption,
    object? Interactive);
