<?php

/**
 * Хелпер для роботи з компонентами та шаблонами
 * Спрощує включення компонентів у шаблони
 *
 * @package Flowaxy\Support\Helpers
 * @version 1.0.0 Alpha prerelease
 */

declare(strict_types=1);

namespace Flowaxy\Support\Helpers;

use Flowaxy\Core\System\PathResolver;

use function extract;
use function file_exists;
use function ltrim;
use function ob_get_clean;
use function ob_start;
use function trigger_error;

use const DS;

final class ComponentHelper
{
    /**
     * Включити компонент
     *
     * @param string $componentName Ім'я компонента (без розширення .php) или путь относительно Components/
     * @param array $data Дані для передачі в компонент (будуть витягнуті як змінні)
     * @return void
     */
    public static function includeComponent(string $componentName, array $data = []): void
    {
        // Сначала пробуем новую структуру content/admin/components/
        // Поддерживаем как простое имя (button/button), так и полный путь
        $componentPath = PathResolver::contentAdmin() . DS . 'components' . DS . $componentName . '.php';

        if (!file_exists($componentPath)) {
            // Fallback на старую структуру admin/Interface/AdminUI/components/
            $componentPath = PathResolver::admin() . DS . 'Interface' . DS . 'AdminUI' . DS . 'components' . DS . $componentName . '.php';
        }

        if (!file_exists($componentPath)) {
            // Fallback для зворотної сумісності
            $componentPath = PathResolver::engine() . DS . 'interface' . DS . 'admin-ui' . DS . 'components' . DS . $componentName . '.php';
        }

        if (!file_exists($componentPath)) {
            trigger_error("Component not found: {$componentName}", E_USER_WARNING);

            return;
        }

        // Витягуємо змінні з даних
        extract($data);

        // Включаємо компонент
        include $componentPath;
    }

    /**
     * Отримати вміст компонента в рядок
     *
     * @param string $componentName Ім'я компонента
     * @param array $data Дані для передачі в компонент
     * @return string Вміст компонента
     */
    public static function getComponent(string $componentName, array $data = []): string
    {
        ob_start();
        self::includeComponent($componentName, $data);

        return ob_get_clean();
    }

    /**
     * Включити шаблон
     *
     * @param string $templateName Ім'я шаблону (без розширення .php)
     * @param array $data Дані для передачі в шаблон
     * @return void
     */
    public static function includeTemplate(string $templateName, array $data = []): void
    {
        // Сначала пробуем новую структуру content/admin/templates/
        $templatePath = PathResolver::contentAdmin() . DS . 'templates' . DS . $templateName . '.php';

        if (!file_exists($templatePath)) {
            // Fallback на старую структуру admin/Interface/AdminUI/templates/
            $templatePath = PathResolver::admin() . DS . 'Interface' . DS . 'AdminUI' . DS . 'templates' . DS . $templateName . '.php';
        }

        if (!file_exists($templatePath)) {
            // Fallback для зворотної сумісності
            $templatePath = PathResolver::engine() . DS . 'interface' . DS . 'admin-ui' . DS . 'templates' . DS . $templateName . '.php';
        }

        if (!file_exists($templatePath)) {
            trigger_error("Template not found: {$templateName}", E_USER_WARNING);

            return;
        }

        // Витягуємо змінні з даних
        extract($data);

        // Включаємо шаблон
        include $templatePath;
    }

    /**
     * Отримати вміст шаблону в рядок
     *
     * @param string $templateName Ім'я шаблону
     * @param array $data Дані для передачі в шаблон
     * @return string Вміст шаблону
     */
    public static function getTemplate(string $templateName, array $data = []): string
    {
        ob_start();
        self::includeTemplate($templateName, $data);

        return ob_get_clean();
    }

    /**
     * Отримати шлях до ассету
     *
     * @param string $assetPath Шлях до ассету (відносно content/admin/resources/)
     * @return string Повний URL до ассету
     */
    public static function asset(string $assetPath): string
    {
        return UrlHelper::base('content/admin/resources/' . ltrim($assetPath, '/'));
    }
}
