<?php

declare(strict_types=1);

namespace Flowaxy\Bootstrap;

use Flowaxy\Core\System\PathResolver;
use Flowaxy\Infrastructure\Cache\Cache as CacheInstance;
use Flowaxy\Support\Facades\Facade;
use Flowaxy\Support\Facades\Log;

use function class_exists;
use function file_exists;
use function function_exists;
use function is_readable;
use function interface_exists;
use function defined;

use const DIRECTORY_SEPARATOR;

// Ініціалізатор кешу та глобальних функцій cache() і cache_remember()
final class CacheInitializer
{
    // Ініціалізація кешу та визначення глобальних функцій
    public static function initialize(): void
    {
        if (function_exists('cache')) {
            return;
        }

        if (!class_exists(PathResolver::class)) {
            return;
        }

        $flowaxyDir = PathResolver::flowaxy();
        $ds = defined('DS') ? DS : DIRECTORY_SEPARATOR;

        // Спочатку завантажуємо інтерфейс, якщо він ще не завантажений
        $cacheInterfaceFile = $flowaxyDir . $ds . 'Contracts' . $ds . 'Cache' . $ds . 'CacheInterface.php';
        if (file_exists($cacheInterfaceFile) && is_readable($cacheInterfaceFile) && !interface_exists('Flowaxy\Contracts\Cache\CacheInterface')) {
            require_once $cacheInterfaceFile;
        }

        $cacheFile = $flowaxyDir . $ds . 'Infrastructure' . $ds . 'Cache' . $ds . 'Cache.php';

        if (file_exists($cacheFile) && is_readable($cacheFile)) {
            require_once $cacheFile;

            // Завантажуємо Facade перед використанням Log
            $facadeFile = $flowaxyDir . $ds . 'Support' . $ds . 'Facades' . $ds . 'Facade.php';
            if (file_exists($facadeFile) && is_readable($facadeFile) && !class_exists(Facade::class)) {
                require_once $facadeFile;
            }

            // Визначаємо глобальні функції cache() та cache_remember()
            $GLOBALS['_FLOWAXY_CACHE_CLASS'] = CacheInstance::class;

            if (!function_exists('cache')) {
                // Глобальна функція для отримання значення з кешу
                function cache(string $key, mixed $default = null): mixed
                {
                    $cache = $GLOBALS['_FLOWAXY_CACHE_CLASS']::getInstance();
                    return $cache->get($key, $default);
                }
            }

            if (!function_exists('cache_remember')) {
                // Глобальна функція для отримання або збереження значення з callback
                function cache_remember(string $key, callable $callback, ?int $ttl = null): mixed
                {
                    $cache = $GLOBALS['_FLOWAXY_CACHE_CLASS']::getInstance();
                    return $cache->remember($key, $callback, $ttl);
                }
            }
        } else {
            try {
                Log::Warning('Cache.php not found at: ' . $cacheFile);
            } catch (\Throwable) {
                // Ігноруємо помилки логування
            }
        }
    }
}
