<?php
/**
 * Site data and locale batch fetching.
 *
 * @package EffortLessMultisiteLanguageSwitcher
 */

if ( ! defined( 'ABSPATH' ) ) {
	exit;
}

/**
 * Handles fetching site data (locale, blogname) for multisite blogs.
 */
class ELMLS_Site_Data {

	/**
	 * Flag resolver instance.
	 *
	 * @var ELMLS_Flag_Resolver
	 */
	private $flag_resolver;

	/**
	 * Constructor.
	 *
	 * @param ELMLS_Flag_Resolver $flag_resolver Flag resolver instance.
	 */
	public function __construct( ELMLS_Flag_Resolver $flag_resolver ) {
		$this->flag_resolver = $flag_resolver;
	}

	/**
	 * Fetches WPLANG locale and blogname for multiple sites in batch.
	 *
	 * Uses get_blog_details() for batch fetching, with fallback to individual
	 * get_blog_option() calls.
	 *
	 * @param array $blog_ids Array of blog IDs.
	 * @return array Array of arrays with 'locale' and 'blogname' keys.
	 */
	public function get_site_data( $blog_ids ) {
		if ( empty( $blog_ids ) ) {
			return array();
		}

		// Try object cache first.
		$cache_key = 'elmls_site_data_' . md5( implode( ',', $blog_ids ) );
		$cached    = wp_cache_get( $cache_key, 'elmls' );

		if ( false !== $cached ) {
			return $cached;
		}

		$data = array();

		// Use get_blog_details for batch fetching (faster than individual queries).
		$blog_ids_chunk = array_chunk( $blog_ids, apply_filters( 'elmls_sites_limit', 100 ) );
		foreach ( $blog_ids_chunk as $chunk ) {
			$blogs = get_blog_details( $chunk );

			if ( ! empty( $blogs ) ) {
				// get_blog_details returns single blog object if single ID passed,
				// array if multiple IDs passed.
				if ( is_array( $blogs ) ) {
					foreach ( $blogs as $blog ) {
						$data[ $blog->blog_id ] = array(
							'locale'   => $this->flag_resolver->normalize_locale( $blog->lang ),
							'blogname' => ! empty( $blog->blogname ) ? $blog->blogname : "Site #{$blog->blog_id}",
						);
					}
				} else {
					$data[ $blogs->blog_id ] = array(
						'locale'   => $this->flag_resolver->normalize_locale( $blogs->lang ),
						'blogname' => ! empty( $blogs->blogname ) ? $blogs->blogname : "Site #{$blogs->blog_id}",
					);
				}
			}
		}

		// Any missing ones (not in get_blog_details response), fetch individually.
		$missing = array_diff( $blog_ids, array_keys( $data ) );
		foreach ( $missing as $blog_id ) {
			$data[ $blog_id ] = array(
				'locale'   => $this->flag_resolver->normalize_locale( get_blog_option( $blog_id, 'WPLANG', '' ) ),
				'blogname' => get_blog_option( $blog_id, 'blogname', "Site #$blog_id" ),
			);
		}

		// Cache for 1 hour.
		wp_cache_set( $cache_key, $data, 'elmls', HOUR_IN_SECONDS );

		return $data;
	}

	/**
	 * Fetches WPLANG locale for multiple sites in a single query.
	 *
	 * Uses get_blog_details() to batch-fetch, with fallback to individual
	 * get_blog_option() calls.
	 *
	 * @param array $blog_ids Array of blog IDs.
	 * @return array Map of blog_id => locale.
	 */
	public function get_site_locales( $blog_ids ) {
		if ( empty( $blog_ids ) ) {
			return array();
		}

		// Use get_site_data and extract locales.
		$site_data = $this->get_site_data( $blog_ids );
		$locales   = array();

		foreach ( $site_data as $blog_id => $data ) {
			$locales[ $blog_id ] = $data['locale'];
		}

		return $locales;
	}
}
