using MediatR;
using FacebookService.API.Application.Dtos;
using FacebookService.Domain.AggregatesModel.ChatbotAggregate;

namespace FacebookService.API.Application.Queries;

/// <summary>
/// EN: Handler for GetChatbotFlowByIdQuery.
/// VI: Handler cho GetChatbotFlowByIdQuery.
/// </summary>
public class GetChatbotFlowByIdQueryHandler : IRequestHandler<GetChatbotFlowByIdQuery, ChatbotFlowDto?>
{
    private readonly IChatbotFlowRepository _flowRepository;

    public GetChatbotFlowByIdQueryHandler(IChatbotFlowRepository flowRepository)
    {
        _flowRepository = flowRepository ?? throw new ArgumentNullException(nameof(flowRepository));
    }

    public async Task<ChatbotFlowDto?> Handle(
        GetChatbotFlowByIdQuery request,
        CancellationToken cancellationToken)
    {
        var flow = await _flowRepository.GetByIdWithNodesAsync(request.FlowId, cancellationToken);

        if (flow is null)
        {
            return null;
        }

        return MapToDto(flow);
    }

    private static ChatbotFlowDto MapToDto(ChatbotFlow flow)
    {
        var nodes = flow.Nodes.OrderBy(n => n.OrderIndex).Select(MapNodeToDto).ToList();

        return new ChatbotFlowDto(
            flow.Id,
            flow.ShopId,
            flow.Name,
            flow.TriggerType.Name,
            flow.TriggerValue,
            flow.IsActive,
            flow.CreatedAt,
            flow.UpdatedAt,
            nodes
        );
    }

    private static FlowNodeDto MapNodeToDto(FlowNode node)
    {
        return new FlowNodeDto(
            node.Id,
            node.NodeType.Name,
            node.Content,
            node.OrderIndex,
            node.NextNodeIds,
            node.Config
        );
    }
}

/// <summary>
/// EN: Handler for GetChatbotFlowsQuery.
/// VI: Handler cho GetChatbotFlowsQuery.
/// </summary>
public class GetChatbotFlowsQueryHandler : IRequestHandler<GetChatbotFlowsQuery, IReadOnlyList<ChatbotFlowSummaryDto>>
{
    private readonly IChatbotFlowRepository _flowRepository;

    public GetChatbotFlowsQueryHandler(IChatbotFlowRepository flowRepository)
    {
        _flowRepository = flowRepository ?? throw new ArgumentNullException(nameof(flowRepository));
    }

    public async Task<IReadOnlyList<ChatbotFlowSummaryDto>> Handle(
        GetChatbotFlowsQuery request,
        CancellationToken cancellationToken)
    {
        var flows = await _flowRepository.GetByShopIdAsync(request.ShopId, cancellationToken);

        if (request.ActiveOnly)
        {
            flows = flows.Where(f => f.IsActive).ToList();
        }

        return flows.Select(f => new ChatbotFlowSummaryDto(
            f.Id,
            f.Name,
            f.TriggerType.Name,
            f.TriggerValue,
            f.IsActive,
            f.CreatedAt
        )).ToList();
    }
}
