<?php
/**
 * Admin AJAX handlers for module-specific tooling endpoints.
 *
 * @package WP_PowerSuite\Core\Http\Controllers
 * @since 1.0.0
 */

namespace WP_PowerSuite\Core\Http\Controllers;

use WP_PowerSuite\Core\Http\AjaxRouter;
use WP_PowerSuite\Core\Http\Concerns\ParsesModuleAjaxInput;
use WP_PowerSuite\Core\OptionStoreModuleSettingsRepository;
use WP_PowerSuite\Core\WpConfigAuditLog;
use WP_PowerSuite\Core\WpConfigHelper;

if ( ! defined( 'ABSPATH' ) ) {
	exit;
}

final class ModuleToolsController {

	use ParsesModuleAjaxInput;

	private static ?self $instance = null;

	public static function getInstance(): self {
		if ( self::$instance === null ) {
			self::$instance = new self();
		}
		return self::$instance;
	}

	public static function register(): void {
		$controller = self::getInstance();

		AjaxRouter::registerAdminAction( 'wp_powersuite_refresh_gutenberg_blocks', [ $controller, 'refreshGutenbergBlocks' ] );
		if ( OptionStoreModuleSettingsRepository::isModuleEnabled( 'quick-debug-toggle' ) ) {
			AjaxRouter::registerAdminAction(
				'wp_powersuite_debug_toggle',
				[ $controller, 'debugToggle' ],
				WpConfigHelper::requiredManageCapability()
			);
		}
		if ( OptionStoreModuleSettingsRepository::isModuleEnabled( 'broken-link-checker' ) ) {
			AjaxRouter::registerAdminAction( 'wp_powersuite_scan_broken_links', [ $controller, 'scanBrokenLinks' ] );
		}
		AjaxRouter::registerAdminAction( 'wp_powersuite_search_users', [ $controller, 'searchUsers' ] );
		AjaxRouter::registerAdminAction( 'wp_powersuite_aln_test_email', [ $controller, 'sendLoginNotificationTestEmail' ] );

		if ( OptionStoreModuleSettingsRepository::isModuleEnabled( 'password-protection' ) ) {
			AjaxRouter::registerAdminAction( 'wp_powersuite_clear_password_gate_lockouts', [ $controller, 'clearPasswordGateLockouts' ] );
		}
	}

	public function clearPasswordGateLockouts(): void {
		if ( ! class_exists( 'PasswordProtection\\Module' ) && defined( 'WP_POWERSUITE_MODULES_DIR' ) ) {
			$module_file = WP_POWERSUITE_MODULES_DIR . 'password-protection' . DIRECTORY_SEPARATOR . 'module.php';
			if ( is_readable( $module_file ) ) {
				require_once $module_file;
			}
		}

		if ( ! class_exists( 'PasswordProtection\\Module' ) ) {
			wp_send_json_error( [ 'message' => __( 'Password Protection module could not be loaded.', 'wp-powersuite' ) ] );
		}

		$deleted = \PasswordProtection\Module::clearAllRateLimitTransients();

		wp_send_json_success(
			[
				/* translators: %d: approximate number of database rows removed */
				'message' => sprintf( __( 'Cleared lockout data (%d rows). Visitors can try the password again.', 'wp-powersuite' ), $deleted ),
				'deleted' => $deleted,
			]
		);
	}

	public function scanBrokenLinks(): void {
		if ( function_exists( 'wp_powersuite_is_license_valid' ) && ! wp_powersuite_is_license_valid() ) {
			wp_send_json_error(
				[
					'message'      => __( 'Broken Link Checker requires an active license.', 'wp-powersuite' ),
					'code'         => 'license_required',
					'license_page' => admin_url( 'admin.php?page=powersuite-license' ),
				]
			);
		}

		if ( ! OptionStoreModuleSettingsRepository::isModuleEnabled( 'broken-link-checker' ) ) {
			wp_send_json_error( [ 'message' => __( 'Module is not enabled.', 'wp-powersuite' ) ] );
		}

		$mod = $this->getBrokenLinkModule();

		$action  = isset( $_POST['scan_action'] ) ? sanitize_key( wp_unslash( $_POST['scan_action'] ) ) : 'start';
		$scan_id = isset( $_POST['scan_id'] ) ? sanitize_key( wp_unslash( $_POST['scan_id'] ) ) : '';

		$post_types = null;
		if ( $action === 'start' && isset( $_POST['post_types'] ) && is_array( $_POST['post_types'] ) ) {
			$post_types = array_map( 'sanitize_key', wp_unslash( $_POST['post_types'] ) );
			$post_types = array_values( array_filter( $post_types ) );
		}

		@set_time_limit( 90 ); // phpcs:ignore Generic.PHP.NoSilencedErrors.Discouraged -- Intentional for scan timeout

		$result = $mod->runScanAction( $action, $post_types ?: null, $scan_id );

		if ( is_wp_error( $result ) ) {
			wp_send_json_error(
				[
					'message' => $result->get_error_message(),
					'code'    => $result->get_error_code(),
				]
			);
		}

		wp_send_json_success( $result );
	}

	/**
	 * Module PHP files are not autoloaded during admin AJAX; require before use.
	 */
	private function getBrokenLinkModule(): \BrokenLinkChecker\Module {
		if ( ! class_exists( '\BrokenLinkChecker\Module', false ) && defined( 'WP_POWERSUITE_MODULES_DIR' ) ) {
			$module_file = WP_POWERSUITE_MODULES_DIR . 'broken-link-checker' . DIRECTORY_SEPARATOR . 'module.php';
			if ( is_readable( $module_file ) ) {
				require_once $module_file;
			}
		}

		if ( ! class_exists( '\BrokenLinkChecker\Module', false ) ) {
			wp_send_json_error(
				[
					'message' => __( 'Broken Link Checker module could not be loaded.', 'wp-powersuite' ),
					'code'    => 'module_not_found',
				]
			);
		}

		\BrokenLinkChecker\Module::loadDependencies();

		return new \BrokenLinkChecker\Module();
	}

	public function searchUsers(): void {
		$term      = isset( $_POST['term'] ) ? sanitize_text_field( wp_unslash( $_POST['term'] ) ) : '';
		$is_search = strlen( $term ) >= 2;

		if ( $is_search ) {
			$query = new \WP_User_Query(
				[
					'search'         => '*' . $term . '*',
					'search_columns' => [ 'user_login', 'user_email', 'display_name' ],
					'number'         => 50,
					'orderby'        => 'display_name',
					'order'          => 'ASC',
					'fields'         => [ 'ID', 'user_login', 'display_name' ],
				]
			);
		} else {
			$query = new \WP_User_Query(
				[
					'number'  => 100,
					'orderby' => 'display_name',
					'order'   => 'ASC',
					'fields'  => [ 'ID', 'user_login', 'display_name' ],
				]
			);
		}

		$users = [];
		foreach ( $query->get_results() as $user ) {
			$id           = 0;
			$user_login   = '';
			$display_name = '';

			if ( $user instanceof \WP_User ) {
				$id           = (int) $user->ID;
				$user_login   = (string) $user->user_login;
				$display_name = (string) $user->display_name;
			} elseif ( is_object( $user ) ) {
				$id           = (int) ( $user->ID ?? 0 );
				$user_login   = (string) ( $user->user_login ?? '' );
				$display_name = (string) ( $user->display_name ?? '' );
			}

			if ( $id <= 0 ) {
				continue;
			}

			if ( $display_name === '' ) {
				$display_name = $user_login !== '' ? $user_login : (string) $id;
			}

			$users[] = [
				'id'           => $id,
				'user_login'   => $user_login,
				'display_name' => $display_name,
				'label'        => $display_name . ( $user_login !== '' ? ' (' . $user_login . ')' : '' ),
				'value'        => (string) $id,
			];
		}

		wp_send_json_success( [ 'users' => $users ] );
	}

	public function refreshGutenbergBlocks(): void {
		if ( function_exists( 'wp_powersuite_is_license_valid' ) && ! wp_powersuite_is_license_valid() ) {
			wp_send_json_error(
				[
					'message'      => __( 'Gutenberg Block Control requires an active license.', 'wp-powersuite' ),
					'code'         => 'license_required',
					'license_page' => admin_url( 'admin.php?page=powersuite-license' ),
				]
			);
		}

		$module_id = $this->getPostedModuleId();
		if ( $module_id === '' || $module_id !== 'gutenberg-block-control' ) {
			wp_send_json_error(
				[
					'message' => __( 'Invalid module ID provided.', 'wp-powersuite' ),
					'code'    => 'invalid_module_id',
				]
			);
		}

		if ( ! class_exists( 'GutenbergBlockControl\\Module' ) && defined( 'WP_POWERSUITE_MODULES_DIR' ) ) {
			$module_file = WP_POWERSUITE_MODULES_DIR . 'gutenberg-block-control' . DIRECTORY_SEPARATOR . 'module.php';
			if ( is_readable( $module_file ) ) {
				require_once $module_file;
			}
		}

		if ( ! class_exists( 'GutenbergBlockControl\\Module' ) ) {
			wp_send_json_error(
				[
					'message' => __( 'Gutenberg Block Control module could not be loaded.', 'wp-powersuite' ),
					'code'    => 'module_not_found',
				]
			);
		}

		delete_transient( \GutenbergBlockControl\Module::getBlocksCacheKey() );

		$blocks_by_category = \GutenbergBlockControl\Module::buildAndCacheBlocks( \GutenbergBlockControl\Module::getBlocksCacheKey() );
		$settings           = OptionStoreModuleSettingsRepository::forModule( $module_id )->all( [] );
		$disabled_blocks    = is_array( $settings['disabled_blocks'] ?? null ) ? $settings['disabled_blocks'] : [];

		wp_send_json_success(
			[
				'html'       => \GutenbergBlockControl\Module::renderBlockListHtml( $blocks_by_category, $disabled_blocks ),
				'has_blocks' => $blocks_by_category !== [],
				'message'    => __( 'Blocks refreshed successfully.', 'wp-powersuite' ),
			]
		);
	}

	public function debugToggle(): void {
		if ( ! OptionStoreModuleSettingsRepository::isModuleEnabled( 'quick-debug-toggle' ) ) {
			wp_send_json_error( [ 'message' => __( 'Quick Debug Toggle module is not enabled.', 'wp-powersuite' ) ] );
		}

		if ( ! WpConfigHelper::canManageWpConfig() ) {
			wp_send_json_error( [ 'message' => __( 'You do not have permission to edit debug configuration.', 'wp-powersuite' ) ] );
		}

		$action    = isset( $_POST['debug_action'] ) ? sanitize_key( wp_unslash( $_POST['debug_action'] ) ) : '';
		$operation = isset( $_POST['operation'] ) ? sanitize_key( wp_unslash( $_POST['operation'] ) ) : '';

		$mod = $this->getQuickDebugModule();

		if ( $operation === 'clear_log' ) {
			$result = $mod->clearDebugLog();
			if ( $result['success'] ) {
				WpConfigAuditLog::log( 'quick-debug-toggle', 'clear_log', __( 'Cleared debug.log from the dashboard.', 'wp-powersuite' ) );
				wp_send_json_success( [ 'message' => $result['message'] ] );
			}
			wp_send_json_error( [ 'message' => $result['message'] ] );
		}

		if ( $operation === 'protect_log' ) {
			$result = $mod->protectDebugLog();
			if ( $result['success'] ) {
				WpConfigAuditLog::log( 'quick-debug-toggle', 'protect_log', $result['message'] );
				wp_send_json_success( [ 'message' => $result['message'] ] );
			}
			wp_send_json_error( [ 'message' => $result['message'] ] );
		}

		if ( $operation === 'get_log' ) {
			$result = $mod->getDebugLogContent();
			if ( $result['success'] ) {
				wp_send_json_success(
					[
						'content'    => $result['content'],
						'truncated'  => $result['truncated'] ?? false,
						'total_size' => $result['total_size'] ?? 0,
					]
				);
			}
			wp_send_json_error( [ 'message' => $result['message'] ] );
		}

		if ( $operation === 'toggle_constant' ) {
			$constant = isset( $_POST['constant'] ) ? sanitize_text_field( wp_unslash( $_POST['constant'] ) ) : '';
			$value    = isset( $_POST['value'] ) && $_POST['value'] === '1';
			$allowed  = [ 'WP_DEBUG', 'WP_DEBUG_LOG', 'WP_DEBUG_DISPLAY' ];
			if ( ! in_array( $constant, $allowed, true ) ) {
				wp_send_json_error( [ 'message' => __( 'Invalid constant.', 'wp-powersuite' ) ] );
			}

			if ( $constant === 'WP_DEBUG_DISPLAY' && $value && WpConfigHelper::isProductionEnvironment() ) {
				$confirmed = isset( $_POST['confirm_production_display'] )
					&& sanitize_key( wp_unslash( $_POST['confirm_production_display'] ) ) === '1';
				if ( ! $confirmed ) {
					wp_send_json_error(
						[
							'message' => __( 'Enabling WP_DEBUG_DISPLAY on a production site exposes errors to visitors. Confirmation required.', 'wp-powersuite' ),
							'code'    => 'production_display_blocked',
						]
					);
				}
			}

			$result = $mod->toggleConstant( $constant, $value );
			if ( $result['success'] ) {
				WpConfigAuditLog::log(
					'quick-debug-toggle',
					'toggle_constant',
					sprintf(
						/* translators: 1: constant name, 2: enabled or disabled */
						__( 'Set %1$s to %2$s in wp-config.php.', 'wp-powersuite' ),
						$constant,
						$value ? 'true' : 'false'
					)
				);
				wp_send_json_success( [ 'message' => $result['message'] ] );
			}
			wp_send_json_error( [ 'message' => $result['message'] ] );
		}

		if ( ! in_array( $action, [ 'enable', 'disable' ], true ) ) {
			wp_send_json_error( [ 'message' => __( 'Invalid action.', 'wp-powersuite' ) ] );
		}

		$result = $action === 'enable' ? $mod->enableDebug() : $mod->disableDebug();
		if ( $result['success'] ) {
			WpConfigAuditLog::log(
				'quick-debug-toggle',
				$action === 'enable' ? 'enable_debug' : 'disable_debug',
				$action === 'enable'
					? __( 'Enabled Quick Debug block in wp-config.php.', 'wp-powersuite' )
					: __( 'Removed Quick Debug block from wp-config.php.', 'wp-powersuite' )
			);
			wp_send_json_success( [ 'message' => $result['message'] ] );
		}
		wp_send_json_error( [ 'message' => $result['message'] ] );
	}

	/**
	 * Module PHP files are not autoloaded during admin AJAX; require before use.
	 */
	private function getQuickDebugModule(): \QuickDebugToggle\Module {
		if ( ! class_exists( '\QuickDebugToggle\Module', false ) && defined( 'WP_POWERSUITE_MODULES_DIR' ) ) {
			$module_file = WP_POWERSUITE_MODULES_DIR . 'quick-debug-toggle' . DIRECTORY_SEPARATOR . 'module.php';
			if ( is_readable( $module_file ) ) {
				require_once $module_file;
			}
		}

		if ( ! class_exists( '\QuickDebugToggle\Module', false ) ) {
			wp_send_json_error(
				[
					'message' => __( 'Quick Debug Toggle module could not be loaded.', 'wp-powersuite' ),
					'code'    => 'module_not_found',
				]
			);
		}

		return new \QuickDebugToggle\Module();
	}

	public function sendLoginNotificationTestEmail(): void {
		if ( function_exists( 'wp_powersuite_is_license_valid' ) && ! wp_powersuite_is_license_valid() ) {
			wp_send_json_error(
				[
					'message'      => __( 'Admin Login Alerts requires an active license.', 'wp-powersuite' ),
					'code'         => 'license_required',
					'license_page' => admin_url( 'admin.php?page=powersuite-license' ),
				]
			);
		}

		if ( ! OptionStoreModuleSettingsRepository::isModuleEnabled( 'login-email-notification' ) ) {
			wp_send_json_error( [ 'message' => __( 'Module is not enabled.', 'wp-powersuite' ) ] );
		}

		if ( ! class_exists( \LoginEmailNotification\Module::class, false ) && defined( 'WP_POWERSUITE_MODULES_DIR' ) ) {
			$mod_file = WP_POWERSUITE_MODULES_DIR . 'login-email-notification' . DIRECTORY_SEPARATOR . 'module.php';
			if ( is_readable( $mod_file ) ) {
				require_once $mod_file;
			}
		}

		if ( ! class_exists( \LoginEmailNotification\Module::class, false ) ) {
			wp_send_json_error( [ 'message' => __( 'Admin Login Notification module could not be loaded.', 'wp-powersuite' ) ] );
		}

		$module = new \LoginEmailNotification\Module();
		$module->sendTestEmail();
	}
}
