using FrameworkBLL.EIPConversation.EIPHandlers.EIPConversationEngine;
using FrameworkDAL.DTO.EIPConversation;
using GB5Shared.DTO.Framework.Login;
using Microsoft.Extensions.Logging;
namespace FrameworkBLL.EIPConversation.EIPHandlers.EIPConversationBLL
{
///
/// Main Orchestrator for EIP Conversation.
/// Controls Phase 1 execution and forwards
/// processing to Conversation Engine.
///
public class EIPConversationBLL : IEIPConversationBLL
{
private readonly IEIPConversationEngine _conversationEngine;
private readonly ILogger _logger;
public EIPConversationBLL(
IEIPConversationEngine conversationEngine,
ILogger logger)
{
_conversationEngine = conversationEngine
?? throw new ArgumentNullException(nameof(conversationEngine));
_logger = logger
?? throw new ArgumentNullException(nameof(logger));
}
///
/// Handles external channel incoming message.
/// Executes Phase 1 and forwards to full engine (Phase 2–6).
///
public async Task HandleIncomingConversationAsync(
EIPConversationDTO payload,
LoginDTO loginDTO,
CancellationToken cancellationToken)
{
if (payload == null)
throw new ArgumentNullException(nameof(payload));
if (loginDTO == null)
throw new ArgumentNullException(nameof(loginDTO));
try
{
_logger.LogInformation(
"PHASE1 START | Tenant={Tenant} | Channel={Channel} | User={User}",
payload.TenantId,
payload.ChannelType,
payload.UserIdentifier);
var result = await _conversationEngine
.ProcessIncomingMessageAsync(payload, loginDTO, cancellationToken);
if (result == null)
throw new InvalidOperationException(
"Conversation engine returned null result.");
_logger.LogInformation(
"PHASE1 COMPLETE | Tenant={Tenant} | FinalStep={Step}",
payload.TenantId,
result.CurrentStepCode);
return result;
}
catch (Exception ex)
{
_logger.LogError(ex,
"PHASE1 ERROR | Tenant={Tenant} | User={User}",
payload.TenantId,
payload.UserIdentifier);
throw; // Never swallow exceptions in BLL
}
}
///
/// Handles system-triggered conversation execution.
/// Used for manual or scheduled conversation processing.
///
public async Task HandleManualConversationRequestAsync(
int conversationId,
LoginDTO loginDTO,
CancellationToken cancellationToken)
{
if (conversationId <= 0)
throw new ArgumentException(
"Invalid conversationId", nameof(conversationId));
if (loginDTO == null)
throw new ArgumentNullException(nameof(loginDTO));
try
{
_logger.LogInformation(
"MANUAL EXECUTION START | ConversationId={Id}",
conversationId);
var result = await _conversationEngine
.ProcessManualRequestAsync(conversationId, loginDTO, cancellationToken);
if (result == null)
throw new InvalidOperationException(
"Conversation engine returned null result.");
_logger.LogInformation(
"MANUAL EXECUTION COMPLETE | ConversationId={Id} | FinalStep={Step}",
conversationId,
result.CurrentStepCode);
return result;
}
catch (Exception ex)
{
_logger.LogError(ex,
"MANUAL EXECUTION ERROR | ConversationId={Id}",
conversationId);
throw;
}
}
}
}