<?php

/**
 * 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       https://mediahubster.in
 * @since      1.0.0
 *
 * @package    Subs_Sys
 * @subpackage Subs_Sys/includes
 */

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

/**
 * 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    Subs_Sys
 * @subpackage Subs_Sys/includes
 * @author     Joe Youngblood <support@subscriptionplugin.com>
 */
class Subs_Sys {

	/**
	 * The loader that's responsible for maintaining and registering all hooks that power
	 * the plugin.
	 *
	 * @since    1.0.0
	 * @access   protected
	 * @var      Subs_Sys_Loader    $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    $plugin_name    The string used to uniquely identify this plugin.
	 */
	protected $plugin_name;

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

	/**
	 * 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( 'SUBS_SYS_VERSION' ) ) {
			$this->version = SUBS_SYS_VERSION;
		} else {
			$this->version = '1.0.18';
		}
		$this->plugin_name = 'subs-sys';

		$this->load_dependencies();
		$this->set_locale();
		$this->define_admin_hooks();
		$this->define_public_hooks();
	}

	/**
	 * Load the required dependencies for this plugin.
	 *
	 * Include the following files that make up the plugin:
	 *
	 * - Subs_Sys_Loader. Orchestrates the hooks of the plugin.
	 * - Subs_Sys_I18n. Defines internationalization functionality.
	 * - Subs_Sys_Admin. Defines all hooks for the admin area.
	 * - Subs_Sys_Public. Defines all hooks for the public side of the site.
	 *
	 * Create an instance of the loader which will be used to register the hooks
	 * with WordPress.
	 *
	 * @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 __DIR__ . '/class-subs-sys-loader.php';

		/**
		 * The class responsible for defining internationalization functionality
		 * of the plugin.
		 */
		require_once __DIR__ . '/class-subs-sys-i18n.php';

		/**
		 * The class responsible for defining all actions that occur in the admin area.
		 */
		require_once __DIR__ . '/../admin/class-subs-sys-admin.php';

		/**
		 * The class responsible for defining all actions that occur in the public-facing
		 * side of the site.
		 */
		require_once __DIR__ . '/../public/class-subs-sys-public.php';

		/**
		 * The class responsible for handling subscriptions
		 */
		require_once __DIR__ . '/class-subs-sys-manager.php';

		/**
		 * The class responsible for database operations
		 */
		require_once __DIR__ . '/class-subs-sys-db.php';

		/**
		 * The class responsible for handling AJAX requests
		 */
		require_once __DIR__ . '/class-subs-sys-ajax.php';

		/**
		 * The class responsible for handling Stripe webhooks
		 */
		require_once __DIR__ . '/class-subs-sys-webhook.php';

		/**
		 * The class responsible for SMTP email handling
		 */
		require_once __DIR__ . '/class-subs-sys-smtp.php';

		/**
		 * The class responsible for Stripe integration
		 */
		require_once __DIR__ . '/class-subs-sys-stripe.php';

		/**
		 * The class responsible for handling shortcodes
		 */
		require_once __DIR__ . '/class-subs-sys-shortcodes.php';

		/**
		 * The class responsible for handling orders
		 */
		require_once __DIR__ . '/class-subs-sys-order.php';

		/**
		 * The class responsible for handling admin menu
		 */
		require_once __DIR__ . '/class-admin-menu.php';

		/**
		 * The class responsible for content-based subscriptions
		 */
		require_once __DIR__ . '/class-subs-sys-content-manager.php';

		/**
		 * The class responsible for category/tag interest subscriptions
		 */
		require_once __DIR__ . '/class-subs-sys-interest-subscription.php';

	/**
	 * The class responsible for safe database updates
	 */
	require_once __DIR__ . '/class-subs-sys-db-updater.php';

	/**
	 * The class responsible for email logging
	 */
	require_once __DIR__ . '/class-subs-sys-email-logger.php';

	$this->loader = new Subs_Sys_Loader();
}

	/**
	 * Define the locale for this plugin for internationalization.
	 *
	 * Uses the Subs_Sys_I18n class in order to set the domain and to register the hook
	 * with WordPress.
	 *
	 * @since    1.0.0
	 * @access   private
	 */
	private function set_locale() {
		$plugin_i18n = new Subs_Sys_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 Subs_Sys_Admin($this->get_plugin_name(), $this->get_version());

		// Admin 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');

		// Admin menus are now registered via register_admin_menus() in the admin class constructor
		// This ensures proper ordering and prevents duplicates

		// Register settings
		$this->loader->add_action('admin_init', $plugin_admin, 'register_settings');

		// Handle AJAX requests
		$this->loader->add_action('wp_ajax_subscription_action', $plugin_admin, 'handle_ajax_request');
		$this->loader->add_action('wp_ajax_nopriv_subscription_action', $plugin_admin, 'handle_ajax_request');

		// Add Stripe mode indicator to admin bar
		$this->loader->add_action('admin_bar_menu', $plugin_admin, 'add_stripe_mode_indicator', 100);

		// Register AJAX handlers for Stripe
		$this->loader->add_action('wp_ajax_test_stripe_connection', $plugin_admin, 'ajax_test_stripe_connection');
		$this->loader->add_action('wp_ajax_install_stripe_sdk', $plugin_admin, 'ajax_install_stripe_sdk');
		$this->loader->add_action('wp_ajax_sync_plan_with_stripe', $plugin_admin, 'ajax_sync_plan_with_stripe');
		$this->loader->add_action('wp_ajax_check_stripe_api_key', $plugin_admin, 'ajax_check_stripe_api_key');
	}

	/**
	 * 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 Subs_Sys_Public( $this->get_plugin_name(), $this->get_version() );
		
		// Public scripts and styles
		$this->loader->add_action('wp_enqueue_scripts', $plugin_public, 'enqueue_styles');
		$this->loader->add_action('wp_enqueue_scripts', $plugin_public, 'enqueue_scripts');
		
		// Shortcodes
		$this->loader->add_action('init', $plugin_public, 'register_shortcodes');
		
		// Public AJAX handlers
		$this->loader->add_action('wp_ajax_ss_subscribe', $plugin_public, 'ajax_subscribe');
		$this->loader->add_action('wp_ajax_nopriv_ss_subscribe', $plugin_public, 'ajax_subscribe');

		// Create the shortcodes instance and register shortcodes
		$plugin_shortcodes = new Subs_Sys_Shortcodes($this->get_plugin_name(), $this->get_version());
		
		// Register AJAX handlers for login and registration
		$this->loader->add_action('wp_ajax_nopriv_subs_sys_register', $plugin_shortcodes, 'process_registration');
		$this->loader->add_action('wp_ajax_nopriv_subs_sys_login', $plugin_shortcodes, 'process_login');
		
		// Hide admin bar for non-admin users
		$this->loader->add_action('after_setup_theme', $this, 'hide_admin_bar_for_subscribers');
		
		// Redirect non-admin users away from wp-admin
		$this->loader->add_action('admin_init', $this, 'redirect_non_admin_users');

		// Register webhook handler
		$plugin_webhook = new Subs_Sys_Webhook();

		// Initialize content subscription manager
		$content_manager = new Subs_Sys_Content_Manager();

		// Initialize interest subscription manager
		$interest_subscription = new Subs_Sys_Interest_Subscription();

		// Initialize database updater (safe updates)
		$db_updater = new Subs_Sys_DB_Updater();

		// Initialize AJAX handlers
		$plugin_ajax = new Subs_Sys_Ajax();
	}

	/**
	 * Hide the admin bar for non-admin users
	 *
	 * @since    1.0.0
	 */
	public function hide_admin_bar_for_subscribers() {
		if (!current_user_can('administrator') && !is_admin()) {
			show_admin_bar(false);
		}
	}

	/**
	 * Redirect non-admin users away from the admin area
	 *
	 * @since    1.0.0
	 */
	public function redirect_non_admin_users() {
		if (!current_user_can('administrator') && !wp_doing_ajax()) {
			wp_redirect(home_url());
			exit;
		}
	}

	/**
	 * 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 get_plugin_name() {
		return $this->plugin_name;
	}

	/**
	 * The reference to the class that orchestrates the hooks with the plugin.
	 *
	 * @since     1.0.0
	 * @return    Subs_Sys_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
	 * @return    string    The version number of the plugin.
	 */
	public function get_version() {
		return $this->version;
	}

	/**
	 * Log debug information
	 *
	 * @param string $message The message to log
	 * @param mixed $data Optional data to include
	 */
	public static function debug_log($message, $data = null) {
		if (get_option('subscription_debug_mode', 0)) {
			$log_message = '[Subscription System] ' . $message;
			
			if ($data !== null) {
				$log_message .= ': ' . (is_array($data) || is_object($data) ? wp_json_encode($data) : $data);
			}
			
			// Only log in debug mode - this is intentional debug code
			error_log($log_message); // phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_error_log
		}
	}

	/**
	 * Register the webhook endpoint
	 */
	public function register_webhook_endpoint() {
		add_rewrite_rule(
			'^subscription-webhook/?$',
			'index.php?subscription_webhook=1',
			'top'
		);
		
		add_rewrite_tag('%subscription_webhook%', '([0-9]+)');
		
		// Flush rewrite rules only once
		if (!get_option('subscription_webhook_rewrite_rules_flushed')) {
			flush_rewrite_rules();
			update_option('subscription_webhook_rewrite_rules_flushed', true);
		}
	}

	/**
	 * Handle the webhook request
	 */
	public function handle_webhook_request($query) {
		if (!isset($query->query_vars['subscription_webhook']) || !$query->query_vars['subscription_webhook']) {
			return;
		}
		
		// Get the Stripe signature from headers with proper sanitization
		$signature = '';
		if (isset($_SERVER['HTTP_STRIPE_SIGNATURE'])) {
			$signature = sanitize_text_field(wp_unslash($_SERVER['HTTP_STRIPE_SIGNATURE']));
		}
		
		// Get the webhook secret from options
		$webhook_secret = get_option('subscription_stripe_webhook_secret');
		
		// Get the raw POST data
		$payload = file_get_contents('php://input');
		
		// Initialize Stripe
		$stripe = new Subs_Sys_Stripe();
		
		// Verify and process the webhook
		$event = $stripe->verify_webhook($payload, $signature, $webhook_secret);
		
		if ($event) {
			$stripe->handle_webhook_event($event);
			http_response_code(200);
		} else {
			http_response_code(400);
		}
		
		exit;
	}
}
