<?php

namespace Sphere\Debloat;

use Sphere\Debloat\Admin\Cache;
use Sphere\Debloat\Admin\OptionsData;

/**
 * Admin initialization.
 * 
 * @author  asadkn
 * @since   1.0.0
 */
class Admin
{
	/**
	 * @var Sphere\Debloat\Admin\Cache
	 */
	protected $cache;

	/**
	 * Setup hooks
	 */
	public function init()
	{
		$this->cache = new Cache;
		$this->cache->init();

		add_action('cmb2_admin_init',  [$this, 'setup_options']);

		// Enqueue at a lower priority to be after CMB2.
		add_action('admin_enqueue_scripts', [$this, 'register_assets'], 99);

		// Page to delete cache.
		add_action('admin_menu', function() {
			add_submenu_page(
				'', 
				'Delete Cache', 
				'Delete Cache', 
				'manage_options', 
				'debloat-delete-cache', 
				[$this, 'delete_cache']
			);
		});

		// Empty cache on save.
		add_action('cmb2_save_options-page_fields', [$this, '_delete_cache']);

		/**
		 * Fix: CMB2 doesn't save unchecked making default => true impossible.
		 */
		add_filter('cmb2_sanitize_checkbox', function($override, $value) {
			return is_null($value) ? '0' : $value;
		}, 20, 2);

		// Custom CMB2 field for manual callback
		add_action('cmb2_render_manual', function($field) {

			// Add attributes to an empty span for cmb2-conditional
			if (!empty($field->args['attributes'])) {
				printf('<meta name="%s" %s />', 
					$field->args('id'),
					\CMB2_Utils::concat_attrs($field->args('attributes'))
				);
			}

			if (!empty($field->args['render_html']) && is_callable($field->args['render_html'])) {
				call_user_func($field->args['render_html'], $field);
			}

			if (!empty($field->args['desc'])) {
				echo '<p class="cmb2-metabox-description">' . esc_html($field->args['desc']) . '</p>';
			}
		});
	}

	/**
	 * Register admin assets
	 */
	public function register_assets()
	{
		// Specific assets for option pages only
		if (!empty($_GET['page']) && strpos($_GET['page'], 'debloat_options') !== false) {

			wp_enqueue_script(
				'debloat-cmb2-conditionals', 
				Plugin::get_instance()->dir_url . 'js/admin/cmb2-conditionals.js', 
				['jquery'],
				Plugin::VERSION
			);

			wp_enqueue_script(
				'debloat-options', 
				Plugin::get_instance()->dir_url . 'js/admin/options.js', 
				['jquery', 'debloat-cmb2-conditionals'],
				Plugin::VERSION
			);

			wp_enqueue_style(
				'debloat-admin-cmb2',
				Plugin::get_instance()->dir_url . 'css/admin/cmb2.css',
				['cmb2-styles'],
				Plugin::VERSION
			);
		}
	}

	/**
	 * Delete Cache page.
	 */
	public function delete_cache()
	{
		check_admin_referer('debloat_delete_cache');
		$this->_delete_cache();

		echo '
			<h2>Clearing Cache</h2>
			<p>Caches cleared. You may also have to clear your cache plugins.</p>
			<a href="' . esc_url(admin_url('admin.php?page=debloat_options')) . '">Back to Options</a>';
	}

	/**
	 * Callback: Delete the cache.
	 *
	 * @access private
	 */
	public function _delete_cache()
	{
		$this->cache->empty();

		/**
		 * Hook after deleting cache.
		 */
		do_action('debloat/after_delete_cache');
	}

	/**
	 * Setup admin options with CMB2
	 */
	public function setup_options()
	{
		// Configure admin options
		$options = new_cmb2_box([
			'id'           => 'debloat_options',
			'title'        => esc_html__('Debloat Plugin Settings', 'debloat'),
			'object_types' => ['options-page'],
			'option_key'   => 'debloat_options',
			'parent_slug'  => 'options-general.php',
			'menu_title'   => esc_html__('Debloat: Optimize', 'debloat'),
			'tab_group'    => 'debloat_options',
			'tab_title'    => esc_html__('Optimize CSS', 'debloat'),
			'classes'      => 'sphere-cmb2-wrap',
			'display_cb'   => [$this, 'render_options_page'],
		]);

		$this->add_options(
			OptionsData::get_css(false),
			$options
		);

		// Configure admin options
		$js_options = new_cmb2_box([
			'id'           => 'debloat_options_js',
			'title'        => esc_html__('Optimize JS', 'debloat'),
			'object_types' => ['options-page'],
			'option_key'   => 'debloat_options_js',
			'parent_slug'  => 'debloat_options',
			'menu_title'   => esc_html__('Optimize JS', 'debloat'),
			'tab_group'    => 'debloat_options',
			'tab_title'    => esc_html__('Optimize JS', 'debloat'),
			'classes'      => 'sphere-cmb2-wrap',
			'display_cb'   => [$this, 'render_options_page'],
		]);

		$this->add_options(
			OptionsData::get_js(false),
			$js_options
		);

		// Configure admin options
		$general_options = new_cmb2_box([
			'id'           => 'debloat_options_general',
			'title'        => esc_html__('General Settings', 'debloat'),
			'object_types' => ['options-page'],
			'option_key'   => 'debloat_options_general',
			'parent_slug'  => 'debloat_options',
			'menu_title'   => esc_html__('General Settings', 'debloat'),
			'tab_group'    => 'debloat_options',
			'tab_title'    => esc_html__('General Settings', 'debloat'),
			'display_cb'   => [$this, 'render_options_page'],
			'classes'      => 'sphere-cmb2-wrap'
		]);

		$this->add_options(
			OptionsData::get_general(false),
			$general_options
		);

		do_action('debloat/admin/after_options', $options);

	}
	
	/**
	 * Add options to CMB2 array.
	 *
	 * @param array $options
	 * @param \CMB2 $object
	 * @return void
	 */
	protected function add_options($options, $object)
	{
		return array_map(
			function($option) use ($object) {
				if (isset($option['attributes']['data-conditional-id'])) {
					$condition = &$option['attributes']['data-conditional-id'];
					if (is_array($condition)) {
						$condition = json_encode($condition);
					}
				}

				$field_id = $object->add_field($option);
				
                if ($option['type'] === 'group') {
                    $this->add_option_group($option, $field_id, $object);
                }

			}, 
			$options
		);
	}

	protected function add_option_group($option, $group_id, $object)
	{
		if ($option['id'] === 'allow_conditionals_data') {
			$object->add_group_field($group_id, [
				'id'      => 'type',
				'name'    => esc_html__('Condition Type', 'debloat'),
				'type'    => 'radio',
				'default' => 'class',
				'options' => [
					'class'  => esc_html__('Class - If a class (in "condition match") exists in HTML, keep classes matching "selector match".', 'debloat'),
					'prefix' => esc_html__('Prefix - Condition matches the first class and keeps all the used child classes. Example: .s-dark will keep .s-dark .site-header.', 'debloat'),
				],
			]);

			$object->add_group_field($group_id, [
				'id'      => 'match',
				'name'    => esc_html__('Condition Match', 'debloat'),
				'desc'    => esc_html__('Required. Usually a single class, example:', 'debloat') . '<code>.my-class</code>',
				'type'    => 'text',
				'default' => '',
			]);

			$object->add_group_field($group_id, [
				'id'      => 'search',
				'name'    => esc_html__('Selectors Match', 'debloat'),
				'desc'    => esc_html__('Enter one per line. See example matchings in "Always Keep Selectors" above.', 'debloat'),
				'type'    => 'textarea_small',
				'default' => '',
				'attributes' => [
					'data-conditional-id' => json_encode([$group_id, 'type']),
					'data-conditional-value' => 'class'
				]
			]);
		}
	}

	public function render_options_page($hookup)
	{
		?>
		<div class="cmb2-options-page debloat-options option-<?php echo esc_attr( sanitize_html_class( $hookup->option_key ) ); ?>">
			<div class="wrap">
				<?php if ( $hookup->cmb->prop( 'title' ) ) : ?>
					<h2><?php echo wp_kses_post( $hookup->cmb->prop( 'title' ) ); ?></h2>
				<?php endif; ?>
			</div>
			
			<div class="wrap"><?php $hookup->options_page_tab_nav_output(); ?></div>

			<div class="debloat-inner-wrap">
				<form class="cmb-form debloat-options-form" action="<?php echo esc_url( admin_url( 'admin-post.php' ) ); ?>" method="POST" id="<?php echo esc_attr($hookup->cmb->cmb_id); ?>" enctype="multipart/form-data" encoding="multipart/form-data">
					<input type="hidden" name="action" value="<?php echo esc_attr( $hookup->option_key ); ?>">

					<div class="sphere-cmb2-wrap debloat-intro-info">
						<div class="cmb2-wrap cmb2-metabox">
						<div class="cmb-row">
							<h3>Important: Debloat Plugin</h3>
							<p>
								This plugin is for advanced users. The features "Remove Unused CSS" and "Delay JS" are especially for advanced users only.
							</p>
							<ol>
								<li>Use a cache plugin like W3 Total Cache, WP Super Cache, etc. <strong>Required</strong> for Remove Unused CSS feature.</li>
								<li>Do <strong>NOT</strong> enable minification, CSS, or JS optimization via another plugin.</li>
								<li>If your theme doesn't have it built-in, use a Lazyload plugin for images.</li>
							</ol>
						</div>
						</div>
					</div>

					<?php $hookup->options_page_metabox(); ?>
					<?php submit_button( esc_attr( $hookup->cmb->prop( 'save_button' ) ), 'primary', 'submit-cmb' ); ?>
				</form>
				<div class="debloat-sidebar">
					<?php $this->cache_info(); ?>
				</div>
			</div>

		</div>
		<?php
	}

	public function cache_info()
	{
		$js_cache   = Plugin::file_cache()->get_stats('js');
		$css_cache  = Plugin::file_cache()->get_stats('css');

		// Number of css sheets in cache.
		$css_sheets = count($this->cache->get_transients());
		?>

		<div class="sphere-cmb2-wrap debloat-cache-info">
		<div class="cmb2-wrap cmb2-metabox">
			<div class="cmb-row cmb-type-title">
				<div class="cmb-td">
					<h3 class="cmb2-metabox-title">
						<?php esc_html_e('Cache Stats', 'debloat'); ?>
					</h3>
				</div>
			</div>

			<div class="cmb-row">
				<?php if (defined('SCRIPT_DEBUG') && SCRIPT_DEBUG): ?>
					<p><strong>Minification Disabled</strong>: SCRIPT_DEBUG is enabled (likely in wp-config.php).</p>
				<?php endif; ?>
				
				<div class="cache-stats">
					<p><?php printf(esc_html__('Minified CSS files: %d', 'debloat'), $css_cache); ?></p>
					<p><?php printf(esc_html__('Minified JS files: %d', 'debloat'), $js_cache); ?></p>
					<p><?php printf(esc_html__('Processed CSS Sheets: %d', 'debloat'), $css_sheets); ?></p>
				</div>

				<a href="<?php echo wp_nonce_url(admin_url('admin.php?page=debloat-delete-cache'), 'debloat_delete_cache'); ?>" 
					class="button button-secondary" style="margin-top: 10px;">
					<?php echo esc_html('Empty All Cache', 'debloat'); ?>
				</a>
				</p>
			</div>
		</div>
		</div>

		<?php
	}
}