<?php

/**
 * Class WPML_Media
 */
class WPML_Media implements IWPML_Action {
	private static $settings;
	private static $settings_option_key = '_wpml_media';
	private static $default_settings = array(
		'version'                  => false,
		'media_files_localization' => array(
			'posts'         => true,
			'custom_fields' => true,
			'strings'       => true
		),
		'wpml_media_2_3_migration' => true,
		'setup_run'                => false
	);

	public $languages;
	public $parents;
	public $unattached;
	/**
	 * @var wpdb
	 */
	private $wpdb;

	/**
	 * @var SitePress
	 */
	private $sitepress;

	private $languages_to_clear = array();

	/**
	 * @var WPML_Media_Menus_Factory
	 */
	private $menus_factory;

	/**
	 * WPML_Media constructor.
	 *
	 * @param SitePress $sitepress
	 * @param wpdb $wpdb
	 * @param WPML_Media_Menus_Factory $menus_factory
	 */
	public function __construct( SitePress $sitepress, wpdb $wpdb, WPML_Media_Menus_Factory $menus_factory ) {
		$this->sitepress     = $sitepress;
		$this->wpdb          = $wpdb;
		$this->menus_factory = $menus_factory;
	}

	public function add_hooks() {
		add_action( 'wpml_loaded', array( $this, 'loaded' ), 2 );
	}

	public static function has_settings() {
		return get_option( self::$settings_option_key );
	}

	public function loaded() {
		global $sitepress;
		if ( ! isset( $sitepress ) || ! $sitepress->get_setting( 'setup_complete' ) ) {
			return null;
		}

		$this->plugin_localization();

		if ( is_admin() ) {
			WPML_Media_Upgrade::run();
		}

		self::init_settings();

		global $sitepress_settings, $pagenow;

		$active_languages = $sitepress->get_active_languages();

		$this->languages = null;

		if ( $this->is_admin_or_xmlrpc() && ! $this->is_uploading_plugin_or_theme() ) {

			add_action( 'wpml_admin_menu_configure', array( $this, 'menu' ) );

			if ( 1 < count( $active_languages ) ) {

				if ( $pagenow == 'media-upload.php' ) {
					add_action( 'pre_get_posts', array( $this, 'filter_media_upload_items' ), 10, 1 );
				}

				if ( $pagenow == 'media.php' ) {
					add_action( 'admin_footer', array( $this, 'media_language_options' ) );
				}

				add_action( 'wp_ajax_wpml_media_scan_prepare', array( $this, 'batch_scan_prepare' ) );

				add_action( 'wp_ajax_find_posts', array( $this, 'find_posts_filter' ), 0 );
			}

		} else {
			if ( WPML_LANGUAGE_NEGOTIATION_TYPE_DOMAIN === (int) $sitepress_settings['language_negotiation_type'] ) {
				// Translate media url when in front-end and only when using custom domain
				add_filter( 'wp_get_attachment_url', array( $this, 'wp_get_attachment_url' ), 10, 2 );
			}
		}

		add_filter( 'WPML_filter_link', array( $this, 'filter_link' ), 10, 2 );
		add_filter( 'icl_ls_languages', array( $this, 'icl_ls_languages' ), 10, 1 );

		return null;
	}

	function is_admin_or_xmlrpc() {
		$is_admin  = is_admin();
		$is_xmlrpc = ( defined( 'XMLRPC_REQUEST' ) && XMLRPC_REQUEST );

		return $is_admin || $is_xmlrpc;
	}

	function is_uploading_plugin_or_theme() {
		global $action;

		return ( isset( $action ) && ( $action == 'upload-plugin' || $action == 'upload-theme' ) );
	}

	function plugin_localization() {
		load_plugin_textdomain( 'wpml-media', false, WPML_MEDIA_FOLDER . '/locale' );
	}

	/**
	 *    Needed by class init and by all static methods that use self::$settings
	 */
	public static function init_settings() {
		if ( ! self::$settings ) {
			self::$settings = get_option( self::$settings_option_key, array() );
		}

		self::$settings = array_merge(self::$default_settings, self::$settings);
	}

	public static function has_setup_run() {
		return self::get_setting( 'setup_run' );
	}

	public static function set_setup_run( $value = 1 ) {
		return self::update_setting( 'setup_run', $value );
	}

	public static function get_setting( $name, $default = false ) {
		self::init_settings();
		if ( ! isset( self::$settings[ $name ] ) || ! self::$settings[ $name ] ) {
			return $default;
		}

		return self::$settings[ $name ];
	}

	public static function update_setting( $name, $value ) {
		self::init_settings();
		self::$settings[ $name ] = $value;

		return update_option( self::$settings_option_key, self::$settings );
	}

	function batch_scan_prepare() {
		global $wpdb;

		$response = array();
		$wpdb->delete( $wpdb->postmeta, array( 'meta_key' => 'wpml_media_processed' ) );

		$response['message'] = __( 'Started...', 'wpml-media' );

		echo wp_json_encode( $response );
		exit;
	}

	static function is_valid_post_type( $post_type ) {
		global $wp_post_types;

		$post_types = array_keys( (array) $wp_post_types );

		return in_array( $post_type, $post_types );
	}

	function find_posts_filter() {
		add_action( 'pre_get_posts', array( $this, 'pre_get_posts' ) );
	}

	function pre_get_posts( $query ) {
		$query->query['suppress_filters']      = 0;
		$query->query_vars['suppress_filters'] = 0;
	}

	function media_language_options() {
		global $sitepress;
		$att_id       = filter_input( INPUT_GET, 'attachment_id', FILTER_SANITIZE_NUMBER_INT, FILTER_NULL_ON_FAILURE );
		$translations = $sitepress->get_element_translations( $att_id, 'post_attachment' );
		$current_lang = '';
		foreach ( $translations as $lang => $id ) {
			if ( $id == $att_id ) {
				$current_lang = $lang;
				unset( $translations[ $lang ] );
				break;
			}
		}

		$active_languages = icl_get_languages( 'orderby=id&order=asc&skip_missing=0' );
		$lang_links       = '';

		if ( $current_lang ) {

			$lang_links = '<strong>' . $active_languages[ $current_lang ]['native_name'] . '</strong>';

		}

		foreach ( $translations as $lang => $id ) {
			$lang_links .= ' | <a href="' . admin_url( 'media.php?attachment_id=' . $id . '&action=edit' ) . '">' . $active_languages[ $lang ]['native_name'] . '</a>';
		}


		echo '<div id="icl_lang_options" style="display:none">' . $lang_links . '</div>';
	}

	/**
	 * Synchronizes _wpml_media_* meta fields with all translations
	 *
	 * @param int $meta_id
	 * @param int $object_id
	 * @param string $meta_key
	 * @param string|mixed $meta_value
	 */
	function updated_postmeta( $meta_id, $object_id, $meta_key, $meta_value ) {
		if ( in_array( $meta_key, array( '_wpml_media_duplicate', '_wpml_media_featured' ) ) ) {
			global $sitepress;
			$el_type      = 'post_' . get_post_type( $object_id );
			$trid         = $sitepress->get_element_trid( $object_id, $el_type );
			$translations = $sitepress->get_element_translations( $trid, $el_type, true, true );
			foreach ( $translations as $translation ) {
				if ( $translation->element_id != $object_id ) {
					$t_meta_value = get_post_meta( $translation->element_id, $meta_key, true );
					if ( $t_meta_value != $meta_value ) {
						update_post_meta( $translation->element_id, $meta_key, $meta_value );
					}
				}
			}
		}
	}

	/**
	 *Add a filter to fix the links for attachments in the language switcher so
	 *they point to the corresponding pages in different languages.
	 */
	function filter_link( $url, $lang_info ) {
		return $url;
	}

	function wp_get_attachment_url( $url, $post_id ) {
		global $sitepress;

		return $sitepress->convert_url( $url );
	}

	function icl_ls_languages( $w_active_languages ) {
		static $doing_it = false;

		if ( is_attachment() && ! $doing_it ) {
			$doing_it = true;
			// Always include missing languages.
			$w_active_languages = icl_get_languages( 'skip_missing=0' );
			$doing_it           = false;
		}

		return $w_active_languages;
	}

	function get_post_metadata( $value, $object_id, $meta_key, $single ) {
		if ( $meta_key == '_thumbnail_id' ) {

			global $wpdb;

			$thumbnail_prepared = $wpdb->prepare( "SELECT meta_value FROM {$wpdb->postmeta} WHERE post_id = %d AND meta_key = %s", array(
				$object_id,
				$meta_key
			) );
			$thumbnail          = $wpdb->get_var( $thumbnail_prepared );

			if ( $thumbnail == null ) {
				// see if it's available in the original language.

				$post_type_prepared = $wpdb->prepare( "SELECT post_type FROM {$wpdb->posts} WHERE ID = %d", array( $object_id ) );
				$post_type          = $wpdb->get_var( $post_type_prepared );
				$trid_prepared      = $wpdb->prepare( "SELECT trid, source_language_code FROM {$wpdb->prefix}icl_translations WHERE element_id=%d AND element_type = %s", array(
					$object_id,
					'post_' . $post_type
				) );
				$trid               = $wpdb->get_row( $trid_prepared );
				if ( $trid ) {

					global $sitepress;

					$translations = $sitepress->get_element_translations( $trid->trid, 'post_' . $post_type );
					if ( isset( $translations[ $trid->source_language_code ] ) ) {
						$translation = $translations[ $trid->source_language_code ];
						// see if the original has a thumbnail.
						$thumbnail_prepared = $wpdb->prepare( "SELECT meta_value FROM {$wpdb->postmeta} WHERE post_id = %d AND meta_key = %s", array(
							$translation->element_id,
							$meta_key
						) );
						$thumbnail          = $wpdb->get_var( $thumbnail_prepared );
						if ( $thumbnail ) {
							$value = $thumbnail;
						}
					}
				}
			} else {
				$value = $thumbnail;
			}

		}

		return $value;
	}

	/**
	 * @param string $menu_id
	 */
	public function menu( $menu_id ) {
		if ( 'WPML' !== $menu_id ) {
			return;
		}

		$menu_label         = __( 'Media Translation', 'wpml-media' );
		$menu               = array();
		$menu['order']      = 600;
		$menu['page_title'] = $menu_label;
		$menu['menu_title'] = $menu_label;
		$menu['capability'] = 'edit_others_posts';
		$menu['menu_slug']  = 'wpml-media';
		$menu['function']   = array( $this, 'menu_content' );

		do_action( 'wpml_admin_menu_register_item', $menu );
	}

	public function menu_content() {
		$menus = $this->menus_factory->create();
		$menus->display();
	}

	/**
	 * @param $ids
	 * @param $target_language
	 *
	 * @return array|string
	 */
	public function translate_attachment_ids( $ids, $target_language ) {
		global $sitepress;
		$return_string = false;
		if ( ! is_array( $ids ) ) {
			$attachment_ids = explode( ',', $ids );
			$return_string  = true;
		}

		$translated_ids = array();
		if ( ! empty( $attachment_ids ) ) {
			foreach ( $attachment_ids as $attachment_id ) {
				//Fallback to the original ID
				$translated_id = $attachment_id;

				//Find the ID translation
				$trid = $sitepress->get_element_trid( $attachment_id, 'post_attachment' );
				if ( $trid ) {
					$id_translations = $sitepress->get_element_translations( $trid, 'post_attachment', false, true );
					foreach ( $id_translations as $language_code => $id_translation ) {
						if ( $language_code == $target_language ) {
							$translated_id = $id_translation->element_id;
							break;
						}
					}
				}

				$translated_ids[] = $translated_id;
			}
		}

		if ( $return_string ) {
			return implode( ',', $translated_ids );
		}

		return $translated_ids;

	}

	/**
	 * Update query for media-upload.php page.
	 *
	 * @param object $query WP_Query
	 */
	public function filter_media_upload_items( $query ) {
		$current_lang = $this->sitepress->get_current_language();
		$ids          = icl_cache_get( '_media_upload_attachments' . $current_lang );

		if ( false === $ids ) {
			$tbl      = $this->wpdb->prefix . 'icl_translations';
			$db_query = "
				SELECT posts.ID
				FROM {$this->wpdb->posts} as posts, $tbl as icl_translations
				WHERE posts.post_type = 'attachment'
				AND icl_translations.element_id = posts.ID
				AND icl_translations.language_code = %s
				";

			$posts = $this->wpdb->get_results( $this->wpdb->prepare( $db_query, $current_lang ) );
			$ids   = array();
			if ( ! empty( $posts ) ) {
				foreach ( $posts as $post ) {
					$ids[] = absint( $post->ID );
				}
			}

			icl_cache_set( '_media_upload_attachments' . $current_lang, $ids );
		}

		$query->set( 'post__in', $ids );
	}

}
