<?php
/**
 * FluentC WordPress Language File.
 *
 * This file contains the functions for managing Languages
 *
 * @category Translation
 * @package  FluentCPlugin
 * @author   FluentC <wp@fluentc.io>
 * @license  http://www.gnu.org/copyleft/gpl.html GNU General Public License
 * @link     https://www.fluentc.ai
 */

namespace FluentC\Utils;

use FluentC\Services\Connect;
use FluentC\Services\Cache;
use FluentC\Services\API_Key_Validator;

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

/**
 * Utils needed to manage language
 */
class Language {

	/**
	 * FluentC connection class
	 *
	 * @var object
	 */
	protected $fluentc_connect;

	/**
	 * FluentC Cache class
	 *
	 * @var object
	 */
	protected $fluentc_cache;
	
	/**
	 * FluentC API Key Validator
	 *
	 * @var API_Key_Validator
	 */
	protected $api_validator;
	
	/**
	 * FluentC lang list string
	 *
	 * @var string
	 */
	protected $regex_lang;
	
	/**
	 * FluentC widget options
	 *
	 * @var object|null
	 */
	protected $fetch_widget_options;
	
	/**
	 * Current language code
	 *
	 * @var string|null
	 */
	protected $current_language = null;
	
	/**
	 * Default language code
	 *
	 * @var string
	 */
	protected $default_language = null;
	
	/**
	 * Available languages
	 *
	 * @var array
	 */
	protected $available_languages = [];

	/**
	 * Constructor.
	 *
	 * @since 1.2
	 */
	public function __construct() {
		$this->fluentc_connect = new Connect();
		$this->fluentc_cache = new Cache();
		$this->api_validator = new API_Key_Validator();
    
		$widget_id = get_option('fluentc_api_key');
		
		// First check if we have a valid API key
		$has_valid_key = $this->api_validator->has_valid_api_key();
		
		if ($widget_id && $has_valid_key) {
			// Get language list from cache first
			$this->regex_lang = $this->fluentc_cache->get('regex_lang_' . $widget_id, 'languages');
			
			// Only fetch if not in cache
			if ($this->regex_lang === false) {
				$this->regex_lang = $this->fluentc_connect->get_language_list_string($widget_id);
				if (!empty($this->regex_lang)) {
					$this->fluentc_cache->set('regex_lang_' . $widget_id, $this->regex_lang, 'languages', 12 * HOUR_IN_SECONDS);
				}
			}
			
			// Same for widget options - with added safety checks
			$this->fetch_widget_options = $this->fluentc_cache->get('widget_options_' . $widget_id, 'languages');
			if ($this->fetch_widget_options === false) {
				$this->fetch_widget_options = $this->fluentc_connect->fetch_widget_options($widget_id);
				// Verify we got a valid response before caching
				if (is_object($this->fetch_widget_options) && isset($this->fetch_widget_options->data) && 
					isset($this->fetch_widget_options->data->fetchSiteOptions)) {
					$this->fluentc_cache->set('widget_options_' . $widget_id, $this->fetch_widget_options, 'languages', 12 * HOUR_IN_SECONDS);
				} else {
					// Invalid response, set to null to avoid errors
					$this->fetch_widget_options = null;
				}
			}
			
			// And available languages
			$this->available_languages = $this->fluentc_cache->get('available_languages_' . $widget_id, 'languages');
			if ($this->available_languages === false) {
				$this->available_languages = $this->fluentc_connect->get_language_list($widget_id) ?: [];
				if (!empty($this->available_languages)) {
					$this->fluentc_cache->set('available_languages_' . $widget_id, $this->available_languages, 'languages', 12 * HOUR_IN_SECONDS);
				}
			}
		} else {
			// Set default values if no valid API key
			$this->regex_lang = '';
			$this->available_languages = [];
			$this->fetch_widget_options = null;
		}
		
		// Initialize default language
		$this->default_language = $this->fluentc_site_language();
		
		// Set up initialization hooks
		add_action('parse_request', [$this, 'maybe_set_language_from_query'], 1);
	}

	/**
	 * Get the site's default language
	 *
	 * @return string
	 * @since 1.2
	 */
	public function fluentc_site_language() {
		if (!$this->default_language) {
			// First try to get from validated API key
			if ($this->api_validator->has_valid_api_key()) {
				$site_language = $this->api_validator->get_source_language();
				if (!empty($site_language)) {
					$this->default_language = substr($site_language, 0, 2);
					return $this->default_language;
				}
			}
			
			// Then try from widget options if available
			if ($this->fetch_widget_options && isset($this->fetch_widget_options->data) && 
				isset($this->fetch_widget_options->data->fetchSiteOptions) && 
				isset($this->fetch_widget_options->data->fetchSiteOptions->sourceLanguage)) {
				$site_language = $this->fetch_widget_options->data->fetchSiteOptions->sourceLanguage;
				$site_language = substr($site_language, 0, 2);
				$this->default_language = $site_language;
			} else {
				// Otherwise use WordPress default locale
				$site_language = substr(get_bloginfo('language'), 0, 2);
				$this->default_language = $site_language;
			}
		}
		
		return $this->default_language;
	}

	/**
	 * Get the current language from the query var if available
	 *
	 * @param object $wp WordPress request object
	 * @return void
	 */
	public function maybe_set_language_from_query($wp) {
		// First check if the fluentc_language query var is set
		if (isset($wp->query_vars['fluentc_language'])) {
			$this->set_current_language($wp->query_vars['fluentc_language']);
		} else {
			// Fall back to regex if query var not available
			$this->set_language_from_url();
		}
	}
	
	/**
	 * Legacy method to extract language from URL using regex
	 *
	 * @return void
	 */
	protected function set_language_from_url() {
		if (empty($this->regex_lang)) {
			return;
		}
		
		$pattern = '/\/(' . $this->regex_lang . ')(\/|$|\?|#)/';
		
		if (isset($_SERVER['REQUEST_URI'])) {
			$sanitize_uri_raw = filter_var($_SERVER['REQUEST_URI'], FILTER_SANITIZE_URL);
			
			if (preg_match($pattern, wp_unslash($sanitize_uri_raw), $matches)) {
				if (isset($matches[1])) {
					$this->set_current_language($matches[1]);
				}
			}
		}
	}

	/**
	 * Set the current language code
	 *
	 * @param string $language_code The language code to set
	 * @return void
	 */
	public function set_current_language($language_code) {
		// Validate the language code against available languages
		if (empty($language_code) || ($this->available_languages && !in_array($language_code, $this->available_languages))) {
			return;
		}
		
		$this->current_language = $language_code;
		
		// Make the language available globally
		$GLOBALS['fluentc_current_language'] = $language_code;
		
		// Set locale for WordPress - helps with date formatting etc.
		add_filter('locale', function($locale) use ($language_code) {
			// Map language code to WordPress locale if needed
			$locale_map = [
				'en' => 'en_US',
				'fr' => 'fr_FR',
				'es' => 'es_ES',
				'de' => 'de_DE',
				// Add more mappings as needed
			];
			
			return isset($locale_map[$language_code]) ? $locale_map[$language_code] : $locale;
		});
		
		// Fire an action so other code can respond to language changes
		do_action('fluentc_language_set', $language_code);
	}

	/**
	 * Get the current language code
	 *
	 * @return string|null The current language code or null if not set
	 */
	public function get_fluentc_language() {
		// Return from property if already set
		if ($this->current_language !== null) {
			return $this->current_language;
		}
		
		// Check global variable
		if (isset($GLOBALS['fluentc_current_language'])) {
			return $GLOBALS['fluentc_current_language'];
		}
		
		// Check for AJAX request with language parameter
		if (wp_doing_ajax() && isset($_REQUEST['fluentc_language'])) {
			$ajax_language = sanitize_text_field($_REQUEST['fluentc_language']);
			// Validate the language code against available languages
			if (!empty($ajax_language) && in_array($ajax_language, $this->available_languages)) {
				// Store in property for future calls
				$this->current_language = $ajax_language;
				return $ajax_language;
			}
		}
		
		// Only try regex method if we have the language list
		if (!empty($this->regex_lang)) {
			// Fall back to regex method for backward compatibility
			$pattern = '/\/(' . $this->regex_lang . ')(\/|$|\?|#)/';
			
			if (isset($_SERVER['REQUEST_URI'])) {
				$sanitize_uri_raw = filter_var($_SERVER['REQUEST_URI'], FILTER_SANITIZE_URL);
				
				if (preg_match($pattern, wp_unslash($sanitize_uri_raw), $matches)) {
					if (isset($matches[1])) {
						// Store in property for future calls
						$this->current_language = $matches[1];
						return $matches[1];
					}
				}
			}
		}
		
		return null;
	}

	/**
	 * Check if a language is available
	 *
	 * @param string $language_code The language code to check
	 * @return bool True if the language is available
	 */
	public function is_language_available($language_code) {
		return in_array($language_code, $this->available_languages);
	}

	/**
	 * Get all available languages
	 *
	 * @return array List of language codes
	 */
	public function get_available_languages() {
		return $this->available_languages;
	}

	/**
	 * FluentC Language Helper with slashes
	 *
	 * @return string|null
	 * @since 1.2
	 */
	public function get_fluentc_language_url() {
		$language_code = $this->get_fluentc_language();
		
		if ($language_code) {
			return '/' . $language_code . '/';
		}
		
		return null;
	}

	/**
	 * FluentC Language Helper with slashes from url
	 *
	 * @param string $url The URL to extract language from
	 * @return string|null
	 * @since 1.2
	 */
	public function get_fluentc_language_url_from_url($url) {
		if (empty($this->regex_lang)) {
			return null;
		}
		
		$pattern = '/\/(' . $this->regex_lang . ')(\/|$|\?|#)/';
		
		if (preg_match($pattern, wp_unslash($url), $matches)) {
			return $matches[0];
		}
		
		return null;
	}
	
	/**
	 * Get the widget display appearance setting
	 *
	 * @return string Display appearance (default: 'float')
	 */
	public function get_widget_appearance() {
		if ($this->fetch_widget_options && isset($this->fetch_widget_options->data) && 
			isset($this->fetch_widget_options->data->fetchSiteOptions) &&
			isset($this->fetch_widget_options->data->fetchSiteOptions->appearance)) {
			return $this->fetch_widget_options->data->fetchSiteOptions->appearance;
		}
		
		return 'float'; // Default to float if not set
	}
}