<?php
namespace JET_APB;

// If this file is called directly, abort.
if ( ! defined( 'WPINC' ) ) {
	die;
}

/**
 * @property WC_Integration wc
 * @property DB\Manager db
 * @property Form form
 * @property Admin\Settings settings
 * @property Rest_API\Manager rest_api
 * @property Tools tools
 * @property Service_Provider_Relations_Map service_provider_relations_map
 * @property Calendar calendar
 *
 * Main file
 */
class Plugin {

	/**
	 * Instance.
	 *
	 * Holds the plugin instance.
	 *
	 * @since 1.0.0
	 * @access public
	 * @static
	 *
	 * @var Plugin
	 */
	public static $instance = null;

	/**
	 * @var DB\Manager
	 */
	public $db = null;

	/**
	 * [$data description]
	 * @var boolean
	 */
	public $data = false;

	/**
	 * [$working_hours_config description]
	 * @var array
	 */
	public $working_hours_config = false;

	public $settings;
	public $tools;
	public $service_provider_relations_map;
	public $services_meta;
	public $providers_meta;
	public $form;
	public $calendar;
	public $rest_api;
	public $google_cal;
	public $wc;
	public $elementor;
	public $bricks;
	public $blocks;
	public $statuses;
	/**
	 * @var Workflows\Manager
	 */
	public $workflows;
	public $setup;
	public $dashboard;
	public $macros;
	public $export;
	public $compatibility;

	/**
	 * Plugin constructor.
	 */
	private function __construct() {

		if ( ! function_exists( 'jet_engine' ) ) {

			add_action( 'admin_notices', function() {
				$class = 'notice notice-error';
				$message = __( '<b>WARNING!</b> <b>JetAppointmentsBooking</b> plugin requires <b>JetEngine</b> plugin to work properly!', 'jet-appointments-booking' );
				printf( '<div class="%1$s"><p>%2$s</p></div>', esc_attr( $class ), wp_kses_post( $message ) );
			} );

			return;
		}

		$this->register_autoloader();

		add_action( 'after_setup_theme', [ $this, 'init_modules' ], -20 );

		// Jet Dashboard Init
		add_action( 'after_setup_theme', array( $this, 'init_components' ), 0 );

		// Jet Dashboard Init
		add_action( 'init', array( $this, 'jet_dashboard_init' ), -999 );
	}

	/**
	 * Returns plugin version
	 *
	 * @return string
	 */
	public function get_version() {

		if ( is_admin() ) {

			if( ! function_exists('get_plugin_data') ){
				require_once( ABSPATH . 'wp-admin/includes/plugin.php' );
			}

			if( ! $this->data ){
				$this->data = get_plugin_data( JET_APB__FILE__ );
			}
		}

		return $this->data['Version'];
	}

	/**
	 * Page slug
	 *
	 * @return string
	 */
	public function slug() {
		return 'jet-appointments-booking';
	}

	/**
	 * Register autoloader.
	 */
	private function register_autoloader() {
		require JET_APB_PATH . 'includes/autoloader.php';
		Autoloader::run();
	}

	/**
	 * Initialize framework modules
	 *
	 * @return [type] [description]
	 */
	public function init_modules() {
		new Modules\Loader( [
			JET_APB_PATH . 'includes/modules/macros/base-macros.php',
			JET_APB_PATH . 'includes/modules/macros/macros-handler.php',
			JET_APB_PATH . 'includes/modules/google-calendar-synch/controller.php',
		] );
	}


	/**
	 * [jet_dashboard_init description]
	 * @return [type] [description]
	 */
	public function jet_dashboard_init() {

		if ( is_admin() ) {

			if( ! class_exists( 'Jet_Dashboard\Dashboard' ) ){
				return;
			}

			$jet_dashboard = \Jet_Dashboard\Dashboard::get_instance();

			$jet_dashboard->init( array(
				'path'           => $jet_dashboard->get_dashboard_path(),
				'url'            => $jet_dashboard->get_dashboard_url(),
				'cx_ui_instance' => array( $this, 'jet_dashboard_ui_instance_init' ),
				'plugin_data'    => array(
					'slug'    => $this->slug(),
					'file'    => JET_APB_PLUGIN_BASE,
					'version' => $this->get_version(),
					'plugin_links' => array(
						array(
							'label'  => esc_html__( 'Go to settings', 'jet-elements' ),
							'url'    => add_query_arg( array( 'page' => 'jet-dashboard-settings-page', 'subpage' => 'jet-apb-general-settings' ), admin_url( 'admin.php' ) ),
							'target' => '_self',
						),
					),
				),
			) );
		}
	}

	/**
	 * [jet_dashboard_ui_instance_init description]
	 * @return [type] [description]
	 */
	public function jet_dashboard_ui_instance_init() {
		$cx_ui_module_data = jet_engine()->framework->get_included_module_data( 'cherry-x-vue-ui.php' );

		return new \CX_Vue_UI( $cx_ui_module_data );
	}

	/**
	 * Initialize plugin parts
	 *
	 * @return void
	 */
	public function init_components() {

		add_action( 'admin_enqueue_scripts', [ $this, 'register_assets' ],        0 );
		add_action( 'wp_enqueue_scripts',    [ $this, 'register_public_assets' ], 0 );
		add_action( 'init',                  [ $this, 'register_macros' ] );

		$this->db                   = new DB\Manager();
		$this->settings             = new Admin\Settings();
		$this->service_provider_relations_map = new Service_Provider_Relations_Map();
		$this->tools                = new Tools();
		$this->services_meta        = new Admin\Cpt_Meta_Box\Services_Meta();
		$this->form                 = new Form();
		$this->calendar             = new Calendar();
		$this->rest_api             = new Rest_API\Manager();
		$this->google_cal           = new Google_Calendar();
		$this->wc                   = new WC_Integration();
		$this->elementor            = new Elementor_Integration\Manager();
		$this->bricks               = new Bricks_Integration\Manager();
		$this->blocks               = new Blocks_Integration\Manager();
		$this->statuses             = new Statuses();
		$this->workflows            = new Workflows\Manager();
		$this->export               = new Export();
		$this->compatibility        = new Compatibility\Manager();

		Integrations\Manager::instance();
		Admin\Helpers\Options_Switcher::instance();

		if ( $this->settings->get( 'providers_cpt' ) ) {
			$this->providers_meta = new Admin\Cpt_Meta_Box\Providers_Meta();
		}

		if ( is_admin() ) {
			$this->setup = new Set_Up();

			//Init Settings Manager
			new \JET_APB\Admin\Settings\Manager();

			$this->dashboard = new Admin\Dashboard( array(
				new Admin\Pages\Appointments(),
			) );

			new DB_Upgrader();
		}

		new Listings();
		new Formbuilder_Plugin\Form_Builder();
		new Public_Actions\Manager();

		Cron\Manager::instance();
	}

	public function register_macros() {
		$this->macros = new Macros();
	}

	/**
	 * Page specific assets
	 *
	 * @return [type] [description]
	 */
	public function register_assets() {
		$this->register_script( 'momentjs', 'lib/moment/moment.min.js', true );
		$this->register_script( 'vuejs-datepicker', 'admin/lib/vuejs-datepicker.min.js' );
		$this->register_script( 'jet-apb-wc-details-builder', 'admin/wc-details-builder.js' );

		$this->register_style( 'vanilla-calendar', 'public/vanilla-calendar.css' );
		$this->register_style( 'jet-apb-working-hours', 'admin/working-hours.css' );
		$this->register_style( 'jet-apb-workflows', 'admin/workflows.css' );
		$this->register_style( 'jet-apb-integrations', 'admin/integrations.css' );
		$this->register_style( 'jet-apb-set-up', 'admin/set-up.css' );
		$this->register_style( 'jet-appointments-booking-admin', 'admin/jet-appointments-booking-admin.css' );
		$this->register_style( 'jet-apb-layout', 'admin/layout.css' );
	}
	/**
	 * Page specific assets
	 *
	 * @return [type] [description]
	 */
	public function register_public_assets() {

		$this->register_script( 'jet-ab-front-init', 'public/appointments-init.js' );
		$this->register_script( 'jet-ab-choices', 'lib/choices/choices.min.js', true );
		$this->register_script( 'momentjs', 'lib/moment/moment.min.js', true );

		$this->register_script( 'vanilla-calendar', 'public/vanilla-calendar.min.js' );
		$this->register_script( 'flatpickr', 'lib/flatpickr/flatpickr.js', true );

		$this->register_style( 'jet-ab-front-style', 'public/jet-appointments-booking.css' );
		$this->register_style( 'jet-ab-choices', 'lib/choices/choices.min.css', true );
		$this->register_style( 'flatpickr', 'lib/flatpickr/flatpickr.min.css', true );
		$this->register_style( 'vanilla-calendar', 'public/vanilla-calendar.css' );
	}

	/**
	 * Register script
	 *
	 * @param  [type] $handle    [description]
	 * @param  [type] $file_path [description]
	 * @return [type]            [description]
	 */
	public function register_script( $handle = null, $file_path = null, $from_root = false ) {

		$prefix = 'assets/';

		if ( ! $from_root ) {
			$prefix .= 'js/';
		}

		wp_register_script(
			$handle,
			JET_APB_URL . $prefix . $file_path,
			array( 'wp-api-fetch', 'jquery' ),
			JET_APB_VERSION,
			true
		);
	}

	/**
	 * Register style
	 *
	 * @param  [type] $handle    [description]
	 * @param  [type] $file_path [description]
	 * @return [type]            [description]
	 */
	public function register_style( $handle = null, $file_path = null, $from_root = false ) {

		$prefix = 'assets/';

		if ( ! $from_root ) {
			$prefix .= 'css/';
		}

		wp_register_style(
			$handle,
			JET_APB_URL . $prefix . $file_path,
			array(),
			JET_APB_VERSION
		);
	}

	/**
	 * Capability Filter
	 *
	 * @param  [type] $contextn [description]
	 * @return [type]           [description]
	 */
	public function current_user_can( $context = null ) {

		$default_capability = $this->settings->get('capability_type');

		return apply_filters(
			'jet-apb/current-user-can',
			current_user_can( apply_filters( 'jet-apb/capability', $default_capability, $context ) ),
			$context
		);

	}

	/**
	 * Appointment Pages Capability Filter
	 *
	 * @param  [type] $page_slug [description]
	 * @return [type]            [description]
	 */
	public function page_capability( $page_slug ) {

		$default_capability = $this->settings->get('capability_type');

		return apply_filters( "jet-apb/page/{$page_slug}/capability", $default_capability );

	}

	/**
	 * Instance.
	 *
	 * Ensures only one instance of the plugin class is loaded or can be loaded.
	 *
	 * @since 1.0.0
	 * @access public
	 * @static
	 *
	 * @return Plugin An instance of the class.
	 */
	public static function instance() {

		if ( is_null( self::$instance ) ) {

			self::$instance = new self();

		}

		return self::$instance;
	}
}

Plugin::instance();
