using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.ViewFeatures;
using PowderCoating.Core.Entities;
using PowderCoating.Core.Enums;
namespace PowderCoating.Web.Helpers
{
///
/// Extension methods on for storing toast
/// notification messages that survive a POST→redirect→GET cycle.
///
/// TempData is used (rather than ViewBag or ViewData) because toast messages
/// must survive an HTTP redirect: a controller sets the message before calling
/// RedirectToAction, and the layout reads and renders it on the next GET.
/// TempData is session-backed and automatically cleared after it is read.
///
///
/// The four well-known string keys (Success, Error, Warning,
/// Info) match the JavaScript toast-renderer in _Layout.cshtml;
/// changing them here requires a matching update in the layout script.
///
///
public static class ToastHelper
{
/// TempData key read by the layout to render a green success toast.
private const string SuccessKey = "Success";
/// TempData key read by the layout to render a red error toast.
private const string ErrorKey = "Error";
/// TempData key read by the layout to render a yellow warning toast.
private const string WarningKey = "Warning";
/// TempData key read by the layout to render a yellow warning toast that does not auto-dismiss.
private const string WarningPermanentKey = "WarningPermanent";
/// TempData key read by the layout to render a blue info toast.
private const string InfoKey = "Info";
///
/// Stores a success (green) toast message in TempData for display on the
/// next page render after a redirect.
///
/// The TempData dictionary for the current request.
/// The human-readable success message.
public static void Success(this ITempDataDictionary tempData, string message)
{
tempData[SuccessKey] = message;
}
///
/// Stores an error (red) toast message in TempData for display on the
/// next page render after a redirect.
///
/// The TempData dictionary for the current request.
/// The human-readable error message.
public static void Error(this ITempDataDictionary tempData, string message)
{
tempData[ErrorKey] = message;
}
///
/// Stores a warning (yellow) toast message in TempData for display on the
/// next page render after a redirect.
///
/// The TempData dictionary for the current request.
/// The human-readable warning message.
public static void Warning(this ITempDataDictionary tempData, string message)
{
tempData[WarningKey] = message;
}
///
/// Stores a warning (yellow) toast that requires manual dismissal (no auto-timeout).
/// Use for critical warnings the user must not miss, such as email delivery failures.
///
public static void WarningPermanent(this ITempDataDictionary tempData, string message)
{
tempData[WarningPermanentKey] = message;
}
///
/// Stores an informational (blue) toast message in TempData for display on
/// the next page render after a redirect.
///
/// The TempData dictionary for the current request.
/// The human-readable informational message.
public static void Info(this ITempDataDictionary tempData, string message)
{
tempData[InfoKey] = message;
}
}
///
/// Convenience extension methods on that delegate to
/// via the controller's own TempData.
///
/// These shorten controller code from TempData.Success("…") to the
/// more readable this.ToastSuccess("…"), which reads closer to
/// natural language and is consistent with other MVC helper conventions.
///
///
public static class ControllerToastExtensions
{
///
/// Stores a success (green) toast in the controller's TempData.
/// Convenience wrapper around .
///
/// The calling MVC controller.
/// The success message to display after redirect.
public static void ToastSuccess(this Controller controller, string message)
{
controller.TempData.Success(message);
}
///
/// Stores an error (red) toast in the controller's TempData.
/// Convenience wrapper around .
///
/// The calling MVC controller.
/// The error message to display after redirect.
public static void ToastError(this Controller controller, string message)
{
controller.TempData.Error(message);
}
///
/// Stores a warning (yellow) toast in the controller's TempData.
/// Convenience wrapper around .
///
/// The calling MVC controller.
/// The warning message to display after redirect.
public static void ToastWarning(this Controller controller, string message)
{
controller.TempData.Warning(message);
}
///
/// Stores a permanent warning (yellow, no auto-dismiss) in the controller's TempData.
/// Use for failures the user must not miss — email delivery errors, PDF generation failures.
///
public static void ToastWarningPermanent(this Controller controller, string message)
{
controller.TempData.WarningPermanent(message);
}
///
/// Stores an informational (blue) toast in the controller's TempData.
/// Convenience wrapper around .
///
/// The calling MVC controller.
/// The informational message to display after redirect.
public static void ToastInfo(this Controller controller, string message)
{
controller.TempData.Info(message);
}
///
/// Translates a outcome into the appropriate
/// toast severity and message.
///
/// Sent notifications use Info (not Success) because the notification is a
/// side effect of the main action — the main action already gets a Success
/// toast. Skipped and Failed outcomes are Warning (not Error) because the
/// primary operation succeeded even if the notification did not.
///
///
/// The calling MVC controller.
///
/// The most recent record, or null
/// if no notification was attempted (in which case this method is a no-op).
///
public static void SetNotificationResultToast(this Controller controller, NotificationLog? log)
{
if (log == null) return;
var channel = log.Channel == NotificationChannel.Sms ? "SMS" : "Email";
switch (log.Status)
{
case NotificationStatus.Sent:
controller.ToastInfo($"{channel} sent to {log.RecipientName} ({log.Recipient}).");
break;
case NotificationStatus.Skipped:
controller.ToastWarning(!string.IsNullOrEmpty(log.Message)
? $"{channel} skipped: {log.Message}"
: $"{channel} notification was skipped.");
break;
case NotificationStatus.Failed:
controller.ToastWarningPermanent(!string.IsNullOrEmpty(log.ErrorMessage)
? $"{channel} delivery failed: {log.ErrorMessage}"
: $"{channel} notification failed.");
break;
}
}
}
}