<?php
/**
 * Flag resolution and locale normalization.
 *
 * @package EffortLessMultisiteLanguageSwitcher
 */

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

/**
 * Handles flag mapping, locale normalization, and flag image rendering.
 */
class ELMLS_Flag_Resolver {

	/**
	 * Mapping of locale codes to flags.
	 *
	 * @var array|null
	 */
	private $flag_mapping = null;

	/**
	 * Returns the flag code for a given locale.
	 *
	 * Uses transients with object cache fallback for performance.
	 *
	 * @param string $locale Locale code.
	 * @return string Flag code.
	 */
	public function get_flag_code( $locale ) {
		if ( null === $this->flag_mapping ) {
			// Try object cache first (persistent across requests if object caching enabled).
			$this->flag_mapping = wp_cache_get( 'elmls_flag_mapping', 'elmls' );

			if ( false === $this->flag_mapping ) {
				// Fallback to transient with version key.
				$transient_key      = 'elmls_flag_mapping_v' . str_replace( '.', '_', ELMLS_Plugin::VERSION );
				$this->flag_mapping = get_transient( $transient_key );

				if ( false === $this->flag_mapping ) {
					$json_path = ELMLS_Plugin::PLUGIN_DIR . '/assets/flags/locales_flags.json';
					if ( file_exists( $json_path ) ) {
						// phpcs:ignore WordPress.WP.AlternativeFunctions.file_get_contents_file_get_contents
						$decoded            = json_decode( file_get_contents( $json_path ), true );
						$this->flag_mapping = is_array( $decoded ) ? $decoded : array();
					} else {
						$this->flag_mapping = array();
					}

					// Cache for 12 hours (transient).
					set_transient( $transient_key, $this->flag_mapping, 12 * HOUR_IN_SECONDS );
				}

				// Store in object cache if available.
				if ( ! empty( $this->flag_mapping ) ) {
					wp_cache_set( 'elmls_flag_mapping', $this->flag_mapping, 'elmls', 12 * HOUR_IN_SECONDS );
				}

				// Merge custom flag mapping from settings.
				$custom_mapping = get_site_option( 'elmls_custom_flag_mapping', '' );
				if ( ! empty( $custom_mapping ) ) {
					$custom = json_decode( $custom_mapping, true );
					if ( is_array( $custom ) ) {
						$this->flag_mapping = array_merge( $this->flag_mapping, $custom );
					}
				}

				/**
				 * Filters the locale to flag mapping.
				 *
				 * @since 1.0.30
				 *
				 * @param array $flag_mapping Array of locale => flag code.
				 */
				$this->flag_mapping = apply_filters( 'elmls_flag_mapping', $this->flag_mapping );
			}
		}

		$locale = $this->normalize_locale( sanitize_text_field( $locale ) );

		$flag_code = isset( $this->flag_mapping[ $locale ] ) ? $this->flag_mapping[ $locale ] : 'world';

		return $flag_code;
	}

	/**
	 * Returns a sanitized locale, falling back to 'en_US' if empty.
	 *
	 * @param string $locale Raw locale string.
	 * @return string Sanitized locale.
	 */
	public function normalize_locale( $locale ) {
		return ! empty( $locale ) ? $locale : 'en_US';
	}

	/**
	 * Returns the list of available flag codes (from the bundled SVG files).
	 *
	 * @return array Sorted array of flag codes.
	 */
	public function get_available_flag_codes() {
		$codes = wp_cache_get( 'elmls_available_flag_codes', 'elmls' );
		if ( false !== $codes ) {
			return $codes;
		}

		$codes     = array();
		$flag_path = ELMLS_Plugin::PLUGIN_DIR . '/assets/flags/1x1';
		$files     = glob( $flag_path . '/*.svg' );

		if ( is_array( $files ) ) {
			foreach ( $files as $file ) {
				$codes[] = basename( $file, '.svg' );
			}
			sort( $codes );
		}

		wp_cache_set( 'elmls_available_flag_codes', $codes, 'elmls', 12 * HOUR_IN_SECONDS );

		return $codes;
	}

	/**
	 * Returns the URL of the flag image for a given flag code.
	 *
	 * @param string $flag_code Flag code.
	 * @return string Flag URL.
	 */
	public function get_flag_url( $flag_code ) {
		$flag_code = sanitize_file_name( $flag_code );
		$flag_path = ELMLS_Plugin::PLUGIN_DIR . "/assets/flags/1x1/{$flag_code}.svg";
		if ( file_exists( $flag_path ) ) {
			return ELMLS_PLUGIN_URL . "assets/flags/1x1/{$flag_code}.svg";
		}
		// Fallback to us.svg if flag file doesn't exist.
		return ELMLS_PLUGIN_URL . 'assets/flags/1x1/us.svg';
	}

	/**
	 * Renders a flag <img> tag.
	 *
	 * @param string $url    Flag image URL.
	 * @param string $locale Locale code.
	 * @return string HTML <img> tag.
	 */
	public function render_flag_img( $url, $locale ) {
		$attachment_id = attachment_url_to_postid( $url );
		if ( $attachment_id ) {
			return wp_get_attachment_image( $attachment_id, 'thumbnail', false, array( 'alt' => esc_attr( $locale ) ) );
		}

		$image_attributes = array(
			'src'      => esc_url( $url ),
			'alt'      => esc_attr( $locale ),
			'width'    => 24,
			'height'   => 24,
			'decoding' => 'async',
			'loading'  => 'lazy',
		);

		return '<img ' . implode(
			' ',
			array_map(
				function ( $key, $value ) {
					return sprintf( '%s="%s"', $key, $value );
				},
				array_keys( $image_attributes ),
				$image_attributes
			)
		) . ' />';
	}
}
