class RoleHelper
{
	public static function isGuest(): bool
	{
		$guest = \Yii::$app->user->isGuest ? true : false;
		
		return (bool) $guest;
	}
	
	public static function userIdentity(): IdentityInterface|null
	{
		if (self::isGuest())
		{
			return null;
		}
		
		$identity = \Yii::$app->user->identity;
		if ($identity instanceof IdentityInterface)
		{
			return $identity;
		}
		
		// Defensive fallback: If identity is not instance, treat as guest
		return null;
	}
	
	public static function isAdmin(): bool
	{
		if (self::isGuest())
		{
			return false;
		}
		
		$identity = self::userIdentity();
		if ($identity === null || empty($identity->email))
		{
			return false;
		}
		
		$userId = $identity->id;
		if (self::hasRole($userId) != 'appAdmin')
		{
			return false;
		}
		
		$ip = self::userIp();
		$email = $identity->email;
		
		// Use both role and IP/email match for admin
		return \Yii::$app->authManager->checkAccess(self::userId(), 'appAdmin') 
			&& RBAMHelper::isAdmin($email, $ip);
	}
	
	public static function hasRole($userId): string
	{
		$authManager = \Yii::$app->authManager;
		if ($authManager->checkAccess($userId, 'appAdmin'))
		{
			return \Yii::t('app', 'appAdmin');
		}
		elseif ($authManager->checkAccess($userId, 'appSupport'))
		{
			return  \Yii::t('app', 'appSupport');
		}
		elseif ($authManager->checkAccess($userId, 'userAssist'))
		{
			return  \Yii::t('app', 'userAssist');
		}
		else
		{
			return  \Yii::t('app', 'userOwner');
		}
	}
}


class RBAMHelper
{
	/**
	* Checks if an IP is in the list of allowed IPs, including support for CIDR notation.
	* @param string[] $allowedIps Array of allowed IP addresses or CIDR ranges.
	* @param string $ip IP address to check.
	* @return bool True if IP matches any allowed IP or subnet, false otherwise.
	*/
	protected static function ipInRangeArray(array $allowedIps, string $ip): bool
	{
		foreach ($allowedIps as $allowedIp)
		{
			if (self::ipMatches($ip, $allowedIp))
			{
				return true;
			}
		}
		
		return false;
	}
	
	/**
	* Determines whether a single IP matches an allowed IP or CIDR subnet.
	* @param string $ip IP address to check.
	* @param string $allowedIp IP address or subnet in CIDR notation.
	* @return bool True if $ip is within $allowedIp or equal to it.
	*/
	protected static function ipMatches(string $ip, string $allowedIp): bool
	{
		// If no CIDR mask given, treat as single IP
		if (strpos($allowedIp, '/') === false)
		{
			return filter_var($ip, FILTER_VALIDATE_IP) && $ip === $allowedIp;
		}
		
		// CIDR subnet check
		list($subnet, $mask) = explode('/', $allowedIp);
		
		// Invalid IP format
		if (!filter_var($ip, FILTER_VALIDATE_IP) || !filter_var($subnet, FILTER_VALIDATE_IP))
		{
			return false;
		}
		
		$ipLong = ip2long($ip);
		$subnetLong = ip2long($subnet);
		$maskLong = ~((1 << (32 - intval($mask))) - 1);
		
		return ($ipLong & $maskLong) === ($subnetLong & $maskLong);
	}
	
	/**
	* Checks if the given email belongs to an admin user and the IP is allowed.
	* @param string $email User email to check.
	* @param string|null $ip IP address of the user (optional but recommended).
	* @return bool True if user is an admin and IP is allowed.
	*/
	public static function isAdmin(string $email, ?string $ip = null): bool
	{
		$adminUsers = ParamHelper::get('app.user.admin', []);
		//$adminUsers = \Yii::$app->params['app.user.admin'] ?? [];
		
		// If email not configured as admin user, fail fast
		if (!isset($adminUsers[$email]))
		{
			return false;
		}
		
		// Require IP for strict checking; reject if missing
		if ($ip === null)
		{
			return false;
		}
		
		$allowedIps = $adminUsers[$email];
		
		// Return true if IP matches any allowed IP or subnet
		return self::ipInRangeArray($allowedIps, $ip);
	}
	
	/**
	* Checks if the given email belongs to a support user and the IP is allowed.
	* @param string $email User email to check.
	* @param string|null $ip IP address of the user (optional but recommended).
	* @return bool True if user is support and IP is allowed.
	*/
	public static function isSupport(string $email, ?string $ip = null): bool
	{
		$supportUsers = ParamHelper::get('app.user.support', []);
		//$supportUsers = \Yii::$app->params['app.user.support'] ?? [];
		
		if (!isset($supportUsers[$email]))
		{
			return false;
		}
		
		if ($ip === null)
		{
			return false;
		}
		
		$allowedIps = $supportUsers[$email];
		
		return self::ipInRangeArray($allowedIps, $ip);
	}
}

'app.user.admin' => [
	'admin1@example.com' => ['192.168.1.10', '203.0.113.50'],
	'admin2@example.com' => ['10.0.0.22'],
 ],

'app.user.support' => [
 	'support1@example.com' => ['198.51.100.1'],
 	'support2@example.com' => ['198.51.100.2', '198.51.100.3'],
 ],


does isAdmin() look correct?