<?php

namespace Blocksy;

class DemoInstall {
	protected $ajax_actions = [
		'blocksy_demo_export',
		'blocksy_demo_get_export_data',

		'blocksy_demo_list',
		'blocksy_demo_install_child_theme',
		'blocksy_demo_activate_plugins',
		'blocksy_demo_fake_step',
		'blocksy_demo_erase_content',
		'blocksy_demo_install_widgets',
		'blocksy_demo_install_options',
		'blocksy_demo_install_content',
		'blocksy_demo_register_current_demo',
		'blocksy_demo_deregister_current_demo',
		'blocksy_demo_deactivate_plugins',
		'blocksy_demo_install_finish',

		// 'blocksy_extension_activate',
		// 'blocksy_extension_deactivate',
	];

	public function has_mock() {
		return true;
	}

	public function __construct() {
		$this->attach_ajax_actions();

		add_filter(
			'blocksy_dashboard_localizations',
			function ($d) {
				$d['has_demo_install'] = apply_filters(
					'blocksy_ext_demo_install_enabled',
					'yes'
				);

				return $d;
			}
		);

		// add_filter( 'woocommerce_enable_setup_wizard', '__return_false' );
		// add_filter( 'woocommerce_show_admin_notice', '__return_false' );
		// add_filter( 'woocommerce_prevent_automatic_wizard_redirect', '__return_false' );
	}

	public function get_demo_remote_url($args = []) {
		$endpoint = 'https://demo.creativethemes.com/';
		// $endpoint = 'http://localhost:3008/';
		return $endpoint . '?' . http_build_query($args);
	}

	public function blocksy_demo_install_child_theme() {
		$this->check_nonce();

		$m = new DemoInstallChildThemeInstaller();
		$m->import();
	}

	public function blocksy_demo_erase_content() {
		$this->check_nonce();
		$plugins = new DemoInstallContentEraser();
		$plugins->import();
	}

	public function blocksy_demo_install_widgets() {
		$this->check_nonce();
		$plugins = new DemoInstallWidgetsInstaller();
		$plugins->import();
	}

	public function blocksy_demo_install_options() {
		$this->check_nonce();

		$plugins = new DemoInstallOptionsInstaller();
		$plugins->import();
	}

	public function blocksy_demo_install_content() {
		$this->check_nonce();

		$plugins = new DemoInstallContentInstaller();
		$plugins->import();
	}

	public function blocksy_demo_activate_plugins() {
		$this->check_nonce();
		$plugins = new DemoInstallPluginsInstaller();
		$plugins->import();
	}

	public function blocksy_demo_fake_step() {
		$this->check_nonce();
		$plugins = new DemoInstallFakeContentEraser();
		$plugins->import();
	}

	public function blocksy_demo_register_current_demo() {
		$this->check_nonce();

		$this->start_streaming();

		if (! isset($_REQUEST['demo_name']) || !$_REQUEST['demo_name']) {
			Plugin::instance()->demo->emit_sse_message([
				'action' => 'complete',
				'error' => 'No demo name passed.',
			]);

			exit;
		}

		$demo_name = explode(':', $_REQUEST['demo_name']);

		if (! isset($demo_name[1])) {
			$demo_name[1] = '';
		}

		$demo = $demo_name[0];
		$builder = $demo_name[1];

		$this->set_current_demo($demo . ':' . $builder);

		Plugin::instance()->demo->emit_sse_message([
			'action' => 'complete',
			'error' => false
		]);

		exit;
	}

	public function blocksy_demo_deregister_current_demo() {
		$this->check_nonce();

		$this->start_streaming();

		update_option('blocksy_ext_demos_current_demo', null);

		Plugin::instance()->demo->emit_sse_message([
			'action' => 'complete',
			'error' => false
		]);

		exit;
	}

	public function blocksy_demo_deactivate_plugins() {
		$this->check_nonce();

		$plugins = new DemoInstallPluginsUninstaller();
		$plugins->import();
	}

	public function blocksy_demo_install_finish() {
		$this->check_nonce();

		$finish = new DemoInstallFinalActions();
		$finish->import();
	}

	public function get_current_demo() {
		return get_option('blocksy_ext_demos_current_demo', null);
	}

	public function set_current_demo($demo) {
		update_option('blocksy_ext_demos_current_demo', [
			'demo' => $demo
		]);
	}

	public function fetch_single_demo($args = []) {
		$args = wp_parse_args(
			$args,
			[
				'demo' => $args['demo'],
				'builder' => '',
				'field' => ''
			]
		);

		$request = wp_remote_get(
			$this->get_demo_remote_url([
				'route' => 'get_single',
				'demo' => $args['demo'] . ':' . $args['builder'],
				'field' => $args['field']
			]),
			[
				'sslverify' => false
			]
		);

		if (is_wp_error($request)) {
			return false;
		}

		$body = wp_remote_retrieve_body( $request );

		$body = json_decode($body, true);

		if (! $body) {
			return false;
		}

		return $body;
	}

	public function fetch_all_demos() {
		$request = wp_remote_get(
			$this->get_demo_remote_url([
				'route' => 'get_all'
			]),
			['sslverify' => false]
		);

		if (is_wp_error($request)) {
			return $request;
		}

		if (wp_remote_retrieve_response_code($request) !== 200) {
			return new \WP_Error(
				'demo_fetch_failed',
				'Failed to fetch demos with status code ' . wp_remote_retrieve_response_code($request)
			);
		}

		$body = wp_remote_retrieve_body($request);

		$body = json_decode($body, true);

		if (! $body) {
			return false;
		}

		$data = get_plugin_data(BLOCKSY__FILE__);

		$result = [];

		foreach ($body as $single_demo) {
			if (! isset($single_demo['required_companion_version'])) {
				$result[] = $single_demo;
				continue;
			}

			if (version_compare(
				$data['Version'],
				$single_demo['required_companion_version'],
				'>='
			)) {
				$result[] = $single_demo;
			}
		}

		return $result;
	}

	public function blocksy_demo_list() {
		$this->check_nonce();

		$demos = $this->fetch_all_demos();

		if (! $demos || is_wp_error($demos)) {
			wp_send_json_error([
				'demos' => [],
				'demo_error' => is_wp_error($demos) ? $demos->get_error_message() : ''
			]);
		}

		$plugins = [];

		foreach ($demos as $demo_index => $demo) {
			foreach ($demo['plugins'] as $plugin) {
				if (! isset($plugins[$plugin])) {
					$plugins[$plugin] = false;
				}
			}

			if ($demo_index === 0) {
				// $demos[0]['is_pro'] = true;
			}
		}

		foreach ($plugins as $plugin_name => $status) {
			$plugins_manager = $this->get_plugins_manager();

			$path = $plugins_manager->is_plugin_installed( $plugin_name );

			if ($path) {
				if ($plugins_manager->is_plugin_active($path)) {
					$plugins[$plugin_name] = true;
				}
			}
		}

		$has_demo_error = false;

		if (! extension_loaded('xml') && ! extension_loaded('simplexml')) {
			$has_demo_error = __("Your PHP installation doesn't have support for XML. Please install the <i>xml</i> or <i>simplexml</i> PHP extension in order to be able to install starter sites. You might need to contact your hosting provider to assist you in doing so.", 'blocksy-companion');
		}

		wp_send_json_success([
			'demos' => $demos,
			'active_plugins' => $plugins,
			'current_installed_demo' => $this->get_current_demo(),
			'demo_error' => $has_demo_error
		]);
	}

	public function blocksy_demo_export() {
		$this->check_nonce();

		if (! current_user_can('edit_theme_options')) {
			wp_send_json_error();
		}

		global $wp_customize;

		$demoId = sanitize_text_field($_REQUEST['demoId']);
		$builder = sanitize_text_field($_REQUEST['builder']);
		$plugins = sanitize_text_field($_REQUEST['plugins']);

		$plugins = explode(',', preg_replace('/\s+/', '', $plugins));

		$options_data = new DemoInstallOptionsExport();

		$widgets_data = new DemoInstallWidgetsExport();
		$widgets_data = $widgets_data->export();

		add_filter(
			'export_wp_all_post_types',
			function ($post_types) {
				$post_types['wpforms'] = 'wpforms';
				return $post_types;
			}
		);

		$content_data = new DemoInstallContentExport();
		$content_data = $content_data->export();

		$demo_data = [
			'options' => $options_data->export(),
			'widgets' => $widgets_data,
			'content' => $content_data,

			'pages_ids_options' => $options_data->export_pages_ids_options(),
			'created_at' => date('d-m-Y'),

			'builder' => $builder,
			'plugins' => $plugins
		];

		update_option( 'blocksy_ext_demos_exported_demo_data', [
			'demoId' => $demoId,
			'builder' => $builder,
			'plugins' => $plugins
		]);

		wp_send_json_success([
			'demo' => $demo_data
		]);
	}

	public function blocksy_demo_get_export_data() {
		$this->check_nonce();

		if (! current_user_can('edit_theme_options')) {
			wp_send_json_error();
		}

		$data = get_option(
			'blocksy_ext_demos_exported_demo_data',
			[]
		);

		wp_send_json_success([
			'data' => $data
		]);
	}

	public function attach_ajax_actions() {
		foreach ($this->ajax_actions as $action) {
			add_action(
				'wp_ajax_' . $action,
				[$this, $action]
			);
		}
	}

	public function get_plugins_manager() {
		if (! class_exists('Blocksy_Plugin_Manager')) {
			require_once get_template_directory() . '/admin/dashboard/plugins/ct-plugin-manager.php';
		}

		return new \Blocksy_Plugin_Manager();
	}

	public function start_streaming() {
		// Turn off PHP output compression
		// $previous = error_reporting(error_reporting() ^ E_WARNING);
		ini_set('output_buffering', 'off');
		ini_set('zlib.output_compression', false);
		// error_reporting( $previous );
		// error_reporting(0);

		if ($GLOBALS['is_nginx']) {
			// Setting this header instructs Nginx to disable fastcgi_buffering
			// and disable gzip for this request.
			header('X-Accel-Buffering: no');
			header('Content-Encoding: none');
		}

		// Start the event stream.
		header('Content-Type: text/event-stream, charset=UTF-8');

		flush();

		// 2KB padding for IE
		echo ':' . str_repeat(' ', 2048) . "\n\n";
		// Time to run the import!
		set_time_limit(0);

		remove_action('shutdown', 'wp_ob_end_flush_all', 1);

		add_action('shutdown', function() {
			while (@ob_end_flush());
		});
    }

	public function emit_sse_message( $data ) {
		echo "event: message\n";
		echo 'data: ' . wp_json_encode( $data ) . "\n\n";
		// Extra padding.
		echo ':' . str_repeat( ' ', 2048 ) . "\n\n";
		flush();
	}

	public function check_nonce() {
		if (! check_ajax_referer('ct-dashboard', 'nonce', false)) {
			wp_send_json_error('nonce');
		}
	}
}
