<?php

declare(strict_types=1);

function cache_store_path(string $key): string
{
    return runtime_path('cache/data/' . sha1($key) . '.json');
}

function cache_get(string $key): mixed
{
    if (function_exists('apcu_fetch') && ini_get('apc.enabled')) {
        $success = false;
        $value = apcu_fetch($key, $success);
        if ($success) {
            return $value;
        }
    }

    $path = cache_store_path($key);
    if (!is_file($path)) {
        return null;
    }

    $json = file_get_contents($path);
    if ($json === false || $json === '') {
        return null;
    }

    $payload = json_decode($json, true);
    if (!is_array($payload)) {
        return null;
    }

    $expiresAt = (int) ($payload['expires_at'] ?? 0);
    if ($expiresAt <= time()) {
        @unlink($path);
        return null;
    }

    return $payload['data'] ?? null;
}

function cache_put(string $key, mixed $value, int $ttlSeconds): void
{
    $ttlSeconds = max(1, $ttlSeconds);

    if (function_exists('apcu_store') && ini_get('apc.enabled')) {
        apcu_store($key, $value, $ttlSeconds);
    }

    $payload = [
        'expires_at' => time() + $ttlSeconds,
        'data' => $value,
    ];

    $path = cache_store_path($key);
    file_put_contents($path, json_encode($payload, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES), LOCK_EX);
}

function cache_remember(string $key, int $ttlSeconds, callable $resolver): mixed
{
    $cached = cache_get($key);
    if ($cached !== null) {
        return $cached;
    }

    $value = $resolver();
    cache_put($key, $value, $ttlSeconds);

    return $value;
}

function cache_clear_all_data(): void
{
    if (function_exists('apcu_clear_cache') && ini_get('apc.enabled')) {
        @apcu_clear_cache();
    }

    $files = glob(runtime_path('cache/data/*.json'));
    if (!is_array($files)) {
        return;
    }

    foreach ($files as $file) {
        if (is_string($file) && is_file($file)) {
            @unlink($file);
        }
    }
}
