using EnablementBLL.ShowRun; using EnablementDAL.CustomCode.ShowRun; using EnablementDAL.DTO; using GB5Shared.DTO.Framework.Login; using GB5Shared.DTO.Framework.ResponseStandard; using GB5Shared.EventLogPublish; using GB5Shared.GenerateAutoNumber; using Microsoft.Extensions.Logging; namespace EnablementBLL.Implementations; public class ShowRunBLL : IShowRunBLL { private readonly IShowRunDAL _dal; private readonly AutoNumber _autoNumber; private readonly EventLogPublish _eventLog; private readonly ILogger _logger; public ShowRunBLL( IShowRunDAL dal, AutoNumber autoNumber, EventLogPublish eventLog, ILogger logger) { _dal = dal; _autoNumber = autoNumber; _eventLog = eventLog; _logger = logger; } public async Task> CreateRunAsync(ShowRunDTO dto, LoginDTO login, CancellationToken ct) { if (dto.ShowId <= 0) throw new ArgumentException("ShowId must be greater than zero."); if (string.IsNullOrWhiteSpace(dto.RequestId)) throw new ArgumentException("RequestId must not be empty."); if (dto.StartedBy > 3) throw new ArgumentException("StartedBy must be in range 0-3."); var an = await _autoNumber.GetNumberAsync(1, "SHOWRUN", login).ConfigureAwait(false); int showRunId = an.StartNumber; dto.ShowRunId = showRunId; dto.UserId = login.UserId; dto.RunState = 0; // InProgress dto.StartedOn = DateTime.UtcNow; dto.CreatedById = login.UserId; dto.ModifiedById = login.UserId; dto.SourceType = login.SourceType; dto.TenantId = login.ClientId; await _dal.InsertShowRunAsync(dto, login, ct).ConfigureAwait(false); _logger.LogInformation( "ShowRun created ShowRunId={ShowRunId} ShowId={ShowId} UserId={UserId}", showRunId, dto.ShowId, login.UserId); _ = _eventLog.PublishEventLogAsync("ShowRun Created", dto, 1, showRunId, login, ct: ct); return new ResponseStandardDTO { Body = showRunId, Status = GB5Shared.DTO.Framework.Enum.FrameworkEnumDTO.ResponseStatus.Ok }; } public async Task> UpdateStepAsync(ShowRunStepDTO stepDto, LoginDTO login, CancellationToken ct) { if (stepDto.ShowRunId <= 0) throw new ArgumentException("ShowRunId must be greater than zero."); if (stepDto.ShowStepId <= 0) throw new ArgumentException("StepId must be greater than zero."); if (stepDto.StepState > 2) throw new ArgumentException("StepState must be in range 0-2."); if (stepDto.ActionTaken > 5) throw new ArgumentException("ActionTaken must be in range 0-5."); if (stepDto.TimeSpentOnMs < 0) throw new ArgumentException("TimeSpentMs must be >= 0."); bool isOwner = await _dal.ValidateOwnerAsync(stepDto.ShowRunId, login.UserId, login, ct).ConfigureAwait(false); if (!isOwner) throw new UnauthorizedAccessException("ShowRun does not belong to the current user."); await _dal.InsertShowRunStepAsync(stepDto, login, ct).ConfigureAwait(false); await _dal.UpdateCurrentStepAsync(stepDto.ShowRunId, stepDto.ShowStepId, login, ct).ConfigureAwait(false); return OkResponse("Step updated."); } public async Task> DismissAsync(int showRunId, LoginDTO login, CancellationToken ct) { bool isOwner = await _dal.ValidateOwnerAsync(showRunId, login.UserId, login, ct).ConfigureAwait(false); if (!isOwner) throw new UnauthorizedAccessException("ShowRun does not belong to the current user."); await _dal.UpdateRunStateAsync(showRunId, 2, login, ct).ConfigureAwait(false); // Dismissed _ = _eventLog.PublishEventLogAsync("ShowRun Dismissed", new { ShowRunId = showRunId }, 2, showRunId, login, ct: ct); return OkResponse("Show dismissed."); } public async Task> CompleteAsync(int showRunId, LoginDTO login, CancellationToken ct) { bool isOwner = await _dal.ValidateOwnerAsync(showRunId, login.UserId, login, ct).ConfigureAwait(false); if (!isOwner) throw new UnauthorizedAccessException("ShowRun does not belong to the current user."); await _dal.UpdateRunStateAsync(showRunId, 1, login, ct).ConfigureAwait(false); // Completed _ = _eventLog.PublishEventLogAsync("ShowRun Completed", new { ShowRunId = showRunId }, 3, showRunId, login, ct: ct); return OkResponse("Show completed."); } public async Task> GetHistoryAsync( int userId, int showId, int pageNo, int pageSize, LoginDTO login, CancellationToken ct) { if (pageNo < 1) throw new ArgumentException("PageNo must be >= 1."); if (pageSize < 1) throw new ArgumentException("PageSize must be >= 1."); var items = await _dal.GetHistoryAsync(userId, showId, pageNo, pageSize, login, ct).ConfigureAwait(false); int total = await _dal.GetHistoryCountAsync(userId, showId, login, ct).ConfigureAwait(false); return new ResponseStandardDTO { Body = new { Items = items, TotalCount = total }, Status = GB5Shared.DTO.Framework.Enum.FrameworkEnumDTO.ResponseStatus.Ok }; } private static ResponseStandardDTO OkResponse(string message) => new() { Body = message, Status = GB5Shared.DTO.Framework.Enum.FrameworkEnumDTO.ResponseStatus.Ok }; }