<?php
/**
 * Main plugin class
 *
 * @package ZeroSpam
 */

namespace ZeroSpam;

// Security Note: Blocks direct access to the plugin PHP files.
defined( 'ABSPATH' ) || die();

/**
 * Main plugin class
 */
class Plugin {

	/**
	 * Instance
	 *
	 * @var Plugin
	 */
	public static $instance = null;

	/**
	 * Constructor
	 */
	private function __construct() {
		$this->register_autoloader();
		$this->init_modules();

		add_filter( 'zerospam_types', array( $this, 'types' ), 10, 1 );
		add_filter( 'zerospam_failed_types', array( $this, 'failed_types' ), 10, 1 );
		add_action( 'zero_spam_flagged_attempt', array( $this, 'flagged_attempt' ), 10, 3 );
	}

	/**
	 * Register autoloader
	 */
	private function register_autoloader() {
		require_once ZEROSPAM_PATH . 'includes/class-autoloader.php';

		Autoloader::run();
	}

	/**
	 * Instance
	 */
	public static function instance() {
		if ( is_null( self::$instance ) ) {
			self::$instance = new self();
		}

		return self::$instance;
	}

	/**
	 * Add to failed types
	 *
	 * @param array $types Array of failed types.
	 */
	public function failed_types( $types ) {
		$types['honeypot']             = __( 'Honeypot', 'zero-spam' );
		$types['blocked_email_domain'] = __( 'Blocked Email Domain', 'zero-spam' );
		$types['blocked']              = __( 'Blocked IP', 'zero-spam' );

		return $types;
	}

	/**
	 * Initializes modules
	 */
	private function init_modules() {
		// Debug module
		new \ZeroSpam\Modules\Debug();

		if ( is_admin() ) {
			// Plugin admin module.
			new \ZeroSpam\Core\Admin\Admin();
		}

		// Register REST API routes.
		add_action( 'rest_api_init', array( $this, 'register_rest_routes' ) );

		// Preform the firewall access check.
		new \ZeroSpam\Core\Access();

		// Database functionality.
		new \ZeroSpam\Includes\DB();

		// Updates functionality.
		new \ZeroSpam\Includes\Updates();

		// Site security
		new \ZeroSpam\Modules\Security\Security();

		// Zero Spam module.
		new \ZeroSpam\Modules\Zero_Spam();

		// API Monitoring module.
		new \ZeroSpam\Modules\API_Monitoring();

		// API Usage Alerts.
		new \ZeroSpam\Includes\API_Usage_Alerts();

		// Unified Dashboard Widget - use plugins_loaded for multisite compatibility.
		if ( is_admin() ) {
			add_action( 'plugins_loaded', array( $this, 'init_dashboard_widget' ), 20 );
		}

		// Network Statistics Page (multisite only).
		if ( is_admin() && is_multisite() ) {
			new \ZeroSpam\Includes\Admin\Network_Stats_Page();
		}

		// Network Settings Page (multisite only).
		if ( is_admin() && is_multisite() ) {
			new \ZeroSpam\Includes\Admin\Network_Settings_Page();
		}

		// Site Admin Overrides (multisite only).
		if ( is_admin() && is_multisite() && ! is_network_admin() ) {
			new \ZeroSpam\Includes\Admin\Site_Admin_Overrides();
		}

		// Stats Aggregation (multisite only).
		if ( is_multisite() ) {
			new \ZeroSpam\Includes\Stats_Aggregator();
		}

		// Network Settings (multisite only).
		if ( is_multisite() ) {
			new \ZeroSpam\Includes\Network_Settings();
			new \ZeroSpam\Includes\Network_Notifications();
		}

		// Stop Forum Spam module.
		new \ZeroSpam\Modules\StopForumSpam();

		// Project Honeypot module.
		new \ZeroSpam\Modules\ProjectHoneypot();

		// ipbase module
		new \ZeroSpam\Modules\ipbase\ipbase();

		// IPinfo module.
		new \ZeroSpam\Modules\IPinfoModule();

		// ipstack module.
		new \ZeroSpam\Modules\ipstack();

		if ( is_admin() ) {
			// Google API module.
			new \ZeroSpam\Modules\Google();
		}

		// David Walsh module.
		new \ZeroSpam\Modules\DavidWalsh\DavidWalsh();

		// WordPress comments module.
		new \ZeroSpam\Modules\Comments\Comments();

		// WordPress registration module.
		new \ZeroSpam\Modules\Registration\Registration();

		// WordPress login module.
		new \ZeroSpam\Modules\Login\Login();

		// Used to check if a plugin is installed & active.
		include_once ABSPATH . 'wp-admin/includes/plugin.php';

		// GiveWP plugin module.
		if ( is_plugin_active( 'give/give.php' ) ) {
			new \ZeroSpam\Modules\Give\Give();
		}

		// Contact Form 7 plugin module.
		if ( is_plugin_active( 'contact-form-7/wp-contact-form-7.php' ) ) {
			new \ZeroSpam\Modules\ContactForm7\ContactForm7();
		}

		// WPForms plugin module.
		if (
			is_plugin_active( 'wpforms-lite/wpforms.php' ) ||
			is_plugin_active( 'wpforms/wpforms.php' )
		) {
			new \ZeroSpam\Modules\WPForms\WPForms();
		}

		// Formidable plugin module.
		if ( is_plugin_active( 'formidable/formidable.php' ) ) {
			new \ZeroSpam\Modules\Formidable\Formidable();
		}

		// Fluent Forms plugin module.
		if ( is_plugin_active( 'fluentform/fluentform.php' ) ) {
			new \ZeroSpam\Modules\FluentForms\FluentForms();
		}

		// Mailchimp for WordPress plugin module.
		if ( is_plugin_active( 'mailchimp-for-wp/mailchimp-for-wp.php' ) ) {
			new \ZeroSpam\Modules\MailchimpForWP\MailchimpForWP();
		}

		// Zero Spam WooCommerce module.
		if ( is_plugin_active( 'woocommerce/woocommerce.php' ) ) {
			new \ZeroSpam\Modules\WooCommerce\WooCommerce();
		}

		// Zero Spam Gravity Forms module.
		if ( is_plugin_active( 'gravityforms/gravityforms.php' ) ) {
			new \ZeroSpam\Modules\GravityForms\GravityForms();
		}

		// Zero Spam Gravity Forms module.
		if ( is_plugin_active( 'wp-user-avatar/wp-user-avatar.php' ) ) {
			new \ZeroSpam\Modules\WPUserAvatar\WPUserAvatar();
		}
	}

	/**
	 * Add to the types array
	 *
	 * @param array $types Types of detections.
	 */
	public function types( $types ) {
		$types['blocked'] = array(
			'label' => __( 'Blocked', 'zero-spam' ),
		);

		return $types;
	}

	/**
	 * Register REST API routes.
	 */
	public function register_rest_routes() {
		$settings_controller = new \ZeroSpam\Includes\Rest\Settings_Controller();
		$settings_controller->register_routes();

		$api_usage_controller = new \ZeroSpam\Includes\Rest\API_Usage_Controller();
		$api_usage_controller->register_routes();

		// Network Settings REST API (multisite only).
		if ( is_multisite() ) {
			$network_settings_controller = new \ZeroSpam\Includes\Rest\Network_Settings_Controller();
			$network_settings_controller->register_routes();
		}
	}

	/**
	 * Action taken for flagged attempts
	 *
	 * @param string $module The associated module.
	 * @param string $signal The associated signal.
	 * @param array  $data   Additional attempt data.
	 */
	public function flagged_attempt( $module, $signal, $data ) {
		$details = array(
			'type'   => $module,
			'failed' => $signal,
			'data'   => $data,
		);

		if ( 'enabled' === \ZeroSpam\Core\Settings::get_settings( $module . '_log_flagged_attempts' ) ) {
			\ZeroSpam\Includes\DB::log( $module, $details );
		}

		if ( 'enabled' === \ZeroSpam\Core\Settings::get_settings( 'share_data' ) ) {
			do_action( 'zerospam_share_detection', $details );
		}
	}

	/**
	 * Initialize dashboard widget
	 *
	 * Called on init hook to ensure multisite context is properly set up.
	 */
	public function init_dashboard_widget() {
		new \ZeroSpam\Core\Admin\Dashboard_Widget();
	}
}

Plugin::instance();
