<?php
declare(strict_types=1);

namespace ROITheme\Shared\Infrastructure\Services;

use ROITheme\Shared\Domain\Contracts\CacheServiceInterface;

/**
 * WordPressCacheService - Cache con Transients API
 *
 * RESPONSABILIDAD: Gestionar cache de componentes
 *
 * IMPLEMENTACIÓN: WordPress Transients
 * - get_transient()
 * - set_transient()
 * - delete_transient()
 *
 * VENTAJAS:
 * - Compatible con object cache (Redis, Memcached)
 * - Expiración automática
 * - API simple
 *
 * @package ROITheme\Infrastructure\Services
 */
final class WordPressCacheService implements CacheServiceInterface
{
    private const PREFIX = 'roi_theme_';

    public function __construct(
        private \wpdb $wpdb
    ) {}

    /**
     * Obtener valor del cache
     *
     * @param string $key Clave del cache
     * @return mixed|null Valor o null si no existe/expiró
     */
    public function get(string $key): mixed
    {
        $transient = get_transient($this->getFullKey($key));

        // WordPress devuelve false si no existe
        return $transient === false ? null : $transient;
    }

    /**
     * Guardar valor en cache
     *
     * @param string $key Clave del cache
     * @param mixed $value Valor a guardar
     * @param int $expiration Tiempo de vida en segundos (default 1 hora)
     * @return bool True si guardó exitosamente
     */
    public function set(string $key, mixed $value, int $expiration = 3600): bool
    {
        return set_transient($this->getFullKey($key), $value, $expiration);
    }

    /**
     * Eliminar entrada de cache
     *
     * @param string $key Clave del cache
     * @return bool True si eliminó exitosamente
     */
    public function delete(string $key): bool
    {
        return $this->invalidate($key);
    }

    /**
     * Limpiar todo el cache
     *
     * @return bool
     */
    public function flush(): bool
    {
        return $this->invalidateAll();
    }

    /**
     * Invalidar (eliminar) entrada de cache
     *
     * @param string $key Clave del cache
     * @return bool True si eliminó exitosamente
     */
    public function invalidate(string $key): bool
    {
        return delete_transient($this->getFullKey($key));
    }

    /**
     * Invalidar todo el cache de componentes
     *
     * @return bool
     */
    public function invalidateAll(): bool
    {
        // Obtener todos los componentes
        $components = $this->wpdb->get_col(
            "SELECT DISTINCT component_name FROM {$this->wpdb->prefix}roi_theme_components"
        );

        $success = true;

        foreach ($components as $componentName) {
            $result = $this->invalidate("component_{$componentName}");
            $success = $success && $result;
        }

        return $success;
    }

    /**
     * Obtener clave completa con prefijo
     *
     * @param string $key
     * @return string
     */
    private function getFullKey(string $key): string
    {
        return self::PREFIX . $key;
    }
}
