<?php

declare(strict_types=1);

namespace Flowaxy\Support\Helpers;

use Flowaxy\Infrastructure\Cache\Cache;
use Flowaxy\Support\Helpers\ManagerHelper;
use Flowaxy\Support\Helpers\ClassLoaderHelper;
use Flowaxy\Support\Facades\Log;
use Throwable;

use function class_exists;

// Хелпер для роботи з кешем
// Централізовані методи для роботи з кешем
final class CacheHelper
{
    // Отримання екземпляра Cache через ManagerHelper
    private static function getCacheInstance(): ?Cache
    {
        ClassLoaderHelper::ensureLoaded(ManagerHelper::class);

        return class_exists(ManagerHelper::class) ? ManagerHelper::cache() : null;
    }

    // Отримання значення з кешу
    public static function get(string $key, mixed $default = null): mixed
    {
        $cache = self::getCacheInstance();
        return $cache?->get($key, $default) ?? $default;
    }

    // Встановлення значення в кеш
    public static function set(string $key, mixed $value, ?int $ttl = null): bool
    {
        $cache = self::getCacheInstance();
        return $cache?->set($key, $value, $ttl) ?? false;
    }

    // Видалення значення з кешу
    public static function forget(string $key): bool
    {
        $cache = self::getCacheInstance();
        return $cache?->delete($key) ?? false;
    }

    // Отримання або встановлення значення з callback
    public static function remember(string $key, callable $callback, ?int $ttl = null): mixed
    {
        $cache = self::getCacheInstance();
        if ($cache !== null) {
            return $cache->remember($key, $callback, $ttl);
        }

        try {
            return $callback();
        } catch (Throwable $e) {
            try {
                Log::Error("CacheHelper::remember callback error: {$e->getMessage()}", [
                    'key' => $key,
                    'exception' => $e,
                ]);
            } catch (Throwable) {
                // Ignore logging errors
            }
            throw $e;
        }
    }

    // Очищення кешу за паттерном
    public static function clear(?string $pattern = null): bool
    {
        $cache = self::getCacheInstance();
        if ($cache === null) {
            return false;
        }

        return match ($pattern) {
            null => $cache->clear(),
            default => false, // Паттерн очистки не реалізовано
        };
    }

    // Видалення кількох ключів одночасно
    public static function forgetMultiple(array $keys): int
    {
        $count = 0;
        foreach ($keys as $key) {
            if (self::forget($key)) {
                $count++;
            }
        }

        return $count;
    }

    // Перевірка наявності ключа в кеші
    public static function has(string $key): bool
    {
        $value = self::get($key);
        return $value !== null;
    }
}
