using FrameworkDAL.CustomCode.EIPConversation.EIPChannelEndpointAdmin; using FrameworkDAL.DTO.EIPConversation; using GB5Shared.DTO.Framework.Login; using GB5Shared.Resource.Response; using Microsoft.Extensions.Logging; using System; using System.Collections.Generic; using System.Threading; using System.Threading.Tasks; namespace FrameworkBLL.EIPConversation.EIPAdmin.EIPChannelEndpointAdmin { public class EIPChannelEndpointAdminBLL : IEIPChannelEndpointAdminBLL { private readonly IEIPChannelEndpointAdminDAL _dal; private readonly ILogger _logger; public EIPChannelEndpointAdminBLL(IEIPChannelEndpointAdminDAL dal, ILogger logger) { _dal = dal ?? throw new ArgumentNullException(nameof(dal)); _logger = logger ?? throw new ArgumentNullException(nameof(logger)); } public async Task> GetEndpointListAsync( byte? channelType, LoginDTO login, CancellationToken ct = default) { try { _logger.LogInformation("BLL | GetEndpointList | Tenant={TenantId} | ChannelType={ChannelType}", login.ClientId, channelType); return await _dal.GetEndpointListAsync(channelType, login, ct).ConfigureAwait(false); } catch (Exception ex) { _logger.LogError(ex, "BLL | GetEndpointList | Error | Tenant={TenantId}", login.ClientId); throw; } } public async Task GetEndpointAsync( int endpointId, LoginDTO login, CancellationToken ct = default) { try { _logger.LogInformation("BLL | GetEndpoint | Tenant={TenantId} | Id={Id}", login.ClientId, endpointId); return await _dal.GetEndpointAsync(endpointId, login, ct).ConfigureAwait(false); } catch (Exception ex) { _logger.LogError(ex, "BLL | GetEndpoint | Error | Id={Id}", endpointId); throw; } } public async Task SaveEndpointAsync( EIPChannelEndpointAdminDTO dto, LoginDTO login, CancellationToken ct = default) { try { _logger.LogInformation( "BLL | SaveEndpoint | Validate | Tenant={TenantId} | ChannelType={ChannelType}", login.ClientId, dto.ChannelType); if (dto.ChannelType > 8) throw new ArgumentException("ChannelType must be one of: 0=Postman, 1=WhatsApp, 2=Teams, 3=Telegram, 4=Slack, 5=SMS, 6=AppChat, 7=Voice, 8=DirectActionWeb."); if (dto.EndpointPurpose < 1 || dto.EndpointPurpose > 3) throw new ArgumentException("EndpointPurpose must be one of: 1=Customer, 2=Service, 3=Internal."); dto.TenantId = login.ClientId; // No DB-enforced uniqueness on (TenantId, ChannelType, PhoneNumber) — this is a // BLL-level business rule to avoid two active endpoints answering the same number. if (!string.IsNullOrWhiteSpace(dto.PhoneNumber)) { bool phoneExists = await _dal.EndpointPhoneExistsAsync( dto.ChannelType, dto.PhoneNumber, dto.EndpointId, login, ct).ConfigureAwait(false); if (phoneExists) throw new InvalidOperationException( $"An active endpoint already exists for channel {dto.ChannelType} and phone number '{dto.PhoneNumber}'."); } var isNew = dto.EndpointId == 0; _logger.LogInformation( "BLL | SaveEndpoint | Persist | Tenant={TenantId} | ChannelType={ChannelType} | IsNew={IsNew}", login.ClientId, dto.ChannelType, isNew); if (isNew) { var newId = await _dal.InsertEndpointAsync(dto, login, ct).ConfigureAwait(false); _logger.LogInformation("BLL | SaveEndpoint | Inserted | NewId={NewId}", newId); return $"{SuccessResponse.SaveSuccessMessage} {newId}"; } else { await _dal.UpdateEndpointAsync(dto, login, ct).ConfigureAwait(false); _logger.LogInformation("BLL | SaveEndpoint | Updated | Id={Id}", dto.EndpointId); return SuccessResponse.UpdateSuccess; } } catch (Exception ex) { _logger.LogError(ex, "BLL | SaveEndpoint | Error | Tenant={TenantId} | ChannelType={ChannelType}", login.ClientId, dto.ChannelType); throw; } } public async Task DeleteEndpointAsync( int endpointId, LoginDTO login, CancellationToken ct = default) { try { _logger.LogInformation("BLL | DeleteEndpoint | Tenant={TenantId} | Id={Id}", login.ClientId, endpointId); if (endpointId == 0) throw new ArgumentException("EndpointId must reference a valid record."); await _dal.DeleteEndpointAsync(endpointId, login, ct).ConfigureAwait(false); _logger.LogInformation("BLL | DeleteEndpoint | Completed | Id={Id}", endpointId); return SuccessResponse.DeleteSuccessMessage; } catch (Exception ex) { _logger.LogError(ex, "BLL | DeleteEndpoint | Error | Id={Id}", endpointId); throw; } } } }