<?php
/**
 * CocoDB_alias — Fachada sobre AcaiAPI con la misma firma pública que CocoDB.
 *
 * Uso:
 *   1. Incluir este archivo además de AcaiAPI.php (o en su lugar).
 *   2. Para migrar: copiar el contenido de este archivo, renombrar la clase a
 *      `CocoDB`, y TODA referencia anterior a CocoDB seguirá funcionando sin
 *      cambios en el código de llamada.
 *
 * Cómo funciona:
 *   - Declara las mismas propiedades estáticas públicas que CocoDB (force_redis,
 *     storeDebugData, etc.), de forma que el código externo pueda leerlas y
 *     escribirlas con la misma sintaxis.
 *   - Antes de cada llamada, sincroniza sus propiedades hacia AcaiAPI
 *     (syncToAcai). Después, lee de vuelta el estado acumulado (syncFromAcai).
 *   - Los métodos de la API pública delegan directamente a AcaiAPI manteniendo
 *     los mismos nombres y firmas que CocoDB.
 *
 * require_once 'CocoDB_alias.php';
 * require_once 'AcaiAPI.php';
 *
 * CocoDB_alias::$force_redis = true;
 * $result = CocoDB_alias::get('productos', 'visible=1', 'num ASC', 10);
 */

require_once __DIR__ . '/AcaiAPI.php';

class CocoDB {

    // ──────────────────────────────────────────────────────────────────────
    // Propiedades públicas — idénticas a CocoDB para compatibilidad directa
    // ──────────────────────────────────────────────────────────────────────

    /** Resultado raw de queries de debug */
    public static $debugData              = [];
    /** Activa acumulación de debugData */
    public static $storeDebugData         = false;
    /** Datos de tracking de rendimiento por request */
    public static $trackData              = [];
    public static $backTracePoint         = null;

    /** Profundidad de relaciones por defecto */
    public static $defaultRelationsDepth  = 2;

    /** Caché in-memory de resultados de get() */
    public static $getCaches              = [];
    /** Caché de campos traducibles */
    public static $allowedTranslateFields = null;
    /** Caché de configuración de plugins */
    public static $pluginsConfig          = [];

    /** Conexión Redis activa (null = sin Redis) */
    public static $redis                  = null;
    /** TTL Redis activo */
    public static $redis_expireTime       = 0;

    /** Activar caché in-memory para TODOS los get() */
    public static $force_load_cache       = false;
    /** Activar Redis para TODOS los get() */
    public static $force_redis            = false;
    /** Consumido por la capa de caché de módulos del CMS */
    public static $force_redis_module     = false;
    /** Consumido por la capa de caché de HTML del CMS */
    public static $force_redis_html       = false;
    /** Activar caché JSON diario de uploads */
    public static $force_json_cache_uploads = false;

    /** URIs excluidas de caché (array de regex) */
    public static $noCacheURIS            = [];
    /** Tablas excluidas de caché (nombre exacto) */
    public static $noCacheTABLES          = [];

    // ──────────────────────────────────────────────────────────────────────
    // Sincronización bidireccional de estado con AcaiAPI
    // ──────────────────────────────────────────────────────────────────────

    private static function syncToAcai() {
        AcaiAPI::$storeDebugData         = self::$storeDebugData;
        AcaiAPI::$defaultRelationsDepth  = self::$defaultRelationsDepth;
        AcaiAPI::$getCaches              = self::$getCaches;
        AcaiAPI::$allowedTranslateFields = self::$allowedTranslateFields;
        AcaiAPI::$pluginsConfig          = self::$pluginsConfig;
        AcaiAPI::$redis                  = self::$redis;
        AcaiAPI::$redis_expireTime       = self::$redis_expireTime;
        AcaiAPI::$force_load_cache       = self::$force_load_cache;
        AcaiAPI::$force_redis            = self::$force_redis;
        AcaiAPI::$force_redis_module     = self::$force_redis_module;
        AcaiAPI::$force_redis_html       = self::$force_redis_html;
        AcaiAPI::$force_json_cache_uploads = self::$force_json_cache_uploads;
        AcaiAPI::$noCacheURIS            = self::$noCacheURIS;
        AcaiAPI::$noCacheTABLES          = self::$noCacheTABLES;
        AcaiAPI::$backTracePoint         = self::$backTracePoint;
        AcaiAPI::$trackData              = self::$trackData;
    }

    private static function syncFromAcai() {
        self::$debugData              = AcaiAPI::$debugData;
        self::$trackData              = AcaiAPI::$trackData;
        self::$getCaches              = AcaiAPI::$getCaches;
        self::$allowedTranslateFields = AcaiAPI::$allowedTranslateFields;
        self::$pluginsConfig          = AcaiAPI::$pluginsConfig;
        self::$redis                  = AcaiAPI::$redis;
        self::$redis_expireTime       = AcaiAPI::$redis_expireTime;
        self::$force_load_cache       = AcaiAPI::$force_load_cache;
        self::$force_redis            = AcaiAPI::$force_redis;
        self::$force_redis_module     = AcaiAPI::$force_redis_module;
        self::$force_redis_html       = AcaiAPI::$force_redis_html;
        self::$force_json_cache_uploads = AcaiAPI::$force_json_cache_uploads;
    }

    // ──────────────────────────────────────────────────────────────────────
    // API pública principal — mismos nombres y firmas que CocoDB
    // ──────────────────────────────────────────────────────────────────────

    /**
     * Lee registros de una tabla.
     * Firma idéntica a CocoDB::get().
     */
    static function get($table, $where = null, $order = null, $limit = null, $options = []) {
        self::syncToAcai();
        $result = AcaiAPI::get($table, $where, $order, $limit, $options);
        self::syncFromAcai();
        return $result;
    }

    /**
     * Inserta uno o varios registros.
     * Firma idéntica a CocoDB::insertRecords().
     */
    static function insertRecords($table, $records, $functions = [], $options = []) {
        self::syncToAcai();
        $result = AcaiAPI::insert($table, $records, $functions, $options);
        self::syncFromAcai();
        return $result;
    }

    /**
     * Actualiza registros que cumplan $where.
     * Firma idéntica a CocoDB::updateRecords().
     */
    static function updateRecords($table, $records, $where, $functions = [], $options = []) {
        self::syncToAcai();
        $result = AcaiAPI::update($table, $records, $where, $functions, $options);
        self::syncFromAcai();
        return $result;
    }

    /**
     * Elimina registros que cumplan $where.
     * Firma idéntica a CocoDB::deleteRecords().
     */
    static function deleteRecords($table, $where, $options = []) {
        self::syncToAcai();
        $result = AcaiAPI::delete($table, $where, $options);
        self::syncFromAcai();
        return $result;
    }

    /**
     * Manejo de errores.
     * Firma idéntica a CocoDB::error().
     */
    static function error($array = []) {
        return AcaiAPI::error($array);
    }

    // ──────────────────────────────────────────────────────────────────────
    // Cache helpers — mismos nombres que CocoDB
    // ──────────────────────────────────────────────────────────────────────

    /** Activa caché in-memory para el siguiente get(). */
    static function localCache() {
        self::syncToAcai();
        AcaiAPI::localCache();
        self::syncFromAcai();
    }

    /** Activa Redis para el siguiente get(). */
    static function fullCache($expireTime = 60) {
        self::syncToAcai();
        AcaiAPI::fullCache($expireTime);
        self::syncFromAcai();
    }

    /** Limpia las cachés activas antes de la siguiente query. */
    static function initCache() {
        self::syncToAcai();
        AcaiAPI::initCache();
        self::syncFromAcai();
    }

    /** Genera el hash de caché para una query. Alias de cacheHash(). */
    static function cacheGenerateHash($string) {
        return AcaiAPI::cacheHash($string);
    }

    /** Guarda un valor en Redis o en $getCaches. */
    static function cacheSet($hash, $data, $expireTime = null) {
        self::syncToAcai();
        $result = AcaiAPI::cacheSet($hash, $data, $expireTime);
        self::syncFromAcai();
        return $result;
    }

    /** Lee un valor de Redis o $getCaches. */
    static function cacheGet($hash) {
        self::syncToAcai();
        $result = AcaiAPI::cacheGet($hash);
        self::syncFromAcai();
        return $result;
    }

    /** Comprueba si la URL actual está excluida de caché. */
    static function bloquedCacheByURL($url) {
        self::syncToAcai();
        return AcaiAPI::bloquedCacheByURL($url);
    }

    /**
     * En HTML cacheado, reemplaza el token CSRF con el de la sesión actual.
     * Firma idéntica a CocoDB::replaceHooksToken().
     */
    static function replaceHooksToken($html) {
        self::syncToAcai();
        return AcaiAPI::replaceHooksToken($html);
    }

    // ──────────────────────────────────────────────────────────────────────
    // Debug y tracking
    // ──────────────────────────────────────────────────────────────────────

    /**
     * Renderiza el panel de debug de queries.
     * Firma idéntica a CocoDB::showDebug().
     */
    static function showDebug($formated = false, $index = -1) {
        self::syncToAcai();
        return AcaiAPI::showDebug($formated, $index);
    }

    static function setBacktracePoint($string) {
        self::syncToAcai();
        $result = AcaiAPI::setBacktracePoint($string);
        self::syncFromAcai();
        return $result;
    }

    static function getTrackData() {
        self::syncFromAcai();
        return AcaiAPI::getTrackData();
    }

    static function setTrackData($init = false, $type = null, $id = null, $data = []) {
        self::syncToAcai();
        $result = AcaiAPI::setTrackData($init, $type, $id, $data);
        self::syncFromAcai();
        return $result;
    }

    // ──────────────────────────────────────────────────────────────────────
    // Categorías
    // ──────────────────────────────────────────────────────────────────────

    /**
     * Reconstruye el árbol de categorías (globalOrder, siblingOrder, depth,
     * lineage, breadcrumb) para la tabla indicada.
     * Firma idéntica a CocoDB::updateCategoryMetadata().
     */
    static function updateCategoryMetadata($tableName = null, $where = '') {
        self::syncToAcai();
        $result = AcaiAPI::updateCategoryMetadata($tableName, $where);
        self::syncFromAcai();
        return $result;
    }

    // ──────────────────────────────────────────────────────────────────────
    // Schema
    // ──────────────────────────────────────────────────────────────────────

    /**
     * Carga y cachea el schema de una tabla.
     * Equivalente a la función privada schema() de AcaiAPI, expuesta aquí
     * para compatibilidad con código externo que llame a CocoDB::schema().
     */
    static function schema($table) {
        return AcaiAPI::schema($table);
    }

    // ──────────────────────────────────────────────────────────────────────
    // Plugins
    // ──────────────────────────────────────────────────────────────────────

    static function getPluginsConfig($table, $where) {
        self::syncToAcai();
        $result = AcaiAPI::getPluginsConfig($table, $where);
        self::syncFromAcai();
        return $result;
    }

    // ──────────────────────────────────────────────────────────────────────
    // Traducciones — mismo helper que CocoDB expone públicamente
    // ──────────────────────────────────────────────────────────────────────

    /**
     * Aplica traducciones recursivamente a un registro.
     * Firma idéntica a CocoDB::t_recursivo().
     */
    static function t_recursivo($record, $idx = null) {
        self::syncToAcai();
        $result = AcaiAPI::t_recursivo($record, $idx);
        self::syncFromAcai();
        return $result;
    }

    // ──────────────────────────────────────────────────────────────────────
    // Métodos internos de CocoDB — stubs para compatibilidad
    //
    // Estos métodos son "public static" en CocoDB por accidente histórico;
    // ningún código externo debería llamarlos directamente. Si encuentras un
    // uso externo, migra la llamada al equivalente de AcaiAPI o refactoriza.
    // ──────────────────────────────────────────────────────────────────────

    /** @deprecated Método interno de CocoDB. No disponible en AcaiAPI. */
    static function insertOrUpdate($record, $sqlBase, &$result, $where = null, $table = null, $functions = null, $ignoreSchema = false, $schema = null, $options = []) {
        trigger_error('CocoDB_alias::insertOrUpdate() es un método interno. Usa insertRecords() o updateRecords().', E_USER_WARNING);
    }

    /** @deprecated Método interno de CocoDB. */
    static function prepareBaseSQL($prefix, $table, $schema = null, $update = false, $ignoreFields = [], $record = []) {
        trigger_error('CocoDB_alias::prepareBaseSQL() es un método interno.', E_USER_WARNING);
    }

    /** @deprecated Método interno de CocoDB. */
    static function parse_options($options) {
        trigger_error('CocoDB_alias::parse_options() es un método interno.', E_USER_WARNING);
    }

    /** @deprecated Usa el schema directamente. */
    static function column_exists($key, $schema, $table, $prefix = '') {
        trigger_error('CocoDB_alias::column_exists() es un método interno.', E_USER_WARNING);
    }

    /** @deprecated Método interno de CocoDB. */
    static function cache_column($table, $column, $exists) {
        trigger_error('CocoDB_alias::cache_column() es un método interno.', E_USER_WARNING);
    }

    /** @deprecated Método interno de CocoDB. */
    static function parse_value_schema($value, $schema, $key) {
        trigger_error('CocoDB_alias::parse_value_schema() es un método interno.', E_USER_WARNING);
    }

    /** @deprecated Usa buildWhere() de AcaiAPI (privado). Pasa el where directamente a get(). */
    static function parse_where($where, $table, $prefix = '') {
        trigger_error('CocoDB_alias::parse_where() es un método interno. Pasa el $where directamente a get().', E_USER_WARNING);
    }

    /** @deprecated Método interno de CocoDB. */
    static function unsetKeys($array, $keys) {
        trigger_error('CocoDB_alias::unsetKeys() es un método interno.', E_USER_WARNING);
    }

    /** @deprecated Método interno de CocoDB. */
    static function parseGetRecord(&$record, $firstTable, $schema, $options = [], $uploadsResult = []) {
        trigger_error('CocoDB_alias::parseGetRecord() es un método interno.', E_USER_WARNING);
    }

    /** @deprecated Método interno de CocoDB. */
    static function getUploadsResults($options) {
        trigger_error('CocoDB_alias::getUploadsResults() es un método interno.', E_USER_WARNING);
    }

    /** @deprecated Método interno de CocoDB. */
    static function getUploadsResultsFromRecord(&$record, $firstTable, $schema, $options) {
        trigger_error('CocoDB_alias::getUploadsResultsFromRecord() es un método interno.', E_USER_WARNING);
    }
}
