using MediatR;
using Microsoft.Extensions.Logging;
using MktZaloService.API.Application.Commands.Messages;
using MktZaloService.API.Application.Services;
using MktZaloService.Domain.AggregatesModel.ChatbotRuleAggregate;
using MktZaloService.Domain.Enums;
using MktZaloService.Domain.Events;

namespace MktZaloService.API.Application.DomainEventHandlers;

/// <summary>
/// EN: Handler for MessageReceivedDomainEvent - triggers chatbot auto-response.
/// VI: Handler cho MessageReceivedDomainEvent - kích hoạt phản hồi tự động chatbot.
/// </summary>
public class MessageReceivedDomainEventHandler : INotificationHandler<MessageReceivedDomainEvent>
{
    private readonly IChatbotRulesService _rulesService;
    private readonly IChatbotRuleRepository _ruleRepository;
    private readonly IMediator _mediator;
    private readonly ILogger<MessageReceivedDomainEventHandler> _logger;

    public MessageReceivedDomainEventHandler(
        IChatbotRulesService rulesService,
        IChatbotRuleRepository ruleRepository,
        IMediator mediator,
        ILogger<MessageReceivedDomainEventHandler> logger)
    {
        _rulesService = rulesService;
        _ruleRepository = ruleRepository;
        _mediator = mediator;
        _logger = logger;
    }

    public async Task Handle(
        MessageReceivedDomainEvent notification,
        CancellationToken cancellationToken)
    {
        // EN: Skip if message is from bot (avoid infinite loops)
        // VI: Bỏ qua nếu tin nhắn từ bot (tránh vòng lặp vô hạn)
        if (notification.IsFromBot)
        {
            return;
        }

        _logger.LogDebug(
            "EN: Processing message for chatbot rules. VI: Đang xử lý tin nhắn cho quy tắc chatbot");

        // EN: Find matching rule / VI: Tìm quy tắc khớp
        var matchedRule = await _rulesService.FindMatchingRuleAsync(
            notification.Content,
            cancellationToken);

        if (matchedRule == null)
        {
            _logger.LogDebug("EN: No rule matched. VI: Không có quy tắc nào khớp");
            return;
        }

        // EN: Record the match / VI: Ghi nhận kết quả khớp
        matchedRule.RecordMatch(notification.ConversationId, notification.Content);
        _ruleRepository.Update(matchedRule);
        await _ruleRepository.UnitOfWork.SaveEntitiesAsync(cancellationToken);

        // EN: Handle action based on type / VI: Xử lý hành động dựa trên loại
        switch (matchedRule.Action.ActionType)
        {
            case ActionType.SendText:
                await HandleSendTextAsync(notification.ConversationId, matchedRule, cancellationToken);
                break;

            case ActionType.SendTemplate:
                // EN: Template sending requires additional implementation
                // VI: Gửi mẫu cần triển khai bổ sung
                _logger.LogInformation(
                    "EN: Template {TemplateId} would be sent. VI: Mẫu {TemplateId} sẽ được gửi",
                    matchedRule.Action.TemplateId);
                break;

            case ActionType.ForwardToHuman:
                // EN: Mark for human attention (could notify staff)
                // VI: Đánh dấu để nhân viên chú ý (có thể thông báo cho staff)
                _logger.LogInformation(
                    "EN: Conversation {ConversationId} forwarded to human. VI: Cuộc hội thoại {ConversationId} chuyển đến nhân viên",
                    notification.ConversationId);
                break;
        }
    }

    private async Task HandleSendTextAsync(
        Guid conversationId,
        ChatbotRule rule,
        CancellationToken ct)
    {
        var responseText = _rulesService.GetResponseText(rule);

        if (string.IsNullOrEmpty(responseText))
        {
            return;
        }

        var sendCommand = new SendMessageCommand(
            conversationId,
            responseText,
            IsFromBot: true);

        var result = await _mediator.Send(sendCommand, ct);

        if (result.Success)
        {
            _logger.LogInformation(
                "EN: Auto-response sent for rule '{RuleName}'. VI: Phản hồi tự động đã gửi cho quy tắc '{RuleName}'",
                rule.Name);
        }
        else
        {
            _logger.LogWarning(
                "EN: Failed to send auto-response: {Error}. VI: Không thể gửi phản hồi tự động: {Error}",
                result.Error);
        }
    }
}
