<?php

/**
 * The admin-specific functionality of the plugin.
 *
 * @link       https://flothemes.com/
 * @since      1.0.0
 *
 * @package    Flo_Flex_Builder
 * @subpackage Flo_Flex_Builder/admin
 */

/**
 * The admin-specific functionality of the plugin.
 *
 * Defines the plugin name, version, and two examples hooks for how to
 * enqueue the admin-specific stylesheet and JavaScript.
 *
 * @package    Flo_Flex_Builder
 * @subpackage Flo_Flex_Builder/admin
 * @author     Flothemes <alexb@flothemes.com>
 */
class Flo_Flex_Builder_Admin {

	/**
	 * The ID of this plugin.
	 *
	 * @since    1.0.0
	 * @access   private
	 * @var      string    $plugin_name    The ID of this plugin.
	 */
	private $plugin_name;

	/**
	 * The version of this plugin.
	 *
	 * @since    1.0.0
	 * @access   private
	 * @var      string    $version    The current version of this plugin.
	 */
	private $version;

	/**
	 * The option name where we will save a flag that tells us to enable/disable the local ACF json for this plugin.
	 * By default if the plugin is activated, the local json is set to this plugin and if we need to add new ACF fields in the theme, then we should disable local json for this plugin
	 * @since    1.0.0
	 * @access   private
	 * @var      string    $version    The local json option name.
	 */
	private $local_json_option_name;

	/**
	 * The option name for the global elements
	 */
	public static $global_elements_option_name = 'flex_global_elements';
	public static $global_flex_option_name = 'flex_global_block_options';

	/**
	 * Initialize the class and set its properties.
	 *
	 * @since    1.0.0
	 * @param      string    $plugin_name       The name of this plugin.
	 * @param      string    $version    The version of this plugin.
	 */
	public function __construct($plugin_name, $version) {

		$this->plugin_name = $plugin_name;
		$this->version = $version;
		$this->local_json_option_name = 'enable_' . $this->plugin_name . '_local_json';

		// $this->init_updater();

	}

	public function init_updater() {
		require_once 'updater/config.php';
	}

	/**
	 * Register the stylesheets for the admin area.
	 *
	 * @since    1.0.0
	 */
	public function enqueue_styles($hook_suffix) {

		/**
		 * This function is provided for demonstration purposes only.
		 *
		 * An instance of this class should be passed to the run() function
		 * defined in Flo_Flex_Builder_Loader as all of the hooks are defined
		 * in that particular class.
		 *
		 * The Flo_Flex_Builder_Loader will then create the relationship
		 * between the defined hooks and the functions defined in this
		 * class.
		 */

		$script_version = $this->version;

		if (defined('FLO_ENVIROMENT') && FLO_ENVIROMENT == 'DEV') {
			$script_version = mt_rand(0, 99999);
		}

		wp_enqueue_style($this->plugin_name, plugin_dir_url(dirname(__FILE__)) . 'dist/admin.css', [], $script_version, 'all');
		if ($hook_suffix == 'toplevel_page_flex-block-settings') {
			wp_enqueue_style($this->plugin_name . '-app', plugin_dir_url(dirname(__FILE__)) . 'dist/app.css', [], $script_version, 'all');
		}
	}

	/**
	 * Register the JavaScript for the admin area.
	 *
	 * @since    1.0.0
	 */
	public function enqueue_scripts($hook_suffix) {

		/**
		 * This function is provided for demonstration purposes only.
		 *
		 * An instance of this class should be passed to the run() function
		 * defined in Flo_Flex_Builder_Loader as all of the hooks are defined
		 * in that particular class.
		 *
		 * The Flo_Flex_Builder_Loader will then create the relationship
		 * between the defined hooks and the functions defined in this
		 * class.
		 */

		$script_version = $this->version;
		if (defined('FLO_ENVIROMENT') && FLO_ENVIROMENT == 'DEV') {
			$script_version = mt_rand(0, 99999);
		}

		wp_enqueue_script($this->plugin_name, plugin_dir_url(dirname(__FILE__)) . 'dist/admin.min.js', ['jquery'], $script_version, false);

		if (is_plugin_active('wordpress-seo/wp-seo.php') || class_exists('WPSEO_Premium')) {
			$path = plugin_dir_url(dirname(__FILE__)) . 'dist/yoastCompat.min.js';
			wp_enqueue_script('extend-content-analysis', $path, array('admin-bar'), mt_rand(0, 99999), true);
			wp_localize_script('extend-content-analysis', 'extendContentYoastScript', array('pluginsUrl' => plugin_dir_url(dirname(__FILE__))));
		}
	}



	/**
	 * Check for the plugin updates
	 *
	 * @since    1.0.0
	 */
	function flo_include_updater() {

		if (is_admin() && !version_compare(phpversion(), '5.3.0', '<')) {

			$plugin_data = get_plugin_data(plugin_dir_path(__DIR__) . 'flo-flex-builder.php');

			$plugin_version = $plugin_data['Version'];

			$flo_plugin_remote_path = 'http://flothemes.com/recommended_plugins/plugin-updates.php';

			$flo_plugin_slug = plugin_basename(plugin_dir_path(__DIR__) . 'flo-flex-builder.php');

			$product_name = 'flo-flex-builder';

			$the_plugin = 'flo-flex-builder/flo-flex-builder.php';

			require_once('class-flo-plugin-auto-update.php');

			new flo_plugin_auto_update($plugin_version, $flo_plugin_remote_path, $flo_plugin_slug, $product_name, $the_plugin);
		}
	}

	/**
	 *
	 * Define the folder where the json files will be saved
	 *
	 */
	public function set_json_save_path($path) {
		if ($this->local_json_enabled()) { // check if local json for this plugin is enabled
			// update path
			$path = plugin_dir_path(__FILE__) . '../' . 'plugin_json';
		}

		return $path;
	}

	public function add_json_load_path($paths) {

		if ($this->local_json_enabled()) { // check if local json for this plugin is enabled
			$paths[] = plugin_dir_path(__FILE__) . '../' . 'plugin_json';
		}

		return $paths;
	}

	public static function flex_fetch_data_for_yoast() {
		$id = json_decode($_POST['postId']);
		$content = apply_filters('the_content', $content);
		$page_object = get_page($id);
		$content = $page_object->post_content;
		$url = get_the_permalink($id);
		echo json_encode([
			'url' => $url,
			'content' => $content
		]);
		die();
	}

	public static function get_script_src_by_handle($handle) {
		global $wp_scripts;
		if (in_array($handle, $wp_scripts->queue)) {
			return $wp_scripts->registered[$handle]->src;
		}
	}

	/**
	 * Hook for rendering elements from serverside
	 */
	public static function render_server_element() {

		$element_type = $_POST['elementType'];

		if ($element_type === 'floform' && $_POST['elementData']) {

			$shortcode = stripslashes($_POST['elementData']);

			if (strpos($shortcode, 'floform') > 0) {

				// Find any integer value from string (ANY!!!)
				preg_match('!\d+!', $shortcode, $matches);

				if ($matches[0] && (int)$matches[0]) {
					$form_id = (int)$matches[0];

					$forms_options = get_option('flo_forms_options', '{}');

					$flo_form_schema = get_post_meta($form_id, 'flo_form_schema', true);
					$flo_form_model = get_post_meta($form_id, 'flo_form_model', true);
					$flo_form_settings = get_post_meta($form_id,  'flo_form_settings', true);

					if (isset($flo_form_settings['styling'])) {
						$form_styling = $flo_form_settings['styling'];
					} else {
						$form_styling = '{}';
					}

					echo json_encode([
						'success' => true,
						'content' => do_shortcode(stripslashes($_POST['elementData'])),
						'injectedVars' => array(
							'forms_options' => $forms_options,
							'flo_form_settings_' . $form_id => $flo_form_settings,
							'form_styling_' . $form_id => $form_styling,
							'flo_form_schema_' . $form_id => $flo_form_schema,
							'flo_form_model_' . $form_id => $flo_form_model,
						),
						'scripts' => class_exists('Flo_Forms_Public') && method_exists('Flo_Forms_Public', 'getFiles') ? Flo_Forms_Public::getFiles() : false
					]);
					die();
				}
			}

			echo json_encode([
				'success' => true,
				'content' => do_shortcode(stripslashes($_POST['elementData'])),
			]);
		} else if ($element_type === 'menu') {
			ob_start();
			ob_clean();

			wp_nav_menu(array("menu" => $_POST['elementData']));

			$the_menu = ob_get_clean();


			echo json_encode([
				'success' => true,
				'content' => $the_menu
			]);
		} else {
			echo json_encode([
				'success' => false,
				'content' => ''
			]);
		}
		die();
	}

	/**	
	 * TODO: ALEX LEU COMMENT IN HERE
	 */
	public static function get_menu_list() {
		echo json_encode([
			'success' => true,
			'list' => wp_get_nav_menus(),
		]);

		die();
	}

	/**	
	 * Will merge all global elements pushed from JS 
	 * in a "flex_global_elements" option
	 */
	public static function save_global_elements() {

		if (!isset($_POST['global_elements'])) {
			echo json_encode([
				'success' => false,
			]);
			die();
		}
		$global_elements = json_decode(stripslashes($_POST['global_elements']), true);

		$old_elements = get_option(self::$global_elements_option_name, array());
		if (!is_array($old_elements)) $old_elements = array();

		$new_elements = array_merge($old_elements, $global_elements);
		update_option(self::$global_elements_option_name, $new_elements);

		echo json_encode([
			'success' => true,
			'option_value' => $new_elements,
			'option_name' => self::$global_elements_option_name,
			'is_in_window' => true
		]);
		die();
	}

	/**
	 * Returns the array with all globally saved elements
	 */
	public static function get_global_elements() {
		$global_elements = get_option(self::$global_elements_option_name, array());

		return is_array($global_elements) ? $global_elements : array();
	}

	/**	
	 * AJAX req - saves an option to DB. 
	 * option_value - the value to be saved
	 * option_name - the option name
	 * should_be_merged - TRUE if option_value should be merged in option_name, FALSE if option should be overwritten
	 * @return void
	 */
	public static function save_flex_option() {
		if (!isset($_POST['action']) || $_POST['action'] !== 'save_flex_option') {
			echo json_encode([
				'success' => false,
			]);
			die();
		}
		$option_value = json_decode(stripslashes($_POST['option_value']), true);
		$option_name = $_POST['option_name'];

		if (boolval($_POST['should_be_merged'])) {
			$old_options = get_option($option_name, array());
			if (!is_array($old_options)) $old_options = array();
			$new_options = array_merge($old_options, $option_value);
			update_option($option_name, $new_options);
		} else {
			update_option($option_name, $option_value);
			$new_options = $option_value;
		}

		echo json_encode([
			'success' => true,
			'option_value' => $new_options,
			'option_name' => $option_name,
			'is_in_window' => boolval($_POST['is_in_window'])
		]);
		die();
	}

	/**
	 *
	 * Append the layout blocks provided by this plugin to the theme layout blocks
	 * This method is called by an ACF action 'acf/load_field/name=layout'
	 *
	 * @param object - $field -> the Layout field
	 *
	 */
	public function append_blocks($field) {

		// main layout from theme
		$parentLayout = $field;

		if (isset($field['layouts'])) {
			$parentLayoutFields = $field['layouts'];
		} else {
			$parentLayoutFields = [];
		}


		// child layout from plugin
		// make sure to use the correct field key
		// for each plugin it must be unique
		$childLayout = acf_get_field('field_5bb35d7e0ce87');
		$childLayoutFields = $childLayout['layouts'];

		if (!is_array($childLayoutFields)) {
			$childLayoutFields = [];
			//echo sprintf('%s Warning: the %s plugin blocks can not be loaded for soame reason. Check Admin class - append_blocks() method.%s', '<span style="color: red;">', $this->plugin_name, '</span>');
		}

		// combine the two above back in the main layout
		$combinedLayout = array_merge($parentLayoutFields, $childLayoutFields);
		$field['layouts'] = $combinedLayout;

		return $field;
	}


	/**
	 *
	 * Enable or disable the local json being saved inside the current plugin files using a GET param
	 *
	 */
	public function enable_disable_local_acf_json() {

		// pass this GET param to disable the local json for the current plugin
		// the plugin folder name is used as a GET param in order to know exactly for which plugin to
		// change the local json settings when there are several Flo Blocks plugins activated
		// i.e. &disable_local_json=flo-flex-builder
		if (isset($_GET['disable_local_json']) && $_GET['disable_local_json'] == $this->plugin_name) {
			update_option($this->local_json_option_name, 0, $autoload = false);
		}

		// pass this GET param to enable the local json back
		if (isset($_GET['enable_local_json']) && $_GET['enable_local_json'] == $this->plugin_name) {
			delete_option($this->local_json_option_name);
		}
	}

	/**
	 *
	 * Check wheather the local ACF json files are disabled for this plugin
	 * @return bool - true or false depending if
	 */
	public function local_json_enabled() {

		if (get_option($this->local_json_option_name, $default = 1) === "0") {
			// the option name is like 'enable_{plugin_name}_local_json'
			// if this option exists, and equals 0, then that means the loca json is disabled
			return false;
		}

		return true;
	}

	/**
	 * Get theme specific global styles
	 * @return array - containing theme paddings and html font size
	 */
	public function flex_get_theme_data() {

		$theme_data_arr = null;
		$theme_data_arr = apply_filters('flex_theme_padding', $theme_data_arr);
		if ($theme_data_arr === null) {
			$theme_list = [
				'cannes' => [
					'html_font_size' => 1.25,
					'block_padding' => 6.25
				],
				'crowd2' => [
					'html_font_size' => 1.21,
					'block_padding' => 3.4375
				],
				'cube' => [
					'html_font_size' => 1.15,
					'block_padding' => 9.375
				],
				'evora' => [
					'html_font_size' => 1.25,
					'block_padding' => 6.25
				],
				'fiji2' => [
					'html_font_size' => 1.25,
					'block_padding' => 9.0625
				],
				'kyoto' => [
					'html_font_size' => 1.21,
					'block_padding' => 4.46875
				],
				'leon' => [
					'html_font_size' => 1.25,
					'block_padding' => 4.375
				],
				'lovely2' => [
					'html_font_size' => 1.25,
					'block_padding' => 9.0625
				],
				'milea' => [
					'html_font_size' => 1.25,
					'block_padding' => 3.75
				],
				'narcisse' => [
					'html_font_size' => 1.25,
					'block_padding' => 6.25
				],
				'osaka' => [
					'html_font_size' => 1.25,
					'block_padding' => 6.25
				],
				'porto2' => [
					'html_font_size' => 1.11111,
					'block_padding' => 6.375
				],
				'rosemary2' => [
					'html_font_size' => 1.25,
					'block_padding' => 3.75
				],
				'trento' => [
					'html_font_size' => 1.25,
					'block_padding' => 4.375
				]
			];

			$current_theme = flex_get_theme();

			if (isset($theme_list[$current_theme])) {
				$theme_data_arr = $theme_list[$current_theme];
			} else {
				$theme_data_arr = [
					'html_font_size' => 1.25,
					'block_padding' => 3.75
				];
			}
		}

		return $theme_data_arr;
	}

	public function flex_set_theme_data() {
		if (!get_transient('flex_theme_data_transient')) {
			$theme_data = $this->flex_get_theme_data();
			// store as 24 hours transient
			set_transient('flex_theme_data_transient', json_encode($theme_data), 60 * 60 * 24);
		}
	}

	public function flex_reset_theme_data() {
		delete_transient('flex_theme_data_transient');
	}

	public function flex_save_base64_image($base64_image_string, $output_file_name_without_extension) {
		global $wp_filesystem;
		if ($wp_filesystem === null) {
			WP_Filesystem();
		}

		// get uploads dir
		$upload_dir = wp_upload_dir();
		$upload_basedir = $upload_dir['basedir'];
		$upload_baseurl = $upload_dir['baseurl'];

		$screens_dir = $upload_basedir . '/flex_screens/';

		// if folder that will hold the screens does not exist yet, create it
		if (!$wp_filesystem->is_dir($screens_dir)) {
			$wp_filesystem->mkdir($screens_dir);
		}

		// folder exists, push image to it
		$file = false;
		if ($wp_filesystem->is_dir($screens_dir)) {

			$splited = explode(',', substr($base64_image_string, 5), 2);
			$data64 = $splited[1];

			$mime = $splited[0];
			$mime_split_without_base64 = explode(';', $mime, 2);
			$mime_split = explode('/', $mime_split_without_base64[0], 2);
			$ext = $mime_split[1];

			$filePath = $screens_dir . $output_file_name_without_extension . ".png";
			$fileCallback = $wp_filesystem->put_contents(
				$filePath,
				base64_decode($data64),
				FS_CHMOD_FILE // predefined mode settings for WP files
			);

			$publicFilePath = str_replace($upload_basedir, $upload_baseurl, $filePath);
			if ($fileCallback) $file = $publicFilePath;
		}

		return $file;
	}

	public function flex_upload_screen() {
		$img = $_POST['main_image'];
		$filename = $_POST['screen_name'];
		$uploaded_img = $this->flex_save_base64_image($img, $filename);
		echo $uploaded_img;
		exit();
	}

	public function flex_delete_screen() {
		global $wp_filesystem;

		$img = $_POST['main_image'];

		$upload_dir = wp_upload_dir();
		$upload_basedir = $upload_dir['basedir'];
		$upload_baseurl = $upload_dir['baseurl'];

		$img_basedir = str_replace($upload_baseurl, $upload_basedir, $img);

		if (file_exists($img_basedir)) {
			$wp_filesystem->delete($img_basedir, true);
			echo 'success';
		}

		exit();
	}

	private function fetch_sub_data() {
		$order_data = null;
		$key = get_option('flotheme_theme_key');
		if ($key) {
			if (strpos($key, '#') !== false) {
				$key = str_replace('#', '', $key);
			}
			if (strpos($key, '-') !== false) {
				$order_nr = explode('-', $key);
				$order_id = $order_nr[0];
				$api_url = "https://flothemes.com/wp-json/flo/v1/subscription_order?order_number=$order_id";
				$order = wp_remote_get($api_url);
				if (!is_wp_error($order) && isset($order['body'])) {
					$order_data = $order['body'];
				}
			}
		}
		return $order_data;
	}

	private function get_order_data() {
		$order_data = get_transient('flextheme_order_data');

		if (!$order_data) {
			$order_data = $this->fetch_sub_data();
			set_transient('flextheme_order_data', $order_data, 60 * 60 * 24 * 7); // 1 week
		}

		return $order_data;
	}

	private function get_update_response() {
		$response = get_transient('flothemes_updates');
		// handle error
		if (is_wp_error($response)) {
			$status = ['code' => 401];
		} else {
			// breaks on php versions below 7
			// $status = $response['response'] ?? null;

			if ($response && isset($response['response'])) {
				$status = $response['response'];
			} else {
				$status = null;
			}
		}
		return $status;
	}

	// for ajax, force refresh subscription
	public function refetch_order_data() {
		$order_data = $this->fetch_sub_data();
		set_transient('flextheme_order_data', $order_data, 60 * 60 * 24 * 7); // 1 week

		$status = $this->get_update_response();

		echo json_encode(["response" => $status, "order_data" => $order_data]);
		exit();
	}

	// check if current theme is eligible for flex to use
	public function send_sub_data() {
		$theme_name = flex_get_theme();

		$activated = get_option("flo_subscription_template_$theme_name");
		// $sub_data = ["activated" => $activated];
		$sub_data = ["activated" => false];

		if ($activated) {
			$status = $this->get_update_response();
			$sub_data['status'] = $status;

			$orderData = $this->get_order_data();
			if ($orderData) {
				$sub_data['orderData'] = $orderData;
			}
		}

		wp_localize_script('flo-flex-builder', 'flex_sub_data', $sub_data);
	}

	public function reset_order_data_on_order_update($new_value, $old_value) {
		delete_transient('flextheme_order_data');
		return $new_value;
	}

	public function reset_order_data() {
		delete_transient('flextheme_order_data');
	}

	public function initAdminData() {
		$adminData = new Flex_Builder_Data();
		$adminData->localizeData();
	}

	//method load all metaboxes in folder metaboxes
	public function enable_metaboxes() {
		require_once plugin_dir_path(__FILE__) . '/metaboxes/autoloader.php';
		Flex_Autoloader::load();
	}
}

require_once(__DIR__ . '/save-blocks.php');

add_filter('Yoast\WP\ACF\blacklist_name', function ($blacklist_name) {
	$skip_names = [
		'flex_block_title',
		'screenshot_url',
		'flex__block-custom-id',
		'flex__block-custom-class',
		'flo-block__id',
		'flo-block__classes',
		'contact_form_shortcode',
		'mailchimp_code'
	];
	foreach ($skip_names as $name) {
		$blacklist_name->add($name);
	}
	return $blacklist_name;
});
add_filter('Yoast\WP\ACF\blacklist_type', function ($blacklist_type) {
	$skip_types = [
		'taxonomy',
		'nav_menu',
		'clone',
		'flo_flexible_content',
		'video_tutorial',
		'flo_template_selector',
		'flo_flex_builder',
		'number_slider',
		'acf_scheme_color_picker',
		'font_style_select'
	];
	foreach ($skip_types as $type) {
		$blacklist_type->add($type);
	}
	return $blacklist_type;
});
