<?php

/**
 * Ajax callbacks
 *
 * @link       https://geotargetingwp.com/geotargeting-pro
 * @since      1.6
 *
 * @package    GeoTarget
 * @subpackage GeoTarget/includes
 * @author     Your Name <email@example.com>
 */
class GeotWP_Ajax {
	/**
	 * $_POST data sent on ajax request
	 * @var Array
	 */
	protected $data;

	/**
	 * Plugin functions
	 *
	 * @since    1.6
	 * @access   private
	 * @var      object    Plugin functions
	 */
	private $functions;

	/**
	 * Initialize the class and set its properties.
	 *
	 * @since    1.6
	 * @var      string $GeoTarget The name of this plugin.
	 * @var      string $version The version of this plugin.
	 */
	public function __construct() {
		add_action( 'wp_ajax_geot_ajax', [ $this, 'geot_ajax' ] );
		add_action( 'wp_ajax_nopriv_geot_ajax', [ $this, 'geot_ajax' ] );

		add_action( 'wp_ajax_geot/field_group/render_rules', [ 'GeotWP_Helper', 'ajax_render_rules' ] );
		add_action( 'wp_ajax_geot/field_group/render_operator', [ 'GeotWP_Helper', 'ajax_render_operator' ] );
	}

	/**
	 * Main function that execute all shortcodes
	 * put the returned data into a array and send the ajax response
	 * @return string
	 */
	public function geot_ajax() {

		$geots      = $posts = [];
		$debug = $redirect = $blocker = "";
		$posts      = $this->get_geotargeted_posts();
		$this->data = $_POST;

		if ( isset( $this->data['geot_redirects'] ) && $this->data['geot_redirects'] == 1 ) {
			$redirect = $this->geo_redirects();
		}

		if ( isset( $this->data['geot_blockers'] ) && $this->data['geot_blockers'] == 1 ) {
			$blocker = $this->geo_blockers();
		}


		if ( isset( $this->data['geots'] ) ) {
			foreach ( $this->data['geots'] as $id => $geot ) {
				if ( method_exists( $this, $geot['action'] ) ) {
					$geots[] = [
						'id'     => $id,
						'action' => $geot['action'],
						'value'  => $this->{$geot['action']}( $geot ),
					];
				}
			}
			// only call debug info if we ran any geo action before to save requests
			$debug = $this->getDebugInfo();
		}

		echo json_encode( [ 'success'  => 1,
		                    'data'     => $geots,
		                    'posts'    => $posts,
		                    'redirect' => $redirect,
		                    'blocker'  => $blocker,
		                    'debug'    => $debug,
		] );
		die();
	}

	/**
	 * Get all post that are geotargeted
	 *
	 * @return array|void
	 */
	private function get_geotargeted_posts() {
		global $wpdb;

		$posts_to_exclude = [];
		$content_to_hide  = [];

		// let users cancel the removal of posts
		// for example they can check if is_search() and show the post in search results
		if ( apply_filters( 'geot/posts_where', false, $this->data ) ) {
			return [
				'remove' => $posts_to_exclude,
				'hide'   => $content_to_hide,
			];
		};

		// by default we get all posts in case a widget or similar it's used so they are removed
		// but add filter to give user the opportunity to remove just one post like for example just current page by passint this->data['pid'] if this->data['is_singular']
		// this will make ajax mode save requests but won't be much efficient
		$geot_posts = GeotWP_Helper::get_geotarget_posts( apply_filters( 'geot/get_geotargeted_posts_pass_id', null, $this->data ) );

		if ( $geot_posts ) {
			foreach ( $geot_posts as $p ) {
				$options = unserialize( $p->geot_options );
				$target  = GeotWP_Helper::user_is_targeted( $options, $p->ID );
				if ( $target ) {
					if ( ! isset( $options['geot_remove_post'] ) || '1' != $options['geot_remove_post'] ) {
						$content_to_hide[] = [
							'id'  => $p->ID,
							'msg' => apply_filters( 'geot/forbidden_text', $options['forbidden_text'], false, $p ),
						];
					} else {
						$posts_to_exclude[] = $p->ID;
					}
				}
			}
		}

		return [
			'remove' => $posts_to_exclude,
			'hide'   => $content_to_hide,
		];
	}

	/**
	 * Print geot Redirect
	 *
	 * @param $geot
	 *
	 * @return string
	 */
	private function geo_redirects() {
		$GeoRedirect = new GeotWP_R_Public();

		return $GeoRedirect->handle_ajax_redirects();
	}

	/**
	 * Print geot Blocks
	 *
	 * @param $geot
	 *
	 * @return string
	 */
	private function geo_blockers() {
		$GeoBlocker = new GeotWP_Bl_Public();

		return $GeoBlocker->handle_ajax_blockers();
	}

	/**
	 * Grab debug info to print in footer
	 * @return string|void
	 */
	private function getDebugInfo() {
		return '<!--' . geot_debug_data() . '-->';
	}

	/**
	 * Get user country name
	 *
	 * @param $geot
	 *
	 * @return string
	 */
	private function country_name( $geot ) {
		if ( ! isset( $geot['locale'] ) ) {
			$geot['locale'] = 'en';
		}
		$name = geot_country_name( $geot['locale'] );

		if ( ! empty( $name ) ) {
			return apply_filters( 'geot/shortcodes/country_name', $name );
		}

		return apply_filters( 'geot/shortcodes/country_name_default', $geot['default'] );

	}

	/**
	 * Get user city name
	 *
	 * @param $geot
	 *
	 * @return string
	 */
	private function city_name( $geot ) {
		if ( ! isset( $geot['locale'] ) ) {
			$geot['locale'] = 'en';
		}
		$name = geot_city_name( $geot['locale'] );

		if ( ! empty( $name ) ) {
			return apply_filters( 'geot/shortcodes/city_name', $name );
		}

		return apply_filters( 'geot/shortcodes/city_name_default', $geot['default'] );

	}

	/**
	 * Get user state name
	 *
	 * @param $geot
	 *
	 * @return string
	 */
	private function state_name( $geot ) {
		if ( ! isset( $geot['locale'] ) ) {
			$geot['locale'] = 'en';
		}
		$name = geot_state_name( $geot['locale'] );

		if ( ! empty( $name ) ) {
			return apply_filters( 'geot/shortcodes/state_name', $name );
		}

		return apply_filters( 'geot/shortcodes/state_name_default', $geot['default'] );

	}

	/**
	 * Get user continent name
	 *
	 * @param $geot
	 *
	 * @return string
	 */
	private function continent_name( $geot ) {
		if ( ! isset( $geot['locale'] ) ) {
			$geot['locale'] = 'en';
		}
		$name = geot_continent( $geot['locale'] );

		if ( ! empty( $name ) ) {
			return apply_filters( 'geot/shortcodes/continent_name', $name );
		}

		return apply_filters( 'geot/shortcodes/continent_name_default', $geot['default'] );

	}

	/**
	 * Get user state code
	 *
	 * @param $geot
	 *
	 * @return string
	 */
	private function state_code( $geot ) {

		$code = geot_state_code();

		return ! empty( $code ) ? $code : $geot['default'];

	}

	/**
	 * Get user zip code
	 *
	 * @param $geot
	 *
	 * @return string
	 */
	private function zip( $geot ) {

		$code = geot_zip();

		return ! empty( $code ) ? $code : $geot['default'];
	}

	/**
	 * Get user timezone
	 *
	 * @param $geot
	 *
	 * @return string
	 */
	private function time_zone( $geot ) {

		$code = geot_time_zone();

		return ! empty( $code ) ? $code : $geot['default'];
	}

	/**
	 * Get user latitude
	 *
	 * @param $geot
	 *
	 * @return string
	 */
	private function latitude( $geot ) {

		$code = geot_lat();

		return ! empty( $code ) ? $code : $geot['default'];
	}

	/**
	 * Get user longitude
	 *
	 * @param $geot
	 *
	 * @return string
	 */
	private function longitude( $geot ) {

		$code = geot_lng();

		return ! empty( $code ) ? $code : $geot['default'];
	}

	/**
	 * Get user current regions
	 *
	 * @param $geot
	 *
	 * @return string
	 */
	private function region( $geot ) {

		$regions = geot_user_country_region( $geot['default'] );

		if ( is_array( $regions ) ) {
			return implode( ', ', $regions );
		}

		return $regions;

	}

	/**
	 * Get user country code
	 *
	 * @param $geot
	 *
	 * @return string
	 */
	private function country_code( $geot ) {

		$code = geot_country_code();

		return ! empty( $code ) ? $code : $geot['default'];

	}

	/**
	 * Filter function for countries
	 *
	 * @param $geot
	 *
	 * @return boolean
	 */
	private function country_filter( $geot ) {

		if ( geot_target( $geot['filter'], $geot['region'], $geot['ex_filter'], $geot['ex_region'] ) ) {
			return true;
		}

		return false;
	}

	/**
	 * Filter function for cities
	 *
	 * @param $geot
	 *
	 * @return boolean
	 */
	private function city_filter( $geot ) {

		if ( geot_target_city( $geot['filter'], $geot['region'], $geot['ex_filter'], $geot['ex_region'] ) ) {
			return true;
		}

		return false;
	}

	/**
	 * Filter function for states
	 *
	 * @param $geot
	 *
	 * @return boolean
	 */
	private function state_filter( $geot ) {

		if ( geot_target_state( $geot['filter'], $geot['ex_filter'] ) ) {
			return true;
		}

		return false;
	}

	/**
	 * Filter function for zip
	 *
	 * @param $geot
	 *
	 * @return boolean
	 */
	private function zip_filter( $geot ) {

		if ( geot_target_zip( $geot['filter'], $geot['ex_filter'] ) ) {
			return true;
		}

		return false;
	}

	/**
	 * Filter function for menus
	 *
	 * @param $geot
	 *
	 * @return boolean
	 */
	private function menu_filter( $geot ) {

		$target = unserialize( base64_decode( $geot['filter'] ) );

		if ( GeotWP_Helper::user_is_targeted( $target, $geot['ex_filter'] ) ) {
			return true;
		}

		return false;
	}

	/**
	 * Print geot flag
	 *
	 * @param $geot
	 *
	 * @return string
	 */
	private function geo_flag( $geot ) {
		$country_code = ! empty( $geot['filter'] ) ? $geot['filter'] : geot_country_code();

		$squared = $geot['default'] ?: '';
		$size    = $geot['region'] ?: '30px';
		$html    = isset( $geot['html_tag'] ) ? esc_attr( $geot['html_tag'] ) : 'span';

		return '<' . $html . ' style="font-size:' . esc_attr( $size ) . '" class="flag-icon flag-icon-' . strtolower( esc_attr( $country_code ) ) . ' ' . $squared . '"></' . $html . '>';

	}
}
