<?php

namespace Limb_Chatbot\Includes\Services\Notifications;

use Limb_Chatbot\Includes\Interfaces\Notification_Type_Interface;

/**
 * Registry of notification types (Single source of truth for type lookup).
 *
 * Types are registered in code; no database table for types. Allows role-based
 * and channel-based resolution without touching the DB.
 *
 * @package Limb_Chatbot\Includes\Services\Notifications
 * @since 1.0.15
 */
class Notification_Type_Registry {

	/**
	 * Registered notification types by key.
	 *
	 * @var array<string, Notification_Type_Interface>
	 * @since 1.0.15
	 */
	private array $types = [];

	/**
	 * Register a notification type.
	 *
	 * @param  Notification_Type_Interface  $type  Type instance.
	 *
	 * @return void
	 * @since 1.0.15
	 */
	public function register( Notification_Type_Interface $type ): void {
		$this->types[ $type->get_key() ] = $type;
	}

	/**
	 * Get a type by key.
	 *
	 * @param  string  $key  Type key.
	 *
	 * @return Notification_Type_Interface|null
	 * @since 1.0.15
	 */
	public function get( string $key ): ?Notification_Type_Interface {
		return $this->types[ $key ] ?? null;
	}

	/**
	 * Get all registered types.
	 *
	 * @return Notification_Type_Interface[]
	 * @since 1.0.15
	 */
	public function get_all(): array {
		return array_values( $this->types );
	}

	/**
	 * Get types that target the given role.
	 *
	 * @param  string  $role  Role slug: 'guest', 'user', 'agent', 'admin'.
	 *
	 * @return Notification_Type_Interface[]
	 * @since 1.0.15
	 */
	public function get_types_for_role( string $role ): array {
		$filtered = [];
		foreach ( $this->types as $type ) {
			if ( in_array( $role, $type->get_target_roles(), true ) ) {
				$filtered[] = $type;
			}
		}

		return $filtered;
	}

	/**
	 * Check if a type is registered.
	 *
	 * @param  string  $key  Type key.
	 *
	 * @return bool
	 * @since 1.0.15
	 */
	public function has( string $key ): bool {
		return isset( $this->types[ $key ] );
	}
}
