using System.Data.Common; using GB5Shared.DTO.Framework.Login; using GB5Shared.QueryExecutor; using GB5Shared.ResponseStandard; using IDMSDAL.DTOs; using IDMSDAL.Interfaces; using IDMSDAL.QueryBuilders; namespace IDMSDAL.Implementations; public class EngagementDAL : IEngagementDAL { private readonly IQueryExecutor _QueryExecutor; public EngagementDAL(IQueryExecutor queryExecutor) { _QueryExecutor = queryExecutor; } // ── Reads ───────────────────────────────────────────────────────────────── public async Task GetEngagementAsync( int engagementId, LoginDTO login, CancellationToken ct) { return await _QueryExecutor.QuerySingleAsync( login, EngagementQB.GET_BY_ID, new { EngagementId = engagementId }).ConfigureAwait(false); } public async Task> GetEngagementModulesAsync( int engagementId, LoginDTO login, CancellationToken ct) { return await _QueryExecutor.QueryAsync( login, EngagementQB.GET_MODULES, new { EngagementId = engagementId }, cancellationToken: ct).ConfigureAwait(false) ?? Enumerable.Empty(); } public async Task GetEngagementDashboardAsync( int engagementId, LoginDTO login, CancellationToken ct) { return await _QueryExecutor.QuerySingleAsync( login, EngagementQB.GET_DASHBOARD, new { EngagementId = engagementId }).ConfigureAwait(false); } // ── Writes ──────────────────────────────────────────────────────────────── public async Task> SaveEngagementAsync( EngagementDTO dto, LoginDTO login, DbTransaction tx, CancellationToken ct) { try { dto.EngagementCreatedById = login.UserId; dto.EngagementCreatedOn = DateTime.UtcNow; dto.EngagementModifiedById = login.UserId; dto.EngagementModifiedOn = DateTime.UtcNow; int rows = await _QueryExecutor.ExecuteAsync( login, EngagementQB.INSERT, dto, tx, cancellationToken: ct).ConfigureAwait(false); return rows > 0 ? Result.Success("Engagement saved.") : Result.Failure("Failed to save engagement."); } catch (Exception) { throw; } } public async Task> UpdateEngagementAsync( EngagementDTO dto, LoginDTO login, DbTransaction tx, CancellationToken ct) { try { dto.EngagementModifiedById = login.UserId; dto.EngagementModifiedOn = DateTime.UtcNow; int rows = await _QueryExecutor.ExecuteAsync( login, EngagementQB.UPDATE, dto, tx, cancellationToken: ct).ConfigureAwait(false); return rows > 0 ? Result.Success("Engagement updated.") : Result.Failure("Engagement not found or not updated."); } catch (Exception) { throw; } } public async Task> ActivateEngagementAsync( int engagementId, string activeDomainsJson, LoginDTO login, DbTransaction tx, CancellationToken ct) { try { var param = new { EngagementId = engagementId, ActiveDomains = activeDomainsJson, EngagementModifiedById = login.UserId, EngagementModifiedOn = DateTime.UtcNow }; int rows = await _QueryExecutor.ExecuteAsync( login, EngagementQB.ACTIVATE, param, tx, cancellationToken: ct).ConfigureAwait(false); return rows > 0 ? Result.Success("Engagement activated.") : Result.Failure("Engagement not found or already active."); } catch (Exception) { throw; } } public async Task> DeclareGoLiveAsync( int engagementId, DateTime goLiveOn, LoginDTO login, DbTransaction tx, CancellationToken ct) { try { var param = new { EngagementId = engagementId, GoLiveOn = goLiveOn, EngagementModifiedById = login.UserId, EngagementModifiedOn = DateTime.UtcNow }; int rows = await _QueryExecutor.ExecuteAsync( login, EngagementQB.DECLARE_GOLIVE, param, tx, cancellationToken: ct).ConfigureAwait(false); return rows > 0 ? Result.Success("Go-live declared.") : Result.Failure("Engagement not found."); } catch (Exception) { throw; } } public async Task> UpdateHealthStatusAsync( int engagementId, string healthStatus, int signalScore, LoginDTO login, DbTransaction tx, CancellationToken ct) { try { var param = new { EngagementId = engagementId, HealthStatus = healthStatus, UpgradeSignalScore = signalScore, EngagementModifiedById = login.UserId, EngagementModifiedOn = DateTime.UtcNow }; int rows = await _QueryExecutor.ExecuteAsync( login, EngagementQB.UPDATE_HEALTH, param, tx, cancellationToken: ct).ConfigureAwait(false); return rows > 0 ? Result.Success("Health updated.") : Result.Failure("Engagement not found."); } catch (Exception) { throw; } } // ── Module management ───────────────────────────────────────────────────── public async Task> SaveEngagementModuleAsync( EngagementModuleDTO dto, LoginDTO login, DbTransaction tx, CancellationToken ct) { try { int rows = await _QueryExecutor.ExecuteAsync( login, EngagementQB.INSERT_MODULE, dto, tx, cancellationToken: ct).ConfigureAwait(false); return rows > 0 ? Result.Success("Module saved.") : Result.Failure("Failed to save module."); } catch (Exception) { throw; } } public async Task> DeleteEngagementModulesAsync( int engagementId, LoginDTO login, DbTransaction tx, CancellationToken ct) { try { int rows = await _QueryExecutor.ExecuteAsync( login, EngagementQB.DELETE_MODULES, new { EngagementId = engagementId }, tx, cancellationToken: ct).ConfigureAwait(false); return rows > 0 ? Result.Success("Modules deleted.") : Result.Failure("No modules found."); } catch (Exception) { throw; } } public async Task> UpdateModuleSeedingStatusAsync( int engagementModuleId, byte status, DateTime? seededOn, LoginDTO login, CancellationToken ct) { try { var param = new { EngagementModuleId = engagementModuleId, SeedingStatus = status, SeededOn = seededOn }; int rows = await _QueryExecutor.ExecuteAsync( login, EngagementQB.UPDATE_MODULE_SEEDING, param, cancellationToken: ct).ConfigureAwait(false); return rows > 0 ? Result.Success("Seeding status updated.") : Result.Failure("Module not found."); } catch (Exception) { throw; } } }