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; } } } }