<?php
/**
 * Please see weepie-framework.php for more details.
 */

namespace WpieFw\Helpers;

use WpieFw\Helpers\WpieMultilangHelper;

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

/**
 * WpieWpmlHelper class
 *
 * Helper class that helps with WPML functions
 *
 * @author $Author: Vincent Weber <weepie-plugins@outlook.com> $
 *
 * @since 1.2
 */
final class WpieWpmlHelper extends WpieMultilangHelper
{
	/**
	 * Get the current active language data
	 *
	 * @acces public
	 *
	 * @uses self::getLangs()
	 *
	 * @since 1.2
	 *
	 * @return array
	 */
	public static function getActiveLanguageData()
	{
		static $cache = null;

		if( null !== $cache ) {
			return $cache;
		}

		$langs = self::getLangs();
		$data = [];

		foreach ( $langs as $code => $data ) {
			if( '1' === $data['active'] ) {
				break;
			}
		}

		if( !empty( $data ) ) {
			$cache = $data;
		}

		return $data;
	}

	/**
	 * Get the active language code
	 *
	 * @acces public
	 *
	 * @uses self::getLangs()
	 *
	 * @since 1.2
	 *
	 * @return string the language code or bool false on failure
	 */
	public static function getActiveCode()
	{
		static $cache = null;

		if( null !== $cache ) {
			return $cache;
		}

		$langs = self::getLangs();
		$activeCode = false;

		foreach ( $langs as $code => $data ) {
			if(  '1' === $data['active'] ) {
				if ( '' === $code && defined( 'ICL_LANGUAGE_CODE' ) ) {
					$activeCode = ICL_LANGUAGE_CODE;
				} elseif( '' !== $code ) {
					$activeCode = $code;
				} else {
					$activeCode = false;
				}
				break;
			}
		}

		if( !$activeCode && self::isAll() ) {
			$activeCode = 'all';
		}

		if( $activeCode ) {
			$cache = $activeCode;
		}

		return $activeCode;
	}

	/**
	 * Get the active language locale
	 *
	 * @acces public
	 *
	 * @uses self::getLangs()
	 *
	 * @since 1.2
	 *
	 * @return string the locale or bool false on failure
	 */
	public static function getActiveLocale()
	{
		static $cache = null;

		if( null !== $cache ) {
			return $cache;
		}

		$langs = self::getLangs();
		$activeLang = false;

		foreach ( $langs as $code => $data ) {
			if(  '1' === $data['active'] ) {
				$activeLang = $data['default_locale'];
				break;
			}
		}

		if( $activeLang ) {
			$cache = $activeLang;
		}

		return $activeLang;
	}

	/**
	 * Get all language codes
	 *
	 * @acces public
	 *
	 * @uses self::getLangs()
	 *
	 * @since 1.2
	 *
	 * @return array
	 */
	public static function getAllCodes()
	{
		static $cache = null;

		if( null !== $cache ) {
			return $cache;
		}

		$langs = self::getLangs();
		$codes = [];

		foreach ( $langs as $code => $data ) {
			$codes[] = $code;
		}

		if( !empty( $codes ) ) {
			$cache = $codes;
		}

		return $codes;
	}

	/**
	 * Get all language locales
	 *
	 * @acces public
	 *
	 * @uses self::getLangs()
	 *
	 * @since 1.2
	 *
	 * @return array
	 */
	public static function getAllLocales()
	{
		static $cache = null;

		if( null !== $cache ) {
			return $cache;
		}

		$langs = self::getLangs();
		$locales = [];

		foreach ( $langs as $code => $data ) {
			$locales[$code] = $data['default_locale'];
		}

		if( !empty( $locales ) ) {
			$cache = $locales;
		}

		return $locales;
	}

	/**
	 * Get the active language locale
	 *
	 * For backword compatibility keep this method
	 *
	 * @see self::getActiveLocale()
	 */
	public static function getActiveLang()
	{
		return self::getActiveLocale();
	}

	/**
	 * Get WPML default language code
	 *
	 * @acces public
	 *
	 * @uses  icl_get_default_language()
	 * @uses  wpml_get_default_language()
	 * @uses  filter "wpml_default_language"
	 *
	 * @since 1.2
	 *
	 * @return string or bool false
	 */
	public static function getDefaultCode()
	{
		static $cache = null;

		if( null !== $cache ) {
			return $cache;
		}

		if( function_exists( 'icl_get_default_language' ) ) {
			$code = icl_get_default_language();
		} elseif( function_exists( 'wpml_get_default_language' ) ) {
			$code = wpml_get_default_language();
		} elseif( has_filter( 'wpml_default_language' ) ) {
			$code = apply_filters( 'wpml_default_language', NULL );
		} else {
			$code = false;
		}

		if( false !== $code ) {
			$cache = $code;
		}

		return $code;
	}

	/**
	 * Get all active language data
	 *
	 * @acces public
	 *
	 * @uses icl_get_languages()
	 *
	 * @since 1.2
	 *
	 * @return array or bool false on failure
	 */
	public static function getActiveLangsData()
	{
		static $cache = null;

		if( null !== $cache ) {
			return $cache;
		}

		if( function_exists( 'icl_get_languages' ) ) {
			$langs = icl_get_languages();
		} elseif( has_filter( 'wpml_default_language' ) ) {
			$langs = apply_filters( 'wpml_active_languages', '', [] );
		} else {
			$langs = false;
		}

		if( is_array( $langs ) && !empty( $langs ) ) {
			$cache = $langs;
		}

		return $langs;
	}

	/**
	 * synonyme for self::getActiveLangsData()
	 *
	 * @see self::getActiveLangsData()
	 */
	public static function getLangs()
	{
		return self::getActiveLangsData();
	}

	/**
	 * Get the current language code
	 *
	 * Use this function if 'all' is a possible option
	 *
	 * @access 	public
	 *
	 * @param	wpml_get_current_language()
	 *
	 * @since 	1.2
	 *
	 * @return	string
	 */
	public static function getCurrentCode()
	{
		static $cache = null;

		if( null !== $cache ) {
			return $cache;
		}

		// @todo is wpml_get_current_language hook working here?
		// see https://wpml.org/wpml-hook/wpml_current_language/
		if( has_filter( 'wpml_get_current_language' ) ) {
			$current = apply_filters( 'wpml_current_language', NULL );
		} elseif( function_exists( 'wpml_get_current_language' ) ) {
			$current = wpml_get_current_language();
		} else {
			$current = '';
		}

		if( '' !== $current ) {
			$cache = $current;
		}

		return $current;
	}

	/**
	 * Get posst for current language only
	 *
	 * @access public
	 *
	 * @param array $posts with WP_Post objects
	 * @param string 	$code (optional) the current language code
	 *
	 * @uses wpml_get_language_information()
	 *
	 * @return bool false or array with posts
	 */
	public static function getPostsCurrentLanguage ( $posts = [], $code = '' )
	{
		if( !is_array( $posts ) ) {
			return false;
		}

		$postsCurrLang = [];

		if( '' === $code ) {
			$code = self::getActiveCode();
		}

		foreach ( $posts as $postId => $post ) {
			if( !is_a( $post, 'WP_Post') ) {
				continue;
			}

			$info = wpml_get_language_information( null, $postId );
			if( $code === $info['language_code'] ) {
				$postsCurrLang[] = $post;
			}
		}

		return ( !empty( $postsCurrLang ) ) ? $postsCurrLang : false;
	}

	/**
	 * Get a settings value
	 *
	 * @param string $key
	 * @param string $default
	 *
	 * @since 1.4.10
	 *
	 * @return NULL|mixed null if $key is empty
	 */
	public static function getSetting( $key = '', $default = false )
	{
		if( '' === trim( $key ) ) {
			return null;
		}

		return apply_filters( 'wpml_setting', $default, $key );
	}

	/**
	 * Switch the language
	 *
	 * If the given $code equals the active lang, return this language code
	 *
	 * @access public
	 *
	 * @param string $code
	 *
	 * @since 1.2
	 *
	 * @return string the (switched) language code
	 */
	public static function switchLanguage( $code = '', $cookie = false )
	{
		if( '' === $code ) {
			$code = self::getDefaultCode();
		}

		if( has_action( 'wpml_switch_language' ) ) {
			do_action( 'wpml_switch_language', $code );
		} else {
			global $sitepress;
			$sitepress->switch_lang( $code, $cookie );
		}

		return self::getCurrentCode();
	}

	/**
	 * Determine if current request is for 'all'
	 *
	 * @access	public
	 *
	 * @uses	self::getCurrentCode()
	 *
	 * @since	1.2
	 *
	 * @return	bool
	 */
	public static function isAll()
	{
		static $cache = null;

		if( null !== $cache ) {
			return $cache;
		}

		$current = self::getCurrentCode();
		$isAll = ( 'all' === $current ) ? true : false;
		$cache = $isAll;

		return $isAll;
	}

	/**
	 * Is the WPML Plugin active
	 *
	 * @access public
	 *
	 * @since 1.2
	 *
	 * @return bool
	 */
	public static function isActive()
	{
		return ( defined( 'ICL_LANGUAGE_CODE' ) && class_exists( 'SitePress' ) ) ? true : false;
	}

	/**
	 * Is the WPML Plugin ready, i.e. is the setup complete
	 *
	 * @access public
	 *
	 * @uses SitePress::get_setting( 'setup_complete' )
	 *
	 * @since 1.2
	 *
	 * @return bool
	 */
	public static function isReady()
	{
		if( !self::isActive() ) {
			return false;
		}

		global $sitepress;

		if( is_object( $sitepress ) && !method_exists( $sitepress, 'get_setting' ) ) {
			return false;
		}

		//@TODO: use WPML API for get_setting() (if possible)
		return ( is_object( $sitepress ) && $sitepress->get_setting( 'setup_complete' ) ) ? true : false;
	}

	/**
	 * Determine if WPML is setup with A different domain per language
	 *
	 * @param string $domain
	 *
	 * @uses self::getSetting()
	 *
	 * @since 1.4.10
	 *
	 * @return boolean
	 */
	public static function isDomainPerLanguageSetup( $domain = '' )
	{
		return ( 2 === (int)self::getSetting( 'language_negotiation_type', 0 ) );
	}

	/**
	 * Determine if given domain is in WPML language_domains array
	 *
	 * @param string $domain
	 *
	 * @uses self::isDomainPerLanguageSetup()
	 * @uses self::getSetting()
	 * @uses WpieMiscHelper::getHostWithoutSubdomain()
	 *
	 * @since 1.4.10
	 *
	 * @return boolean false if language_domains is empty or domain not found, else true
	 */
	public static function isDomainInLanguageDomains( $domain = '' )
	{
		// return false if not having a different domain per language setup
		if( !self::isDomainPerLanguageSetup() ) {
			return false;
		}

		// get WPML language domains
		$languageDomains = self::getSetting( 'language_domains', [] );

		// return false if not having language domains
		if( 0 === count( $languageDomains ) ) {
			return false;
		}

		// remove sub domains from WPML language domains
		$languageDomains = array_map( [ '\WpieFw\Helpers\WpieMiscHelper', 'getHostWithoutSubdomain' ], $languageDomains );
		// get the passed domain with sub domain
		$domain = WpieMiscHelper::getHostWithoutSubdomain( $domain );

		// return if $domain is in the anguage domains array
		return ( in_array( $domain, $languageDomains ) );
	}

	/**
	 * Remove the 'All' language switcher
	 *
	 * @acces public
	 *
	 * @uses WP_Admin_Bar::get_nodes()
	 * @uses WP_Admin_Bar::remove_node()
	 * @uses WP_Admin_Bar::add_node()
	 *
	 * @since 1.2
	 */
	public static function removeAllFromAdminBar()
	{
		global $wp_admin_bar;

		$nodes = $wp_admin_bar->get_nodes();

		if( isset( $nodes['WPML_ALS_all'] ) ) {
			$wp_admin_bar->remove_node( 'WPML_ALS_all' );
		} elseif( isset( $nodes['WPML_ALS'] ) && 'all' === $this->activeCode ) {
			$wp_admin_bar->remove_node( 'WPML_ALS' );

			foreach( $nodes as $k => $node ) {
				if( false !== strpos( $k, 'WPML_ALS' ) && 'WPML_ALS' === $node->parent ) {
					$newNode = [];
					$newNode['id'] 		= $node->id;
					$newNode['title'] 	= $node->title;
					$newNode['parent']	= null;
					$newNode['href'] 	= $node->href;
					$newNode['group'] 	= $node->group;
					$newNode['meta'] 	= $node->meta;

					$wp_admin_bar->remove_node( $k );
					$wp_admin_bar->add_node( $newNode );
				}
			}
		}
	}

	/**
	 * Redirect the current settings tab to the default language if 'all' is requested
	 *
	 * @access public
	 *
	 * @uses SitePress::get_default_language()
	 * @uses add_query_arg()
	 * @uses wp_redirect()
	 *
	 * @since 1.2
	 */
	public static function redirectIfIsAll()
	{
		if( defined( 'ICL_LANGUAGE_CODE' ) && 'all' === ICL_LANGUAGE_CODE ) {
			$defaultCode = self::getDefaultCode();

			if( $defaultCode ) {
				$uri = add_query_arg( [ 'lang' => $this->defaultCode ] );

				// use esc_url_raw()
				// @see https://make.wordpress.org/plugins/2015/04/20/fixing-add_query_arg-and-remove_query_arg-usage/
				wp_redirect( esc_url_raw( $uri ) );exit;
			}
		}
	}
}