<?php // phpcs:disable PSR2.Classes.PropertyDeclaration.Underscore,WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedVariableFound
/**
 * WC Affiliate
 * The Most Feature-rich Affiliate Plugin for WooCommerce. Everything You Need To Run A Full-Featured Affiliate Program
 *
 * @package           WC_Affiliate
 * @author            Codexpert
 * @copyright         2024 Codexpert
 * @license           GPL-2.0-or-later
 *
 * @wordpress-plugin
 * Plugin Name:       WC Affiliate
 * Plugin URI:        https://wcaffiliate.com/?utm_campaign=plugin-uri
 * Description:       The Most Feature-rich Affiliate Plugin for WooCommerce. Everything You Need To Run A Full-Featured Affiliate Program
 * Version:           3.3.1
 * Requires at least: 6.0
 * Requires PHP:      7.4
 * Author:            Codexpert
 * Author URI:        https://codexpert.io/?utm_campaign=author-uri
 * Text Domain:       wc-affiliate
 * License:           GPL v2 or later
 * License URI:       http://www.gnu.org/licenses/gpl-2.0.txt
 */

namespace WC_Affiliate;

use Pluggable\Marketing\Deactivator;
use Pluggable\Marketing\Survey;

defined( 'ABSPATH' ) || exit;

// Load migration handler. This file:
// - Resolves and persists the user status (existing/fresh) exactly once.
// - Registers migration hooks conditionally based on Pro plugin version.
// - Loads the legacy plugin when the migration gate is active.
// - Exposes wc_affiliate_is_legacy_mode_active() used by the gate below.
require_once 'wc-affiliate-migrate.php';

add_action( 'init', 'wc_affiliate_legacy_migration_handle_notice_params' );
add_action( 'admin_enqueue_scripts', 'wc_affiliate_legacy_migration_scripts' );
add_action( 'admin_notices', 'wc_affiliate_legacy_migration_notice' );
add_action( 'rest_api_init', 'wc_affiliate_register_migration_routes' );

// Gate: if the legacy migration is active, the new plugin must not load.
// wc_affiliate_is_legacy_mode_active() is the single source of truth for
// this check — it reads options and fires the filter exactly once, having
// already been called during the require_once above. WordPress caches
// get_option() results in memory, so the repeated call has no database cost.
if ( ! wc_affiliate_is_compatible_with_pro() || wc_affiliate_is_legacy_mode_active() ) {
	require_once __DIR__ . '/legacy/wc-affiliate.php';

	return;
}

define( 'WC_AFFILIATE_VERSION', '3.3.1' );
define( 'WC_AFFILIATE_FILE', __FILE__ );
define( 'WC_AFFILIATE_BASENAME', plugin_basename( WC_AFFILIATE_FILE ) );
define( 'WC_AFFILIATE_PLUGIN_DIR', plugin_dir_path( WC_AFFILIATE_FILE ) );
define( 'WC_AFFILIATE_PLUGIN_URL', plugin_dir_url( WC_AFFILIATE_FILE ) );

require_once 'vendor/autoload.php';

/**
 * Main WC Affiliate Plugin Class
 *
 * This class serves as the main entry point for the WC Affiliate plugin.
 * It handles plugin initialization, activation, deactivation, and provides
 * access to core plugin functionality through its singleton instance.
 *
 * @since 1.0.0
 * @package WC_Affiliate
 */
final class WC_Affiliate {

	/**
	 * Singleton instance of the plugin.
	 *
	 * @since 1.0.0
	 * @var WC_Affiliate|null
	 */
	public static $_instance;

	/**
	 * Plugin configuration and metadata.
	 *
	 * Contains plugin data including version, file paths, server URLs,
	 * and other configuration settings used throughout the plugin.
	 *
	 * @since 1.0.0
	 * @var array
	 */
	public array $plugin;

	/**
	 * Constructor - Initialize the WC Affiliate plugin.
	 *
	 * Sets up the plugin by defining constants and variables,
	 * including necessary files, and registering hooks.
	 *
	 * @since 1.0.0
	 * @return void
	 */
	public function __construct() {
		$this->define();
		$this->includes();
		$this->hook();
	}

	/**
	 * Define plugin variables and constants.
	 *
	 * Sets up essential plugin configuration including plugin metadata,
	 * server endpoints, minimum requirements, and hash identifiers
	 * for marketing integrations.
	 *
	 * @since 1.0.0
	 * @return void
	 */
	public function define(): void {
		$this->plugin             = get_plugin_data( WC_AFFILIATE_FILE, true, false );
		$this->plugin['basename'] = WC_AFFILIATE_BASENAME;
		$this->plugin['file']     = WC_AFFILIATE_FILE;
		$this->plugin['server']   = apply_filters( 'wc_affiliate_server', 'https://my.pluggable.io' );
		$this->plugin['min_php']  = '7.4';
		$this->plugin['min_wp']   = '5.0';
		$this->plugin['doc_id']   = 11009;

		$this->plugin['hash_deactivator'] = '2b22ec78-14a5-4920-9a23-eba610850fe6';
		$this->plugin['hash_survey']      = '6baa92ba-2e82-47af-a5de-36681446267b';
	}

	/**
	 * Include additional plugin files and dependencies.
	 *
	 * Loads admin-specific components like survey and deactivator
	 * functionality when in the WordPress admin area.
	 *
	 * @since 1.0.0
	 * @return void
	 */
	public function includes(): void {
		if ( is_admin() ) {
			new Survey( $this->plugin );
			new Deactivator( $this->plugin );
		}
	}

	/**
	 * Register plugin hooks and activation/deactivation handlers.
	 *
	 * Sets up WordPress hooks for plugin activation, deactivation,
	 * and initialization during the WordPress loading process.
	 *
	 * @since 1.0.0
	 * @return void
	 */
	public function hook(): void {
		register_activation_hook( WC_AFFILIATE_FILE, array( $this, 'install' ) );
		register_deactivation_hook( WC_AFFILIATE_FILE, array( $this, 'uninstall' ) );

		add_action( 'plugins_loaded', array( $this, 'initialize' ) );
		add_action( 'init', array( $this, 'migrate_legacy_settings' ) );
	}

	/**
	 * Install the WC Affiliate plugin.
	 *
	 * Handles plugin installation including database setup,
	 * table creation, and initial configuration.
	 *
	 * @since 1.0.0
	 * @return void
	 */
	public function install(): void {
		Bootstrap\Installer::install();
	}

	/**
	 * Migrate legacy settings if they exist.
	 *
	 * Checks if legacy settings have already been migrated and triggers
	 * the migration process if needed. This ensures settings from previous
	 * plugin versions are properly transferred to the new structure.
	 *
	 * @since 1.0.0
	 * @return void
	 */
	public function migrate_legacy_settings(): void {
		$installer = new Bootstrap\Installer();
		$installer->migrate_legacy_settings();
		$installer->assign_affiliate_role_to_existing_users();
	}

	/**
	 * Initialize the WC Affiliate plugin.
	 *
	 * Sets up the complete plugin environment, loads all necessary
	 * components, controllers, and initializes the affiliate system.
	 *
	 * @since 1.0.0
	 * @return void
	 */
	public function initialize(): void {
		Bootstrap\Initializer::initialize();
	}

	/**
	 * Uninstall the WC Affiliate plugin.
	 *
	 * This function is triggered when the plugin is deactivated.
	 * It cleans up resources, removes database tables, options,
	 * and unregisters custom roles and capabilities.
	 *
	 * @since 1.0.0
	 * @return void
	 */
	public function uninstall(): void {
		Bootstrap\Uninstaller::uninstall();
	}

	/**
	 * Get singleton instance of the WC Affiliate plugin.
	 *
	 * Returns the single instance of the WC_Affiliate class,
	 * creating it if it doesn't already exist (Singleton pattern).
	 *
	 * @since 1.0.0
	 * @return WC_Affiliate The plugin instance.
	 */
	public static function instance(): self {
		if ( is_null( self::$_instance ) ) {
			self::$_instance = new self();
		}
		return self::$_instance;
	}
}

WC_Affiliate::instance();
