<?php
/**
 * Integration Registry Class
 *
 * @package FleekDash
 * @subpackage Integrations\Core
 */

namespace FleekDash\Integrations\Core;

use FleekDash\Traits\Base;

defined('ABSPATH') || exit;

/**
 * Integration Registry class
 *
 * Manages the registration and retrieval of integrations
 */
class IntegrationRegistry
{

    use Base;

    /**
     * Registered integrations
     *
     * @var array
     */
    private $integrations = [];

    /**
     * Constructor
     */
    protected function __construct()
    {
        // Initialize empty integrations array by category
        $this->integrations = [
            'plugin' => [],
            'theme' => [],
            'api' => [],
        ];
    }

    /**
     * Register an integration
     *
     * @param AbstractIntegration $integration Integration instance
     * @return bool
     */
    public function register(AbstractIntegration $integration)
    {
        $id = $integration->getData()['id'];
        $category = $integration->getData()['category'];

        // Validate category
        if (!isset($this->integrations[$category])) {
            $this->integrations[$category] = [];
        }

        // Check if already registered
        if (isset($this->integrations[$category][$id])) {
            return false;
        }

        // Register the integration
        $this->integrations[$category][$id] = $integration;

        return true;
    }

    /**
     * Get all registered integrations
     *
     * @return array
     */
    public function getAll(): array
    {
        // Always return all integrations
        return $this->integrations;
    }

    /**
     * Get integrations by category
     *
     * @param string $category Category name
     * @return array
     */
    public function getByCategory(string $category): array
    {
        return isset($this->integrations[$category]) ? $this->integrations[$category] : [];
    }

    /**
     * Get a specific integration
     *
     * @param string $id Integration ID
     * @param string $category Integration category
     * @return AbstractIntegration|null
     */
    public function get(string $id, ?string $category = null): ?AbstractIntegration
    {
        // If category is provided, look in that category
        if ($category && isset($this->integrations[$category][$id])) {
            return $this->integrations[$category][$id];
        }

        // Otherwise, search in all categories
        foreach ($this->integrations as $integrations) {
            if (isset($integrations[$id])) {
                return $integrations[$id];
            }
        }

        return null;
    }

    /**
     * Check if an integration is registered
     *
     * @param string $id Integration ID
     * @param string $category Integration category
     * @return bool
     */
    public function has(string $id, ?string $category = null): bool
    {
        return $this->get($id, $category) !== null;
    }

    /**
     * Get all available integrations
     *
     * @return array
     */
    public function getAvailable(): array
    {
        $available = [];

        foreach ($this->integrations as $category => $integrations) {
            $available[$category] = [];

            foreach ($integrations as $id => $integration) {
                if ($integration->isAvailable()) {
                    $available[$category][$id] = $integration;
                }
            }
        }

        return $available;
    }

    /**
     * Get all active integrations
     *
     * @return array
     */
    public function getActive(): array
    {
        $active = [];

        foreach ($this->integrations as $category => $integrations) {
            $active[$category] = [];

            foreach ($integrations as $id => $integration) {
                if ($integration->isActive()) {
                    $active[$category][$id] = $integration;
                }
            }
        }

        return $active;
    }
}
