using MktZaloService.Domain.AggregatesModel.ChatbotRuleAggregate;
using MktZaloService.Infrastructure.Caching;
using Microsoft.Extensions.Logging;

namespace MktZaloService.API.Application.Services;

/// <summary>
/// EN: Interface for chatbot rule matching service.
/// VI: Interface cho service khớp quy tắc chatbot.
/// </summary>
public interface IChatbotRulesService
{
    /// <summary>
    /// EN: Find matching rule for user message.
    /// VI: Tìm quy tắc khớp cho tin nhắn người dùng.
    /// </summary>
    Task<ChatbotRule?> FindMatchingRuleAsync(
        string userMessage,
        CancellationToken ct = default);

    /// <summary>
    /// EN: Get response text for matched rule.
    /// VI: Lấy văn bản phản hồi cho quy tắc khớp.
    /// </summary>
    string? GetResponseText(ChatbotRule rule);
}

/// <summary>
/// EN: Service for matching chatbot rules against user messages.
/// VI: Service để khớp quy tắc chatbot với tin nhắn người dùng.
/// </summary>
public class ChatbotRulesService : IChatbotRulesService
{
    private readonly IChatbotRuleRepository _ruleRepository;
    private readonly IChatbotRuleCacheService _cacheService;
    private readonly ILogger<ChatbotRulesService> _logger;

    public ChatbotRulesService(
        IChatbotRuleRepository ruleRepository,
        IChatbotRuleCacheService cacheService,
        ILogger<ChatbotRulesService> logger)
    {
        _ruleRepository = ruleRepository;
        _cacheService = cacheService;
        _logger = logger;
    }

    /// <summary>
    /// EN: Find matching rule for user message (highest priority first).
    /// VI: Tìm quy tắc khớp cho tin nhắn người dùng (ưu tiên cao nhất trước).
    /// </summary>
    public async Task<ChatbotRule?> FindMatchingRuleAsync(
        string userMessage,
        CancellationToken ct = default)
    {
        if (string.IsNullOrWhiteSpace(userMessage))
        {
            return null;
        }

        // EN: Get active rules (cached or from DB)
        // VI: Lấy các quy tắc đang hoạt động (từ cache hoặc DB)
        var rules = await _cacheService.GetActiveRulesAsync(
            () => _ruleRepository.GetActiveRulesOrderedByPriorityAsync(ct),
            ct);

        // EN: Evaluate rules in priority order, return first match
        // VI: Đánh giá các quy tắc theo thứ tự ưu tiên, trả về khớp đầu tiên
        foreach (var rule in rules)
        {
            if (rule.Evaluate(userMessage))
            {
                _logger.LogInformation(
                    "EN: Message matched rule '{RuleName}' (Priority: {Priority}). VI: Tin nhắn khớp quy tắc '{RuleName}' (Ưu tiên: {Priority})",
                    rule.Name, rule.Priority);
                return rule;
            }
        }

        _logger.LogDebug(
            "EN: No matching rule found for message. VI: Không tìm thấy quy tắc khớp cho tin nhắn");
        return null;
    }

    /// <summary>
    /// EN: Get response text for matched rule.
    /// VI: Lấy văn bản phản hồi cho quy tắc khớp.
    /// </summary>
    public string? GetResponseText(ChatbotRule rule)
    {
        return rule.Action.ActionType switch
        {
            Domain.Enums.ActionType.SendText => rule.Action.ResponseText,
            Domain.Enums.ActionType.SendTemplate => null, // Template requires separate handling
            Domain.Enums.ActionType.ForwardToHuman => null, // No auto-response
            _ => null
        };
    }
}
