<?php
/**
 * @package Content Aware Sidebars
 * @author Joachim Jensen <jv@intox.dk>
 * @license GPLv3
 * @copyright 2018 by Joachim Jensen
 */

if (!defined('ABSPATH')) {
	exit;
}

class CAS_Quick_Select {

	const MODULE_NAME = 'post_type';
	const NONCE       = '_cas_nonce';

	protected static $_theme_sidebars = array();

	public function __construct(){
		new CAS_Post_Type_Sidebar();
	}

	/**
	 * Load Quick Select on post screen
	 *
	 * @since  3.7
	 * @param  WP_Screen  $screen
	 * @return void
	 */
	public static function load_screen($screen) {

		//We are on the post edit screen
		if($screen->base == 'post' && $screen->post_type) {
			$module = WPCACore::types()->get(CAS_App::TYPE_SIDEBAR)->get(self::MODULE_NAME);
			if($module) {
				$post_types = $module->post_types();
				self::get_theme_sidebars();
				if(isset($post_types[$screen->post_type]) && self::$_theme_sidebars) {
					add_action('add_meta_boxes_'.$screen->post_type,
						array(__CLASS__,'create_meta_boxes'));
					add_action('save_post_'.$screen->post_type,
						array(__CLASS__,'save_post_sidebars'),10,2);
					add_action('admin_enqueue_scripts',
						array(__CLASS__,'register_scripts'),8);
					add_action('admin_enqueue_scripts',
						array(__CLASS__,'enqueue_scripts'),11);
				}
			}
		}
	}

	/**
	 * Gather theme sidebars for later use
	 *
	 * @since  3.3
	 * @return void
	 */
	public static function get_theme_sidebars() {
		global $wp_registered_sidebars;

		$cas_sidebars = CAS_App::instance()->manager()->sidebars;

		foreach($wp_registered_sidebars as $sidebar) {
			if(!isset($cas_sidebars[$sidebar['id']])) {
				self::$_theme_sidebars[$sidebar['id']] = array(
					'label' => $sidebar['name'],
					'options' => array()
				);
			}
		}
	}

	/**
	 * Save sidebars and conditions for post
	 *
	 * @since  3.3
	 * @param  int      $post_id
	 * @param  WP_Post  $post
	 * @return void
	 */
	public static function save_post_sidebars($post_id, $post) {

		if(!(isset($_POST[self::NONCE])
			&& wp_verify_nonce($_POST[self::NONCE], self::NONCE.$post_id))) {
			return;
		}
		
		// Check post permissions
		if (!current_user_can('edit_post', $post_id))
			return;

		if($post->post_status == 'auto-draft') {
			return;
		}

		// Check autosave
		if (defined('DOING_AUTOSAVE') && DOING_AUTOSAVE)
			return;

		$meta_key = WPCACore::PREFIX . self::MODULE_NAME;
		$new = isset($_POST['cas_sidebars']) ? $_POST['cas_sidebars'] : array();

		$relations = self::_get_content_sidebars($post);
		$user_can_create_sidebar = current_user_can(CAS_App::CAPABILITY);

		foreach ($new as $host => $sidebar_ids) {
			foreach ($sidebar_ids as $sidebar_id) {
				//Post has sidebar already
				if(isset($relations[$sidebar_id])) {
					unset($relations[$sidebar_id]);
				//Discard empty
				} elseif($sidebar_id) {

					$condition_group_id = 0;
					
					//New sidebar
					//check permissions here
					if($sidebar_id[0] == '_') {
						if($user_can_create_sidebar) {
							$id = wp_insert_post(array(
								'post_title'  => str_replace('__',',',substr($sidebar_id,1)),
								'post_status' => CAS_App::STATUS_INACTIVE, 
								'post_type'   => CAS_App::TYPE_SIDEBAR
							));
							if($id) {
								//wp_insert_post does not handle meta before WP4.4
								add_post_meta($id, WPCACore::PREFIX.'host', $host);
								$condition_group_id = WPCACore::add_condition_group($id);
							}
						}
					} else {
						//Add post to group with other posts
						$id = intval($sidebar_id);
						$condition_groups = get_posts(array(
							'posts_per_page'   => 1,
							'meta_key'         => $meta_key,
							'meta_value'       => $post->post_type,
							'meta_compare'     => '!=',
							'post_parent'      => $id,
							'post_type'        => WPCACore::TYPE_CONDITION_GROUP,
							'post_status'      => WPCACore::STATUS_PUBLISHED
						));
						if($condition_groups) {
							$condition_group_id = $condition_groups[0]->ID;
						} else {
							$condition_group_id = WPCACore::add_condition_group($id);
						}
					}

					if($condition_group_id) {
						add_post_meta($condition_group_id, $meta_key, $post_id);
						//add_post_meta($condition_group_id, $meta_key.'_direct', 1);
					}
				}
			}
		}

		//remove old relations
		//todo: sanity check if post is added to several groups?
		$sidebars = CAS_App::instance()->manager()->sidebars;
		$host_meta = CAS_App::instance()->manager()->metadata()->get('host');
		foreach ($relations as $sidebar_id => $group_id) {
			if(isset($sidebars[CAS_App::SIDEBAR_PREFIX.$sidebar_id])) {
				$host_id = $host_meta->get_data($sidebar_id);
				if(!isset(self::$_theme_sidebars[$host_id])) {
					continue;
				}
			}

			//group with no post_type meta will be removed
			//even if it has other meta (unlikely)
			$group_meta = get_post_meta($group_id, $meta_key);
			if(count($group_meta) <= 1) {
				wp_delete_post($group_id);
			} else {
				delete_post_meta($group_id, $meta_key, $post_id);
			}
		}
	}

	/**
	 * Create sidebar meta box for post types
	 *
	 * @since  3.3
	 * @param  WP_Post  $post
	 * @return void
	 */
	public static function create_meta_boxes($post) {

		$post_sidebars = self::_get_content_sidebars($post);

		$manager = CAS_App::instance()->manager();
		$host_meta = $manager->metadata()->get('host');
		foreach ($manager->sidebars as $sidebar) {
			$host_id = $host_meta->get_data($sidebar->ID);
			if(isset(self::$_theme_sidebars[$host_id])) {
				self::$_theme_sidebars[$host_id]['options'][$sidebar->ID] = array(
					'id' => $sidebar->ID,
					'text' => $sidebar->post_title.self::sidebar_states($sidebar)
				);
				if(isset($post_sidebars[$sidebar->ID])) {
					self::$_theme_sidebars[$host_id]['options'][$sidebar->ID]['select'] = 1;
				}
			}
		}

		$post_type = get_post_type_object($post->post_type);
		$content = array(
			__('Author')
		);
		if($post_type->hierarchical) {
			$content[] = __('Child Page','content-aware-sidebars');
		}
		if($post_type->name == 'page') {
			$content[] = __('Page Template','content-aware-sidebars');
		}
		$taxonomies = get_object_taxonomies($post,'objects');
		if($taxonomies) {
			foreach ($taxonomies as $tax) {
				$content[] = $tax->labels->singular_name;
			}
		}
		$content[] = __('Archive Page','content-aware-sidebars');

		$path = plugin_dir_path( __FILE__ ).'../view/';
		$view = WPCAView::make($path.'sidebars_quick_select.php',array(
			'post'     => $post,
			'sidebars' => self::$_theme_sidebars,
			'limit'    => 3,
			'content'  => $content,
			'singular' => $post_type->labels->singular_name,
			'nonce'    => wp_nonce_field(self::NONCE.$post->ID, self::NONCE, false, false)
		));

		add_meta_box(
			'cas-content-sidebars',
			__('Sidebars - Quick Select','content-aware-sidebars'),
			array($view, 'render'),
			$post->post_type,
			'side',
			'default'
		);
	}

	/**
	 * Get sidebar status for display
	 *
	 * @since  3.4.1
	 * @param  WP_Post  $post
	 * @return string
	 */
	public static function sidebar_states($post) {
		switch ($post->post_status) {
			case CAS_App::STATUS_ACTIVE:
				$status = '';
				break;
			case CAS_App::STATUS_SCHEDULED;
				$status = ' ('.__( 'Scheduled' ).')';
				break;
			default:
				$status = ' ('.__( 'Inactive', 'content-aware-sidebars').')';
				break;
		}
		return $status;
	}

	/**
	 * Register scripts and styles
	 * We register early to make sure our select2 comes first
	 *
	 * @since  3.5.2
	 * @param  string  $hook
	 * @return void
	 */
	public static function register_scripts($hook) {

		wp_register_script(
			'select2',
			plugins_url('../lib/wp-content-aware-engine/assets/js/select2.min.js', __FILE__),
			array('jquery'),
			'4.0.3',
			false
		);
		wp_register_script('cas/sidebars/suggest', plugins_url('/js/suggest-sidebars.min.js', dirname(__FILE__)), array('select2'), CAS_App::PLUGIN_VERSION, true);
	}

	/**
	 * Enqueue scripts and styles
	 * We enqueue later to make sure our CSS takes precedence
	 *
	 * @since  3.5.2
	 * @param  string  $hook
	 * @return void
	 */
	public static function enqueue_scripts($hook) {
		wp_enqueue_style(CAS_App::META_PREFIX.'condition-groups');
		wp_enqueue_script('cas/sidebars/suggest');

		$labels = array(
			'createNew' => __('Create New','content-aware-sidebars'),
			'labelNew'  => __('New','content-aware-sidebars')
		);
		if(current_user_can(CAS_App::CAPABILITY)) {
			$labels['notFound'] = __('Type to Add New Sidebar','content-aware-sidebars');
		} else {
			$labels['notFound'] = __('No sidebars found','content-aware-sidebars');
		}
		wp_localize_script('cas/sidebars/suggest', 'CAS', $labels);
	}

	/**
	 * Get sidebars for select post types
	 *
	 * @since  3.3
	 * @param  WP_Post  $post
	 * @return array
	 */
	protected static function _get_content_sidebars($post) {
		$sidebars = array();
		if($post) {
			global $wpdb;
			$query = $wpdb->get_results($wpdb->prepare( 
				"SELECT s.ID, g.ID as group_id
				FROM $wpdb->posts s
				INNER JOIN $wpdb->posts g ON g.post_parent = s.ID
				INNER JOIN $wpdb->postmeta gm ON gm.post_id = g.ID AND gm.meta_key = '".WPCACore::PREFIX.self::MODULE_NAME."'
				WHERE s.post_status <> 'trash'
				AND s.post_type = '".CAS_App::TYPE_SIDEBAR."'
				AND g.post_status = '".WPCACore::STATUS_PUBLISHED."'
				AND gm.meta_value = %d
				ORDER BY s.post_title ASC", 
				$post->ID
			));
			if($query) {
				foreach ($query as $sidebar) {
					$sidebars[$sidebar->ID] = $sidebar->group_id;
				}
			}
		}
		return $sidebars;
	}

}

/**
 * @deprecated 3.7
 */
class CAS_Post_Type_Sidebar {

	public function __construct() {
		add_action('admin_init',
			array(__CLASS__,'initiate'));
	}

	/**
	 * Backwards compat for users disabling quick select
	 * with remove_action('admin_init',...)
	 *
	 * @since  3.7
	 * @return void
	 */
	public static function initiate() {
		add_action('current_screen',
			array('CAS_Quick_Select','load_screen'));
	}
}

//eol