<?php

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

final class iron_security_General_Security {

	const OPTION_NAME = 'wpironis_options';
	const HEADER_MAP = [
		'contentTypeOptions'      => 'wpironis_security_header_content_type_options',
		'frameOptions'            => 'wpironis_security_header_frame_options',
		'xssProtection'           => 'wpironis_security_header_xss_protection',
		'strictTransportSecurity' => 'wpironis_security_header_strict_transport_security',
		'referrerPolicy'          => 'wpironis_security_header_referrer_policy',
		'contentSecurityPolicy'   => 'wpironis_security_header_content_security_policy',
		'permissionsPolicy'       => 'wpironis_security_header_permissions_policy',
	];
	private WpironHelper $helpers;

	public function __construct(WpironHelper $helpers ) {
		$this->helpers = $helpers;
	}

	public function modifyHtaccessForAiBots( $enabled ) {
		$htaccess_path = ABSPATH . '.htaccess';

		$ai_bot_rules = "\n# Ultimate AI Bot Block List\n" .
		                "<IfModule mod_rewrite.c>\n" .
		                "    RewriteEngine On\n" .
		                "    RewriteCond %{HTTP_USER_AGENT} (\.ai\ |Agentic|AI\ Article\ Writer|AI\ Content\ Detector|AI\ Dungeon|AI\ Search\ Engine|AI\ SEO\ Crawler|AI\ Writer|AI21\ Labs|AI2Bot|AIBot|AIMatrix|AISearchBot|AI\ Training|AITraining|Alexa|Alpha\ AI|AlphaAI|Amazon\ Bedrock|Amazon-Kendra) [NC,OR]\n" .
		                "    RewriteCond %{HTTP_USER_AGENT} (Amazon\ Lex|Amazon\ Comprehend|Amazon\ Sagemaker|Amazon\ Silk|Amazon\ Textract|AmazonBot|Amelia|AndersPinkBot|Anthropic|AnyPicker|Anyword|Applebot|Aria\ Browse|Articoolo|Automated\ Writer|AwarioRssBot|AwarioSmartBot|BardBot|BingAI|Bingbot-chat) [NC,OR]\n" .
		                "    RewriteCond %{HTTP_USER_AGENT} (Brave\ Leo|ByteDance|Bytespider|CatBoost|CC-Crawler|CCBot|ChatGLM|Chinchilla|Claude|ClearScope|Cohere|Common\ Crawl|CommonCrawl|Content\ Harmony|Content\ King|Content\ Optimizer|Content\ Samurai|ContentAtScale|ContentBot|Contentedge) [NC,OR]\n" .
		                "    RewriteCond %{HTTP_USER_AGENT} (Conversion\ AI|Copilot|CopyAI|Copymatic|Copyscape|Cotoyogi|CrawlQ\ AI|Crawlspace|Crew\ AI|CrewAI|DALL-E|DataForSeoBot|DataProvider|DeepAI|DeepL|DeepMind|DeepSeek|Diffbot|Doubao\ AI|DuckAssistBot) [NC,OR]\n" .
		                "    RewriteCond %{HTTP_USER_AGENT} (FacebookBot|FacebookExternalHit|Firecrawl|Flyriver|Frase\ AI|FriendlyCrawler|Gemini|Gemma|GenAI|Google\ Bard\ AI|Google-CloudVertexBot|Google-Extended|GoogleOther|Goose|GPT|Grammarly|Grendizer|Grok|GT\ Bot|GTBot) [NC,OR]\n" .
		                "    RewriteCond %{HTTP_USER_AGENT} (Hemingway\ Editor|Hugging\ Face|Hypotenuse\ AI|iaskspider|ICC-Crawler|ImagesiftBot|img2dataset|INK\ Editor|INKforall|IntelliSeek|Inferkit|ISSCyberRiskCrawler|JasperAI|Kafkai|Kangaroo|Keyword\ Density\ AI|KomoBot|LLaMA|magpie-crawler|MarketMuse) [NC,OR]\n" .
		                "    RewriteCond %{HTTP_USER_AGENT} (Meltwater|Meta\ AI|Meta-AI|Meta-External|MetaAI|MetaTagBot|Mistral|Narrative|NeevaBot|Neural\ Text|NeuralSEO|OAI-SearchBot|Omgili|Open\ AI|OpenAI|OpenBot|OpenText\ AI|Outwrite|Page\ Analyzer\ AI|PanguBot) [NC,OR]\n" .
		                "    RewriteCond %{HTTP_USER_AGENT} (Paperlibot|Paraphraser\.io|PerplexityBot|PetalBot|Phindbot|PiplBot|ProWritingAid|QuillBot|RobotSpider|Rytr|SaplingAI|Scalenut|Scraper|Scrapy|ScriptBook|SEO\ Content\ Machine|SEO\ Robot|Sentibot|Sidetrade|Simplified\ AI) [NC,OR]\n" .
		                "    RewriteCond %{HTTP_USER_AGENT} (Skydancer|SlickWrite|Spin\ Rewriter|Spinbot|Stability|StableDiffusionBot|Sudowrite|Surfer\ AI|Text\ Blaze|TextCortex|The\ Knowledge\ AI|Timpibot|Vidnami\ AI|Webzio|Whisper|WordAI|Wordtune|WormsGTP|WPBot|Writecream) [NC,OR]\n" .
		                "    RewriteCond %{HTTP_USER_AGENT} (WriterZen|Writescope|Writesonic|xAI|xBot|YouBot|Zero\ GTP|Zerochat|Zimm) [NC]\n" .
		                "    RewriteRule (.*) - [F,L]\n" .
		                "</IfModule>\n";

		if ( ! file_exists( $htaccess_path ) ) {
			return false;
		}

		$htaccess_content = file_get_contents( $htaccess_path );
		$cleaned_content = preg_replace( '/\n?# Ultimate AI Bot Block List.*?<\/IfModule>\n/s', '', $htaccess_content );

		if ( $enabled ) {
			$new_content = $cleaned_content . $ai_bot_rules;
		} else {
			$new_content = $cleaned_content;
		}

		if ( $new_content !== $htaccess_content ) {
			file_put_contents( $htaccess_path, $new_content );
		}

		return true;
	}

	public function settingsFields( $self ) {
		add_settings_section(
			'wpironis_general_section',
			'',
			false,
			'wpironis_general'
		);
		add_settings_field(
			'wpironis_disable_xmlrpc',
			'Disable XML-RPC',
			false,
			'wpironis_general',
			'wpironis_general_section'
		);
		add_settings_field(
			'wpironis_disable_php_uploads',
			'Disable PHP files in uploads folder',
			false,
			'wpironis_general',
			'wpironis_general_section'
		);
		add_settings_field(
			'wpironis_block_ai_bots',
			'Block AI Bots',
			false,
			'wpironis_general',
			'wpironis_general_section'
		);
	}

	public function wpironis_create_htaccess() {
		$upload_dir    = wp_upload_dir();
		$htaccess_path = $upload_dir['basedir'] . '/.htaccess';

		$htaccess_content = "  
		<Files *.php>
		    deny from all
		</Files>
		";

		if ( ! file_exists( $htaccess_path ) ) {
			file_put_contents( $htaccess_path, $htaccess_content );
		}
	}

	public function wpironis_remove_htaccess() {
		$upload_dir    = wp_upload_dir();
		$htaccess_path = $upload_dir['basedir'] . '/.htaccess';

		if ( file_exists( $htaccess_path ) ) {
			wp_delete_file( $htaccess_path );
		}
	}

	public function handleXmlrpcTogge( $enabled ) {
		$options                            = $this->helpers->wpironis_getOption( self::OPTION_NAME );
		$options['wpironis_disable_xmlrpc'] = $enabled ? 1 : 0;
		$updated                            = $this->helpers->wpironis_updateOption( self::OPTION_NAME, $options );

		if ( $updated ) {
			wp_send_json_success( array(
				'message' => $enabled ? __( 'XML-RPC has been disabled for better security',
					'iron-security' ) : __( 'XML-RPC has been enabled', 'iron-security' ),
				'enabled' => $enabled,
				'options' => $options
			) );
		} else {
			$current_options = $options;
			if (
				isset( $current_options['wpironis_disable_xmlrpc'] ) &&
				$current_options['wpironis_disable_xmlrpc'] === ( $enabled ? 1 : 0 )
			) {
				wp_send_json_success( array(
					'message' => $enabled ? __( 'XML-RPC is already disabled',
						'iron-security' ) : __( 'XML-RPC is already enabled', 'iron-security' ),
					'enabled' => $enabled,
					'options' => $current_options
				) );
			} else {
				wp_send_json_error( 'Failed to update XML-RPC setting' );
			}
		}
	}

	public function handleWpVersionToggle( $enabled ) {
		$options                             = $this->helpers->wpironis_getOption( self::OPTION_NAME );
		$options['wpironis_hide_wp_version'] = $enabled ? 1 : 0;
		$updated                             = $this->helpers->wpironis_updateOption( self::OPTION_NAME, $options );

		if ( $updated ) {
			wp_send_json_success( array(
				'message' => __( 'WordPress version visibility setting updated successfully', 'iron-security' ),
				'enabled' => $enabled,
				'options' => $options
			) );
		} else {
			$current_options = $options;
			if ( isset( $current_options['wpironis_hide_wp_version'] ) &&
			     $current_options['wpironis_hide_wp_version'] === ( $enabled ? 1 : 0 ) ) {
				wp_send_json_success( array(
					'message' => __( 'WordPress version visibility setting is already set to this value',
						'iron-security' ),
					'enabled' => $enabled,
					'options' => $current_options
				) );
			} else {
				wp_send_json_error( 'Failed to update WordPress version visibility setting' );
			}
		}
	}

	public function handleSecurityHeadersToggle( $enabled, $headerNameJs ) {
		if ( empty( $headerNameJs ) || ! isset( self::HEADER_MAP[ $headerNameJs ] ) ) {
			wp_send_json_error( [ 'message' => 'Invalid header name provided' ], 400 );
		}

		$header_name_php = self::HEADER_MAP[ $headerNameJs ];
		$options         = $this->helpers->wpironis_getOption( self::OPTION_NAME );
		$current_value   = isset( $options[ $header_name_php ] ) && (bool) $options[ $header_name_php ];

		if ( $current_value === $enabled ) {
			wp_send_json_success( [
				'message' => sprintf(
				/* translators: %s: Name of a settings */
					__( "%d setting unchanged", 'iron-security' ), $headerNameJs ),
				'enabled' => $enabled,
				'options' => $options
			] );
		}

		$options[ $header_name_php ] = $enabled ? 1 : 0;
		$updated                     = $this->helpers->wpironis_updateOption( self::OPTION_NAME, $options );

		if ( $updated ) {
			do_action( 'wpironis_security_headers_updated', $header_name_php, $enabled, $options );

			if ( function_exists( 'wp_cache_flush' ) ) {
				wp_cache_flush();
			}

			wp_send_json_success( [
				'message' => sprintf(
				/* translators: %s: Name of a settings */
					__( "%d setting updated successfully", 'iron-security' ), $headerNameJs ),
				'enabled' => $enabled,
				'options' => $options
			] );
		} else {
			wp_send_json_error( [
				'message' => sprintf(
				/* translators: %s: Name of a settings */
					__( "Failed to update %d setting", 'iron-security' ),
					$headerNameJs )
			], 500 );
		}
	}

	public function handleRestApiToggle( $enabled ) {
		$options                              = $this->helpers->wpironis_getOption( self::OPTION_NAME );
		$options['wpironis_disable_rest_api'] = $enabled ? 1 : 0;
		$updated                              = $this->helpers->wpironis_updateOption( self::OPTION_NAME, $options );

		if ( $updated ) {
			wp_send_json_success( array(
				'message' => __( 'REST API setting updated successfully', 'iron-security' ),
				'enabled' => $enabled,
				'options' => $options
			) );
		} else {
			$current_options = $options;
			if (
				isset( $current_options['wpironis_disable_rest_api'] ) &&
				$current_options['wpironis_disable_rest_api'] === ( $enabled ? 1 : 0 )
			) {
				wp_send_json_success( array(
					'message' => __( 'REST API setting is already set to this value', 'iron-security' ),
					'enabled' => $enabled,
					'options' => $current_options
				) );
			} else {
				wp_send_json_error( __( 'Failed to update REST API setting', 'iron-security' ) );
			}
		}
	}

    public function handlePluginAutoupdateToggle($enabled) {
	    $options = $this->helpers->wpironis_getOption( self::OPTION_NAME );
	    $options['wpironis_enable_plugin_autoupdate'] = $enabled ? 1 : 0;
	    $updated = $this->helpers->wpironis_updateOption( self::OPTION_NAME, $options );

	    if ( $updated ) {
		    wp_send_json_success( array(
			    'message' => __( 'Plugin auto-update setting updated successfully', 'iron-security' ),
			    'enabled' => $enabled,
			    'options' => $options
		    ) );
	    } else {
		    $current_options = get_option( 'wpironis_options' );
		    if (
                    isset( $current_options['wpironis_enable_plugin_autoupdate'] ) &&
                    $current_options['wpironis_enable_plugin_autoupdate'] === ( $enabled ? 1 : 0 )
            ) {
			    wp_send_json_success( array(
				    'message' => __( 'Plugin auto-update setting is already set to this value', 'iron-security' ),
				    'enabled' => $enabled,
				    'options' => $current_options
			    ) );
		    } else {
			    wp_send_json_error( __( 'Failed to update plugin auto-update setting', 'iron-security' ) );
		    }
	    }
    }

	public function register_plugin_autoupdate_setting() {
		$options = $this->helpers->wpironis_getOption( self::OPTION_NAME );
		$enabled = !empty($options['wpironis_enable_plugin_autoupdate']);
		
		if ($enabled) {
			add_filter('auto_update_plugin', '__return_true' );
		} else {
			add_filter('auto_update_plugin', '__return_false' );
		}
	}

    public function handleCoreUpdatesToggle($enabled) {
	    $options =$this->helpers->wpironis_getOption( self::OPTION_NAME );
	    $options['wpironis_enable_core_autoupdate'] = $enabled ? 1 : 0;
	    $updated = $this->helpers->wpironis_updateOption( self::OPTION_NAME, $options );
	    $this->wpironis_configure_core_autoupdates( $enabled );

	    if ( $updated ) {
		    wp_send_json_success( array(
			    'message' => __( 'Core auto-update setting updated successfully', 'iron-security' ),
			    'enabled' => $enabled,
			    'options' => $options
		    ) );
	    } else {
		    $current_options = get_option( 'wpironis_options' );
		    if (
                    isset( $current_options['wpironis_enable_core_autoupdate'] ) &&
                    $current_options['wpironis_enable_core_autoupdate'] === ( $enabled ? 1 : 0 )
            ) {
			    wp_send_json_success( array(
				    'message' => __( 'Core auto-update setting is already set to this value', 'iron-security' ),
				    'enabled' => $enabled,
				    'options' => $current_options
			    ) );
		    } else {
			    wp_send_json_error( __( 'Failed to update core auto-update setting', 'iron-security' ) );
		    }
	    }

    }

	private function wpironis_configure_core_autoupdates( $enabled ) {
		if ( $enabled ) {
			add_filter( 'allow_major_auto_core_updates', '__return_true' );
			add_filter( 'allow_minor_auto_core_updates', '__return_true' );
			add_filter( 'auto_update_core', '__return_true' );
			add_filter( 'auto_update_translation', '__return_true' );
			update_site_option( 'auto_update_core_major', 'enabled' );
			update_site_option( 'auto_update_core_minor', 'enabled' );
			update_site_option( 'auto_update_core_dev', 'enabled' );
		} else {
			add_filter( 'allow_major_auto_core_updates', '__return_false' );
			add_filter( 'allow_minor_auto_core_updates', '__return_false' );
			add_filter( 'auto_update_core', '__return_false' );
			add_filter( 'auto_update_translation', '__return_false' );
			update_site_option( 'auto_update_core_major', 'disabled' );
			update_site_option( 'auto_update_core_minor', 'disabled' );
			update_site_option( 'auto_update_core_dev', 'disabled' );
		}
	}

	public function handleFileEditorToggle( $enabled ) {
		$options = $this->helpers->wpironis_getOption( self::OPTION_NAME );
		$options['wpironis_disable_file_editor'] = $enabled ? 1 : 0;
		$updated = $this->helpers->wpironis_updateOption( self::OPTION_NAME, $options );

		if ( $enabled ) {
			$this->addDisallowFileEditConstant();
		} else {
			$this->removeDisallowFileEditConstant();
		}

		if ( $updated ) {
			wp_send_json_success( [
				'message' => __( 'File editor setting updated successfully', 'iron-security' ),
				'enabled' => $enabled,
				'options' => $options
			] );
		} else {
			wp_send_json_error( __( 'Failed to update file editor setting', 'iron-security' ) );
		}
	}

	private function addDisallowFileEditConstant() {
		$wp_config_path = ABSPATH . 'wp-config.php';

		if ( ! file_exists( $wp_config_path ) || ! is_writable( $wp_config_path ) ) {
			return false;
		}

		$config = file_get_contents( $wp_config_path );

		// Avoid duplicate insertion
		if ( strpos( $config, 'DISALLOW_FILE_EDIT' ) !== false ) {
			return true;
		}

		// Find position right after <?php tag
		$php_tag = '<?php';
		$insert_pos = strpos( $config, $php_tag );

		if ( $insert_pos === false ) {
			return false; // Invalid wp-config.php (no <?php tag)
		}

		$insert_pos += strlen($php_tag); // Move past '<?php'

		// Injection content
		$injection  = "\n\n// IRON SECURITY: DISALLOW_FILE_EDIT\n";
		$injection .= "define('DISALLOW_FILE_EDIT', true);\n";

		// Inject right after the <?php tag
		$new_config = substr($config, 0, $insert_pos) . $injection . substr($config, $insert_pos);

		file_put_contents( $wp_config_path, $new_config, LOCK_EX );

		return true;
	}


	private function removeDisallowFileEditConstant() {
		$wp_config_path = ABSPATH . 'wp-config.php';

		// Use WP_Filesystem instead of direct file operations
		global $wp_filesystem;
		if ( ! function_exists( 'WP_Filesystem' ) ) {
			require_once ABSPATH . 'wp-admin/includes/file.php';
		}

		WP_Filesystem();

		if ( ! $wp_filesystem->exists( $wp_config_path ) || ! $wp_filesystem->is_writable( $wp_config_path ) ) {
			return false;
		}

		$config = $wp_filesystem->get_contents( $wp_config_path );

		// Pattern to remove both comment and define, along with surrounding newlines and whitespace
		$pattern = '/\s*\/\/ IRON SECURITY: DISALLOW_FILE_EDIT\s*define\(\s*\'DISALLOW_FILE_EDIT\'\s*,\s*true\s*\);\s*/i';

		$config = preg_replace( $pattern, '', $config );

		// Ensure there's at least a newline after <?php if it's stuck
		$config = preg_replace('/<\?php(?!\s)/', "<?php\n\n", $config);

		// Save back the cleaned config
		$wp_filesystem->put_contents( $wp_config_path, $config, FS_CHMOD_FILE );

		return true;
	}



	public function handleAiBlockingToggle( $enabled, $forceDelete=false ) {

	    if ( $forceDelete ) {
		    $this->modifyHtaccessForAiBots( false );
		    return;
	    }

        $general_settings = $this->helpers->wpironis_getOption( self::OPTION_NAME );
	    $general_settings['wpironis_block_ai_bots'] = $enabled ? 1 : 0;
	    $this->helpers->wpironis_updateOption( self::OPTION_NAME, $general_settings );
        $this->modifyHtaccessForAiBots( $enabled );

	    $message = $enabled
		    ? __( 'AI bot blocking has been enabled. Your site is now protected from AI bot crawlers.',
			    'iron-security' )
		    : __( 'AI bot blocking has been disabled. AI bots may now crawl your site.', 'iron-security' );

	    wp_send_json_success( array( 'message' => $message ) );
    }


}