using HrynCo.NotificationService.DAL.Abstract.Providers; using HrynCo.NotificationService.DAL.Abstract.Repositories; using HrynCo.NotificationService.Services.EmailChannels.Create; using HrynCo.NotificationService.Services.EmailChannels.Delete; using HrynCo.NotificationService.Services.EmailChannels.Get; using HrynCo.NotificationService.Services.EmailChannels.GetUsageSummary; using HrynCo.NotificationService.Services.EmailChannels.Send; using HrynCo.NotificationService.Services.EmailChannels.Update; using HrynCo.NotificationService.Web.Controllers.Admin.ViewModels; using MediatR; using Microsoft.AspNetCore.Mvc; namespace HrynCo.NotificationService.Web.Controllers.Admin; [Route("admin/channels")] public class AdminChannelsController(IMediator mediator) : Controller { // GET /admin/channels [HttpGet("")] public async Task Index(CancellationToken ct) { var result = await mediator.Send(new GetChannelUsageSummaryQuery(), ct); if (!result.IsSuccess) { ModelState.AddModelError("", result.Error?.Message ?? "Failed to load channels."); return View(Array.Empty()); } return View(result.Result); } // GET /admin/channels/create [HttpGet("create")] public IActionResult Create() { return View("Edit", new EmailChannelEditViewModel()); } // GET /admin/channels/{id} [HttpGet("{id:guid}")] public async Task Edit(Guid id, CancellationToken ct) { var result = await mediator.Send(new GetEmailChannelQuery(id), ct); if (!result.IsSuccess || result.Result is null) return NotFound(); var channel = result.Result; var smtp = channel.Settings as SmtpChannelSettings ?? new SmtpChannelSettings { Host = "", Username = "", Password = "", FromEmail = "", FromName = "" }; var vm = new EmailChannelEditViewModel { Id = channel.Id, ServiceName = channel.ServiceName, Priority = channel.Priority, EmailChannelType = channel.EmailChannelType, DailyLimit = channel.DailyLimit, MonthlyLimit = channel.MonthlyLimit, WarnThresholdPercent = channel.WarnThresholdPercent, IsActive = channel.IsActive, Host = smtp.Host, Port = smtp.Port, Username = smtp.Username, Password = smtp.Password, UseSsl = smtp.UseSsl, FromEmail = smtp.FromEmail, FromName = smtp.FromName }; return View(vm); } // POST /admin/channels/save [HttpPost("save")] [ValidateAntiForgeryToken] public async Task Save(EmailChannelEditViewModel model, CancellationToken ct) { if (!ModelState.IsValid) return View("Edit", model); var smtpSettings = new SmtpChannelSettings { Host = model.Host, Port = model.Port, Username = model.Username, Password = model.Password, UseSsl = model.UseSsl, FromEmail = model.FromEmail, FromName = model.FromName }; if (model.IsNew) { var command = new CreateEmailChannelCommand( model.ServiceName, model.Priority, EmailChannelType.Smtp, smtpSettings, model.DailyLimit, model.MonthlyLimit, model.WarnThresholdPercent, model.IsActive); var result = await mediator.Send(command, ct); if (!result.IsSuccess) { ModelState.AddModelError("", result.Error?.Message ?? "Failed to create channel."); return View("Edit", model); } } else { var command = new UpdateEmailChannelCommand( model.Id, model.Priority, smtpSettings, model.DailyLimit, model.MonthlyLimit, model.WarnThresholdPercent, model.IsActive); var result = await mediator.Send(command, ct); if (!result.IsSuccess) { ModelState.AddModelError("", result.Error?.Message ?? "Failed to update channel."); return View("Edit", model); } } return RedirectToAction(nameof(Index)); } // POST /admin/channels/{id}/test [HttpPost("{id:guid}/test")] public async Task Test(Guid id, [FromBody] TestChannelRequest request, CancellationToken ct) { var channelResult = await mediator.Send(new GetEmailChannelQuery(id), ct); if (!channelResult.IsSuccess || channelResult.Result is null) return NotFound(new { success = false, message = "Channel not found." }); var channel = channelResult.Result; var subject = "✅ Test email from Notification Service"; var body = $"This is a test email sent from the Notification Service admin panel.\n\nChannel: {channel.ServiceName}"; var sendResult = await mediator.Send( new SendEmailCommand(id, request.ToEmail, request.ToEmail, subject, body, null), ct); if (!sendResult.IsSuccess) return Ok(new { success = false, message = sendResult.Error?.Message }); return Ok(new { success = true, message = $"Test email sent to {request.ToEmail}." }); } // POST /admin/channels/{id}/delete [HttpPost("{id:guid}/delete")] [ValidateAntiForgeryToken] public async Task Delete(Guid id, CancellationToken ct) { await mediator.Send(new DeleteEmailChannelCommand(id), ct); return RedirectToAction(nameof(Index)); } } public record TestChannelRequest(string ToEmail);