```
declare(strict_types=1);

namespace app\widgets;

use Yii;
/**
* @see app\vender\yiisoft\yii2-bootstrap5\src\ActiveForm.php
* @see app\vender\yiisoft\yii2-bootstrap5\src\Html.php
*
* Bootstrap5\ActiveForm.php is a extention of BaseHtml:
*
*	use yii\widgets\ActiveForm;
* 	use yii\bootstrap5\ActiveForm;
*
* Bootstrap5\Html.php is a extention of BaseHtml:
*
*	
* 	use yii\helpers\Html;
*/
use yii\bootstrap5\Widget;
use yii\bootstrap5\Alert as bootstrapAlert;
use yii\web\View;

use app\components\traits\CacheJsCssTrait;
use app\helpers\ParamHelper;
use app\helpers\TimeHelper;

/**
* Alert widget renders a message from session flash. All flash messages are displayed
* in the sequence they were assigned using setFlash. You can set message as following:
*
*	\Yii::$app->session->setFlash('error', 'This is the message');
*	\Yii::$app->session->setFlash('success', 'This is the message');
*	\Yii::$app->session->setFlash('info', 'This is the message');
*
* Multiple messages could be set as follows:
*
*	\Yii::$app->session->setFlash('error', ['Error 1', 'Error 2']);
*
* @author Kartik Visweswaran <<PRESIDIO_ANONYMIZED_EMAIL_ADDRESS>>
* @author Alexander Makarov <<PRESIDIO_ANONYMIZED_EMAIL_ADDRESS>>
*/
class Alert extends Widget
{
	// Note: Every protected variable below CacheJsCssTrait is used by the trait
	use CacheJsCssTrait;
	
	protected bool $_cacheDebugMode = false;
	protected bool $_compressJsCss = false;
	protected bool $_cacheEnable = false;
	protected int $_cacheJsCssTime = 3600;// +1 hour
	protected string $_cacheKeyPrefix = 'alertWidgetDelay_jqury_';
	
	public function init(): void
	{
		/**
		* Call to parent constructor
		*
		* Always call the parent init method first to ensure any
		* initialization logic defined in the base class is executed first.
		*/
		parent::init();
	
		// Get cacheDuration from Param and set with TimeHelper
		$cacheDuration = ParamHelper::get('widgets.cacheDuration');
		$this->_cacheJsCssTime = TimeHelper::convertDurationToSeconds($cacheDuration);
		
		// Cache & Compression
		$this->_cacheEnable = ParamHelper::get('widgets.cacheEnable');
		$this->_compressJsCss = ParamHelper::get('widgets.compressJsCss');
	}
		
	/**
	* @var array the alert types configuration for the flash messages.
	*
	* This array is setup as $key => $value, where:
	*	Key: the name of the session flash variable
	*	Value: the bootstrap alert type (i.e. danger, success, info, warning)
	*/
	public array $alertTypes = [
		'error' => 'alert-danger',
		'danger' => 'alert-danger',
		'success' => 'alert-success',
		'info' => 'alert-info',
		'warning' => 'alert-warning'
	];
	
	/**
	* @var array the options for rendering the close button tag.
	* Array will be passed to [[\yii\bootstrap\Alert::closeButton]].
	*/
	public $closeButton = [];
	
	/**
	* @url https://www.yiiframework.com/doc/api/2.0/yii-base-widget#run()-detail
	*/
	public function run()
	{
		$session = \Yii::$app->session;
		$appendClass = isset($this->options['class']) ? ' ' . $this->options['class'] : '';
		//$needRegisterJs = false;// flag to decide if JS needed
		
		foreach (array_keys($this->alertTypes) as $type)
		{
			$flash = $session->getFlash($type);
			
			foreach ((array) $flash as $info => $message)
			{
				if (is_array($message))
				{
					$body = $message['body'] ?? '';
					$delay = (int) ($message['delay'] ?? 0);
				}
				else
				{
					$body = $message;
					$delay = 0;
				}
				
				//if ($delay > 0)
				//{
				//	$needRegisterJs = true;
				//}
				
				echo bootstrapAlert::widget([
					'body' => $body,
					'closeButton' => $this->closeButton,
					'options' => array_merge($this->options, [
						'id' => $this->getId() . '-' . $type . '-' . $info,
						'class' => $this->alertTypes[$type] . $appendClass . ' square auto-dismiss',
						'data-delay' => $delay,
					]),
				]);
			}
			
			$session->removeFlash($type);
		}
		
		//if ($needRegisterJs)
		//{
			$this->registerJS();
		//}
	}
	
	/**
	* RenderJs
	* Javascript code to add fadeout from Alerts
	*/
	protected function registerJS()
	{
		$uniqueId = uniqid('', false);// Create 13-char unique string based on time
		$cacheKey = $this->_cacheKeyPrefix . $uniqueId . '_js_block_';
		
		$jsBlock = $this->getCachedJsBlock($cacheKey, function ()// use ()
		{
			return <<<JS
			(function(\$)
			{
				\$(function()
				{
					\$('.auto-dismiss').each(function()
					{
						var alert = $(this);
						var delay = parseInt(alert.data('delay')) || 0;
						
						if (delay > 0)
						{
							setTimeout(function()
							{
								alert.fadeTo(500, 0).slideUp(500, function()
								{
									$(this).remove();
								});
							},
							delay);
						}
					});
				});
			})(jQuery);
			JS;
		});
		
		$this->view->registerJs($jsBlock, View::POS_END);
	}
}
```

```
class AlertHelper
{
	/**
	* Sets flash message optionally with auto-dismiss delay.
	* @param string $type Flash key, e.g. 'success', 'error'
	* @param string $message The flash message content
	* @param int|null $delay Milliseconds before auto dismiss, or null/no dismiss if 0
	*
	* Example usage:
	* Normal flash (does NOT auto-dismiss)
	* 
	* 	AlertHelper::setDelay('success', 'Regular flash without auto-dismiss');
	*
	* Flash that auto-dismisses after 5 seconds
	*
	*	AlertHelper::setDelay('success', 'This will auto dismiss after 5 seconds', 5000);
	*/
	public static function setDelay(string $type, string $message, ?int $delay = null)
	{
		$session = \Yii::$app->session;
		
		// Keep normal flash as a string, no delay
		if ($delay === null || $delay <= 0)
		{
			$session->setFlash($type, $message);
		}
		// Wrap in array with delay
		else
		{
			$session->setFlash($type, ['body' => $message, 'delay' => $delay]);
		}
	}
}
```

and when I use it
```
AlertHelper::setDelay('error', \Yii::t('app', 'Your purchase list is empty.'), 5000);
```

the issue is when using it, two messages appear first one 'your purchase...' and another '5000'... also they never fade out...