using MediatR;
using FacebookService.Domain.AggregatesModel.CustomerAggregate;
using FacebookService.Domain.AggregatesModel.ConversationAggregate;

namespace FacebookService.API.Application.Commands;

/// <summary>
/// EN: Handler for ProcessIncomingMessageCommand.
/// VI: Handler cho ProcessIncomingMessageCommand.
/// </summary>
public class ProcessIncomingMessageHandler : IRequestHandler<ProcessIncomingMessageCommand, ProcessIncomingMessageResult>
{
    private readonly ICustomerRepository _customerRepository;
    private readonly IConversationRepository _conversationRepository;
    private readonly ILogger<ProcessIncomingMessageHandler> _logger;

    public ProcessIncomingMessageHandler(
        ICustomerRepository customerRepository,
        IConversationRepository conversationRepository,
        ILogger<ProcessIncomingMessageHandler> logger)
    {
        _customerRepository = customerRepository ?? throw new ArgumentNullException(nameof(customerRepository));
        _conversationRepository = conversationRepository ?? throw new ArgumentNullException(nameof(conversationRepository));
        _logger = logger ?? throw new ArgumentNullException(nameof(logger));
    }

    public async Task<ProcessIncomingMessageResult> Handle(
        ProcessIncomingMessageCommand request,
        CancellationToken cancellationToken)
    {
        _logger.LogInformation(
            "Processing incoming message from sender: {SenderId} on page: {PageId}",
            request.SenderId, request.PageId);

        var isNewCustomer = false;
        var isNewConversation = false;

        // EN: Step 1 - Get or create customer / VI: Bước 1 - Lấy hoặc tạo customer
        var customer = await _customerRepository.GetByFacebookUserIdAsync(request.SenderId, cancellationToken);
        
        if (customer is null)
        {
            customer = new Customer(request.SenderId);
            _customerRepository.Add(customer);
            isNewCustomer = true;
            
            _logger.LogInformation("Created new customer for sender: {SenderId}", request.SenderId);
        }
        else
        {
            customer.RecordInteraction();
            _customerRepository.Update(customer);
        }

        // EN: Step 2 - Get or create conversation / VI: Bước 2 - Lấy hoặc tạo conversation
        var conversation = await _conversationRepository.FindActiveByCustomerAndPageAsync(
            customer.Id, request.PageId, cancellationToken);

        if (conversation is null)
        {
            conversation = new Conversation(customer.Id, request.PageId);
            _conversationRepository.Add(conversation);
            isNewConversation = true;
            
            _logger.LogInformation("Created new conversation for customer: {CustomerId}", customer.Id);
        }

        // EN: Step 3 - Add incoming message / VI: Bước 3 - Thêm tin nhắn đến
        var message = new Message(
            senderId: request.SenderId,
            content: request.MessageText,
            messageType: MessageType.Text,
            direction: MessageDirection.Incoming,
            facebookMessageId: request.FacebookMessageId,
            metadata: request.QuickReplyPayload != null 
                ? new Dictionary<string, object> { ["quick_reply_payload"] = request.QuickReplyPayload }
                : null
        );

        conversation.AddMessage(message);
        _conversationRepository.Update(conversation);

        // EN: Step 4 - Save all changes / VI: Bước 4 - Lưu tất cả thay đổi
        await _conversationRepository.UnitOfWork.SaveEntitiesAsync(cancellationToken);

        _logger.LogInformation(
            "Message processed successfully. ConversationId: {ConversationId}, MessageId: {MessageId}",
            conversation.Id, message.Id);

        return new ProcessIncomingMessageResult(
            ConversationId: conversation.Id,
            CustomerId: customer.Id,
            MessageId: message.Id,
            IsNewConversation: isNewConversation,
            IsNewCustomer: isNewCustomer
        );
    }
}
