<?php

namespace EFFE_Plugin;

/**
 * The core plugin class.
 *
 * @since      1.0.0
 * @package    Event_Feed_For_Eventbrite
 * @subpackage Event_Feed_For_Eventbrite/includes
 * @author     Bohemia Plugins <https://www.bohemiaplugins.com>
 */
class Event_Feed_For_Eventbrite {

	/**
	 * The loader that's responsible for maintaining and registering all hooks that power
	 * the plugin.
	 *
	 * @since    1.0.0
	 * @access   protected
	 * @var      Event_Feed_For_Eventbrite_Loader    $loader    Maintains and registers all hooks for the plugin.
	 */
	protected $loader;

	/**
	 * Define the core functionality of the plugin.
	 *
	 * @since    1.0.0
	 * @access   public
	 */
	public function __construct() {
		$this->plugin_name = EFFE_PLUGIN_NAME;
		$this->version = EFFE_VERSION;
		$this->load_dependencies();
		$this->set_locale();
		$this->define_admin_hooks();
		$this->define_public_hooks();
	}

	/**
	 * Load the required dependencies for this plugin.
	 *
	 * @since    1.0.0
	 * @access   private
	 */
	private function load_dependencies() {

		/**
		 * The class responsible for orchestrating the actions and filters of the
		 * core plugin.
		 */
		require_once plugin_dir_path( dirname( __FILE__ ) ) . 'includes/class-loader.php';

		/**
		 * The class responsible for defining internationalization functionality
		 * of the plugin.
		 */
		require_once plugin_dir_path( dirname( __FILE__ ) ) . 'includes/class-i18n.php';

		/**
		 * The class responsible for defining custom post type used for generating event
		 * feeds.
		 */
		require_once plugin_dir_path( dirname( __FILE__ ) ) . 'includes/class-event-feed.php';

		/**
		 * The class responsible for all communication with Eventbrite API.
		 */
		require_once plugin_dir_path( dirname( __FILE__ ) ) . 'includes/class-event-feed-api.php';

		/**
		 * The class responsible for handling data filtering, setting API attributes.
		 */
		require_once plugin_dir_path( dirname( __FILE__ ) ) . 'includes/class-event-feed-query.php';

		/**
		 * The class responsible for defining all actions that occur in the admin area.
		 */
		require_once plugin_dir_path( dirname( __FILE__ ) ) . 'admin/class-admin.php';

		/**
		 * The class responsible for defining all actions that occur in the public-facing
		 * side of the site.
		 */
		require_once plugin_dir_path( dirname( __FILE__ ) ) . 'public/class-public.php';

		$this->loader = new Event_Feed_For_Eventbrite_Loader();

	}

	/**
	 * Define the locale for this plugin for internationalization.
	 *
	 * @since    1.0.0
	 * @access   private
	 */
	private function set_locale() {

		$plugin_i18n = new Event_Feed_For_Eventbrite_i18n();

		$this->loader->add_action( 'plugins_loaded', $plugin_i18n, 'load_plugin_textdomain' );

	}

	/**
	 * Register all of the hooks related to the admin area functionality
	 * of the plugin.
	 *
	 * @since    1.0.0
	 * @access   private
	 */
	private function define_admin_hooks() {

		$plugin_admin = new Event_Feed_For_Eventbrite_Admin( $this->get_plugin_name(), $this->get_version() );
		
		// Plugin scripts and styles
		$this->loader->add_action( 'admin_enqueue_scripts', $plugin_admin, 'enqueue_styles' );
		$this->loader->add_action( 'admin_enqueue_scripts', $plugin_admin, 'enqueue_scripts' );

		// Add scripts needed for rendering media uploader
		$this->loader->add_action( 'admin_enqueue_scripts', $plugin_admin, 'enqueue_media_uploader' );

		// Save/Update our plugin options
		$this->loader->add_action( 'admin_init', $plugin_admin, 'options_update' );

		// Getting Started page API key update + redirect.
		$this->loader->add_action( 'admin_post_effe_getting_started_save_api_key_response', $plugin_admin, 'getting_started_save_api_key');

		// Process admin actions
		$this->loader->add_action( 'init', $plugin_admin, 'process_admin_actions' );

		// Add menu items
		$this->loader->add_action( 'admin_menu', $plugin_admin, 'add_plugin_admin_menu' );
		$this->loader->add_action( 'admin_menu', $plugin_admin, 'add_plugin_welcome_page' );
		$this->loader->add_action( 'admin_head', $plugin_admin, 'hide_plugin_welcome_page' );
		
		// Add Settings link to the plugin
		$plugin_basename = plugin_basename( plugin_dir_path( __DIR__ ) . $this->plugin_name . '.php' );
		$this->loader->add_filter( 'plugin_action_links_' . $plugin_basename, $plugin_admin, 'add_action_links' );
		
		// Register Event Feed custom post type
		$event_feed_post_type = new Event_Feed_For_Eventbrite_Feed();
		$this->loader->add_action( 'init', $event_feed_post_type, 'register_event_feed_post_type', 999 );

		// Change add title text
		$this->loader->add_filter( 'enter_title_here', $event_feed_post_type , 'event_feed_change_title_text' );

		// Register Event Feed post meta
		$this->loader->add_action( 'init', $event_feed_post_type, 'register_event_feed_post_meta' );
		
		// Add image size for Eventbrite thumbnail
		$this->loader->add_action( 'init', $plugin_admin, 'eventbrite_image_size' );

		// Add admin columns to event feed post type
		$this->loader->add_filter( 'manage_event_feed_posts_columns', $plugin_admin, 'shortcode_event_feed_column' );
		$this->loader->add_action( 'manage_event_feed_posts_custom_column', $plugin_admin, 'shortcode_event_feed_column_content', 10, 2 );
		
		// Make organization admin column sortable
		$this->loader->add_filter( 'manage_edit-event_feed_sortable_columns', $plugin_admin, 'organization_event_feed_column_sortable');
		$this->loader->add_action( 'pre_get_posts', $plugin_admin, 'organization_event_feed_column_orderby' );

		// Make layout admin column sortable
		$this->loader->add_filter( 'manage_edit-event_feed_sortable_columns', $plugin_admin, 'layout_event_feed_column_sortable');
		$this->loader->add_action( 'pre_get_posts', $plugin_admin, 'layout_event_feed_column_orderby' );

		// Global admin css
		$this->loader->add_action( 'admin_head', $plugin_admin, 'event_feed_admin_css' );

		// Add Purge Cache button to admin bar
		$this->loader->add_action( 'admin_bar_menu', $plugin_admin, 'purge_cache_admin_bar_button', 1000 );

		// Add admin notice in case user haven't enter API credentials yet
		$this->loader->add_action( 'admin_notices', $plugin_admin, 'event_feed_for_eventbrite_admin_notices' );

		// Change admin footer text
		$this->loader->add_filter( 'admin_footer_text', $plugin_admin, 'change_left_admin_footer_text' );
		$this->loader->add_filter( 'update_footer', $plugin_admin, 'change_right_admin_footer_text', 11 );

		// Add nonce to default post publish metabox
		$this->loader->add_action( 'post_submitbox_start', $plugin_admin, 'event_feed_add_nonce_to_default_publish_metabox' );

		// Update user's Eventbrite organizations on post edit load
		$this->loader->add_action( 'admin_head', $plugin_admin, 'event_feed_update_user_organizations' );
		
		// Add metaboxes to plugin custom post type
		$this->loader->add_action( 'add_meta_boxes_event_feed', $plugin_admin, 'setup_custom_post_type_metaboxes' );
		
		// Save metabox data to custom post type
		$this->loader->add_action( 'save_post_event_feed', $plugin_admin, 'event_feed_save_post', 10, 2 );

		// Add the ability to duplicate event feed
		$this->loader->add_action( 'admin_action_duplicate_event_feed_as_draft', $plugin_admin, 'duplicate_event_feed_as_draft' );

		// Modify event feed's post row actions
		$this->loader->add_filter( 'post_row_actions', $plugin_admin, 'modify_event_feed_row_actions', 10, 2 );

		// Ajax function to get date in specified format
		$this->loader->add_filter( 'wp_ajax_get_dateformat', $plugin_admin, 'get_dateformat', 10, 2 );
		$this->loader->add_filter( 'wp_ajax_nopriv_get_dateformat', $plugin_admin, 'get_dateformat', 10, 2 );

		// Block editor scripts and styles
		$this->loader->add_action( 'init', $plugin_admin, 'register_block' );
		$this->loader->add_action( 'enqueue_block_editor_assets', $plugin_admin, 'enqueue_block_editor_scripts' );

		// Prevent draft post change when restoring from trash
		$this->loader->add_filter( 'wp_insert_post_data', $plugin_admin, 'prevent_draft_post_change', 20, 2 );
	}

	/**
	 * Register all of the hooks related to the public-facing functionality
	 * of the plugin.
	 *
	 * @since    1.0.0
	 * @access   private
	 */
	private function define_public_hooks() {

		$plugin_public = new Event_Feed_For_Eventbrite_Public( $this->get_plugin_name(), $this->get_version() );
		
		// Plugin scripts and styles
		$this->loader->add_action( 'init', $plugin_public, 'register_styles' );
		$this->loader->add_action( 'init', $plugin_public, 'register_scripts' );
		$this->loader->add_action( 'wp_enqueue_scripts', $plugin_public, 'enqueue_styles' );
		$this->loader->add_action( 'wp_enqueue_scripts', $plugin_public, 'enqueue_scripts' );

		// Add icon to delete cache button in admin bar
		$this->loader->add_action( 'wp_head', $plugin_public, 'event_feed_delete_cache_css' );

		// Add element for Vue modal to end of body
		$this->loader->add_action( 'wp_footer', $plugin_public, 'add_vue_modal_container' );

		// Add shortcode for showing events feed
		$this->loader->add_shortcode( 'event-feed', $plugin_public, 'event_feed_shortcode' );

		// Single event feed templates
		$this->loader->add_filter( 'template_include', $plugin_public, 'single_event_feed_template', 99 );

		// Add Rest API routes for displaying events data
		$this->loader->add_action( 'rest_api_init', $plugin_public, 'register_event_feed_rest_endpoint' );
		
		$this->loader->add_action( 'rest_api_init', $plugin_public, 'register_event_image_rest_endpoint' );

	}

	/**
	 * Run the loader to execute all of the hooks with WordPress.
	 *
	 * @since    1.0.0
	 * @access   public
	 */
	public function run() {
		$this->loader->run();
	}

	/**
	 * The name of the plugin used to uniquely identify it within the context of
	 * WordPress and to define internationalization functionality.
	 *
	 * @since    1.0.0
	 * @access   public
	 * @return   string    The name of the plugin.
	 */
	public function get_plugin_name() {
		return $this->plugin_name;
	}

	/**
	 * The reference to the class that orchestrates the hooks with the plugin.
	 *
	 * @since    1.0.0
	 * @access   public
	 * @return   Event_Feed_For_Eventbrite_Loader    Orchestrates the hooks of the plugin.
	 */
	public function get_loader() {
		return $this->loader;
	}
	
	/**
	 * Retrieve the version number of the plugin.
	 *
	 * @since    1.0.0
	 * @access   public
	 * @return   string    The version number of the plugin.
	 */
	public function get_version() {
		return $this->version;
	}
	
}
