<?php

namespace Eventman\Includes;

use Eventman\Admin\MsEventmanAdmin;
use Eventman\Admin\OpengraphFix;
use Eventman\Admin\Options;
use Eventman\Admin\ThreeWPFix;
use Eventman\Admin\WPML;
use Eventman\Includes\Post\PostTypes;
use Eventman\MsEventmanPublic;
use plainview\sdk_broadcast\wordpress\plugin_pack\plugin;

/**
 * The file that defines the core plugin class
 *
 * A class definition that includes attributes and functions used across both the
 * public-facing side of the site and the admin area.
 *
 * @link       http://example.com
 * @since      1.0.0
 *
 * @package    MS_Eventman
 * @subpackage MS_Eventman/includes
 */

/**
 * The core plugin class.
 *
 * This is used to define internationalization, admin-specific hooks, and
 * public-facing site hooks.
 *
 * Also maintains the unique identifier of this plugin as well as the current
 * version of the plugin.
 *
 * @since      1.0.0
 * @package    MS_Eventman
 * @subpackage MS_Eventman/includes
 * @author     Your Name <email@example.com>
 */
class MsEventman {

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

	/**
	 * The unique identifier of this plugin.
	 *
	 * @since    1.0.0
	 * @access   protected
	 * @var      string    $ms_eventman    The string used to uniquely identify this plugin.
	 */
	protected $ms_eventman;

	/**
	 * The current version of the plugin.
	 *
	 * @since    1.0.0
	 * @access   protected
	 * @var      string    $version    The current version of the plugin.
	 */
	protected $version;
    /**
     * @var PostTypes
     */
    private $posts;

    /**
	 * Define the core functionality of the plugin.
	 *
	 * Set the plugin name and the plugin version that can be used throughout the plugin.
	 * Load the dependencies, define the locale, and set the hooks for the admin area and
	 * the public-facing side of the site.
	 *
	 * @since    1.0.0
	 */
	public function __construct() {
		if ( defined( 'MS_EVENTMAN_VERSION' ) ) {
			$this->version = MS_EVENTMAN_VERSION;
		} else {
			$this->version = '1.0.0';
		}
		$this->msEventman = 'ms-eventman';
        $this->loader = new MsEventmanLoader();
        $this->posts = new PostTypes($this);

		$this->setLocale();

		$this->definedCommonHooks();

        $this->defineAdminHooks();
        $this->definePublicHooks();

    }

    /**
	 * Define the locale for this plugin for internationalization.
	 *
	 * Uses the MsEventmani18n class in order to set the domain and to register the hook
	 * with WordPress.
	 *
	 * @since    1.0.0
	 * @access   private
	 */
	private function setLocale() {

		$plugin_i18n = new MsEventmani18n();

		$this->loader->addAction( 'plugins_loaded', $plugin_i18n, 'loadPluginTextdomain' );

	}

    private function definedCommonHooks()
    {
        // overwrite default stylesheet link tag
//        add_filter('style_loader_tag', function($html, $handle = null, $href = null, $media = null) {
//            return str_replace("rel='stylesheet'", "rel='preload' as='style' onload='this.rel=\'stylesheet\''", $html);
//        });
        add_action('wp_enqueue_scripts', function () {
//            global $wp_styles;
            wp_dequeue_style('elision-font-awesome');

        }, PHP_INT_MAX);
    }

    /**
	 * Register all of the hooks related to the admin area functionality
	 * of the plugin.
	 *
	 * @since    1.0.0
	 * @access   private
	 */
	private function defineAdminHooks() {
        $plugin_admin = new MsEventmanAdmin( $this->getMsEventman(), $this->getVersion() );

        $this->posts->defineAdminHooks();

        // add scripts and styles
        $this->loader->addAction( 'admin_enqueue_scripts', $plugin_admin, 'enqueueStyles' );
        $this->loader->addAction( 'admin_enqueue_scripts', $plugin_admin, 'enqueueScripts' );

        // add require elision qode plugin message
        $this->loader->addAction( 'admin_init', $plugin_admin, 'requireElision');

        $this->loader->addAction('admin_init', $plugin_admin, 'navEdit');

        // add a gallery meta box for exhibitors
        $this->loader->addAction( 'admin_init', $plugin_admin, 'addGalleryMetaBox' );
        // add read settings
        $this->loader->addAction( 'admin_init', $plugin_admin, 'registerSettings' );

        // filter away licensing notifications
        $this->loader->addAction( 'admin_init', $plugin_admin, 'interceptPluginActions', 999);

        // replace default dashboard
        $this->loader->addAction( 'wp_dashboard_setup', $plugin_admin, 'dashboardSetup');

        $this->loader->addFilter( 'plugin_action_links', $plugin_admin, 'disableActivationLink', 10, 2);

        // add and remove admin menu items
        $this->loader->addAction('admin_menu', $plugin_admin, 'adminMenu', 9);
        $this->loader->addAction('network_admin_menu', $plugin_admin, 'networkMenu');

        // remove the 'posts' menu item active class when on event page
        $this->loader->addAction( 'parent_file', $plugin_admin, 'setActiveMenuItemOnEventsTaxonomy');

        // set the 'events' menu item to active when needed
        $this->loader->addAction( 'admin_head', $plugin_admin, 'eventsPageScript');

        // save checked exhibitors for a site
        $this->loader->addAction( 'network_admin_edit_siteExhibitorsUpdate',  $plugin_admin, 'saveExhibitorsForSite' );
        $this->loader->addAction( 'network_admin_edit_sitePartnersUpdate',  $plugin_admin, 'savePartnersForSite' );

        // reorder the admin menu
        $this->loader->addFilter( 'custom_menu_order', $plugin_admin, "returnTrue", 10, 0 );
        $this->loader->addFilter( 'menu_order', $plugin_admin, 'reorderMenu', 9999, 1 );

        // add default theme, qode options, menu items, pages etc. to newly created network site
        $this->loader->addAction( 'wp_initialize_site', $plugin_admin, 'addDefaultsToNewSite', 999, 2);

        // add 'published' column to event list
        $this->loader->addFilter( 'manage_edit-events_columns', $plugin_admin, 'addEventPublishColumn', 10, 1);
        $this->loader->addFilter( 'manage_events_custom_column', $plugin_admin, 'manageEventListColumns', 10, 3);

        // Add default page layout options in read settings
        $this->loader->addFilter( 'display_post_states' , $plugin_admin, 'addCustomPostStates');

        // add favicon to admin pages
        $this->loader->addAction('admin_head', $plugin_admin, 'addFavicon');

        // add wpml hook actions
        $wpml = new WPML();
        $this->loader->addAction('wpml_pro_translation_completed', $wpml, 'broadcastCompletedTranslation', 999);
        $this->replaceBroadcastHookFunctions($wpml);


        // overwrite buggy ThreeWPBroadcast hooks
        $twf = new ThreeWPFix();
//        $this->loader->addAction('threewp_broadcast_manage_posts_custom_column', $twf, 'fixPostCustomColumn');
        $this->loader->addAction('wp_ajax_broadcast_post_action_form', $twf, 'fixBroadcastFormBox', 10);
        $this->loader->addFilter('threewp_broadcast_prepare_meta_box', $twf, 'fixPostBox');

        // add Yoast OpenGraph fixes
        new OpengraphFix();

        if (isset(Options::getOptions()['enable_debug']) && Options::getOptions()['enable_debug'] == 'on') {
            $logger = new HookLogger(Options::getOptions()['debug_hooks'] ?? []);
//            $this->loader->addAction('switch_blog', $logger, 'logSwitchStack');
        } else {
//            dd(get_site_option(Options::_OPTION_ID));
        }

    }

    public function replaceBroadcastHookFunctions(WPML $wpml) {
        add_action('admin_init', function() use ($wpml) {
            global $wp_filter;
            array_pop($wp_filter['threewp_broadcast_collect_post_type_taxonomies']->callbacks[10]);
            add_action('threewp_broadcast_collect_post_type_taxonomies', [$wpml, 'fixedCollectPostTypeTaxonomies']);
        });
    }

    /**
	 * Register all of the hooks related to the public-facing functionality
	 * of the plugin.
	 *
	 * @since    1.0.0
	 * @access   private
	 */
	private function definePublicHooks() {
	    // set the public hooks for custom post types
        $this->posts->definePublicHooks();

        $plugin_public = new MsEventmanPublic( $this->getMsEventman(), $this->getVersion() );

        // add scripts and styles
        $this->loader->addAction( 'wp_enqueue_scripts', $plugin_public, 'enqueueStyles', 999 );
        $this->loader->addAction( 'wp_enqueue_scripts', $plugin_public, 'enqueueScripts', 999 );

        // add eventinfo, bloginfo and calendar feed shortcodes
        $this->loader->addAction('init', $plugin_public, 'addShortcodes', 999);

        // add dynamic css matching Qode Options
        $this->loader->addAction('wp_head', $plugin_public, 'dynamicCss', 999);

        // fix plugin and theme uris to the current subsite's url
        $this->loader->addFilter('plugins_url', $plugin_public, 'fixPluginsUrl', PHP_INT_MAX, 3);
        $this->loader->addFilter('theme_root_uri', $plugin_public, 'fixPluginsUrl', PHP_INT_MAX, 3);

        // order Exhibitors and Partners by ascending title
        $this->loader->addAction('pre_get_posts', $plugin_public, 'orderCustomPostTypesByTitleAsc');

        // add rewrites for events and cpts
        $this->loader->addAction('rewrite_rules_array', $plugin_public, 'addRewritesForEvents');

        // add all published event years as menu items under 'Exhibitor' and 'Partner' menu items
        $this->loader->addFilter('wp_get_nav_menu_items', $plugin_public, 'addSitesMenuOptions', null, 2);

        // add /event/{year} as Exhibitor archive
        $this->loader->addFilter('post_type_link', $plugin_public, 'permalinks', 10, 2);

        // set Exhibitor limit to 9 and Partners to 12
        $this->loader->addFilter( 'pre_get_posts', $plugin_public, 'limitCptArchivePosts');

        // set the post_type query param matching the event url params
        $this->loader->addFilter( 'pre_get_posts', $plugin_public, 'setQueryVarsForArchivePages');

        // overwrite 'Archive' with '{PostType} {EventYear}'
        $this->loader->addFilter( 'get_the_archive_title', $plugin_public, 'overwriteCptArchiveTitle');

        // add a calendar feed link to the latest published event
        $this->loader->addAction('init', $plugin_public, 'addCalendarFeeds');

        $this->loader->addFilter('get_previous_post_sort', $plugin_public, 'orderAdjacentPost', 10, 3);
        $this->loader->addFilter('get_next_post_sort', $plugin_public, 'orderAdjacentPost', 10 ,3);
        $this->loader->addFilter('get_previous_post_where', $plugin_public, 'filterAdjacentPost', 10, 5);
        $this->loader->addFilter('get_next_post_where', $plugin_public, 'filterAdjacentPost', 10, 5);
	}

	/**
	 * Run the loader to execute all of the hooks with WordPress.
	 *
	 * @since    1.0.0
	 */
	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
	 * @return    string    The name of the plugin.
	 */
	public function getMsEventman() {
		return $this->msEventman;
	}

	/**
	 * The reference to the class that orchestrates the hooks with the plugin.
	 *
	 * @since     1.0.0
	 * @return    MsEventmanLoader    Orchestrates the hooks of the plugin.
	 */
	public function getLoader() {
		return $this->loader;
	}

	/**
	 * Retrieve the version number of the plugin.
	 *
	 * @since     1.0.0
	 * @return    string    The version number of the plugin.
	 */
	public function getVersion() {
		return $this->version;
	}

}
