using Microsoft.EntityFrameworkCore; using PnvPanel.Application.Auth; using PnvPanel.Application.Common.Interfaces; using PnvPanel.Application.Common.Messaging; using PnvPanel.Application.Common.Models; using PnvPanel.Application.Support; using PnvPanel.Domain.Audit; using PnvPanel.Domain.Support; namespace PnvPanel.Application.Admin.Support; public sealed class RejectExtensionRequestCommandHandler( IAppDbContext dbContext, IRealtimeNotifier notifier, ITelegramNotifier telegramNotifier, ICurrentUser currentUser ) : ICommandHandler { public async Task Handle( RejectExtensionRequestCommand command, CancellationToken cancellationToken ) { if (currentUser.UserId is not { } adminId) return Result.Failure(AuthErrors.Unauthorized); var ticket = await dbContext.SupportTickets.FirstOrDefaultAsync( t => t.Id == command.TicketId, cancellationToken ); if (ticket is null) return Result.Failure(SupportErrors.NotFound); if (ticket.Type != TicketType.ExtensionRequest) return Result.Failure(SupportErrors.NotExtensionRequest); if (ticket.Status == TicketStatus.Closed) return Result.Failure(SupportErrors.AlreadyClosed); if (!string.IsNullOrWhiteSpace(command.Reason)) dbContext.TicketComments.Add(TicketComment.Create(ticket.Id, adminId, command.Reason)); ticket.Close(); dbContext.AuditLogs.Add( AuditLog.Create( adminId, "ExtensionRequestRejected", "SupportTicket", ticket.Id.ToString(), metadata: null, AuditSource.Web ) ); await notifier.NotifyTicketUpdatedAsync(ticket.Id, ticket.UserId, cancellationToken); await telegramNotifier.NotifyUserAsync( ticket.UserId, "❌ Ваша заявка на продление отклонена.", $"/support?ticket={ticket.Id}", cancellationToken ); return Result.Success(); } }