<?php
if ( ! defined( 'ABSPATH' ) ) {
	die( 'You are not allowed to call this page directly.' );
}

class FormShieldWPCommentsIntegration extends FormShieldIntegration {
	public static $form_prefix = 'wp';

	/*
	 * This is where you will add filters and actions
	 */
	public function __construct() {
		add_filter( 'formshield_forms_list', array( __CLASS__, 'get_forms' ), 10, 1 );
		add_filter( 'pre_comment_approved', array( __CLASS__, 'validate_comment_before_approval' ), 10, 2 );
		add_action( 'wp_insert_comment', array( __CLASS__, 'validate_forms' ), 10, 2 );
		add_action( 'formshield_autoprotect_forms', array( __CLASS__, 'enable_forms' ), 10, 1 );
		
		/**
		 * Add protected badge to WordPress comment forms
		 */
		add_filter( 'comment_form_defaults', array( __CLASS__, 'add_comment_badge' ), 20, 1 );
		
		/**
		 * Completely disable comments if option is enabled
		 */
		add_filter( 'comments_open', array( __CLASS__, 'disable_comments_if_enabled' ), 10, 2 );
		add_filter( 'pings_open', array( __CLASS__, 'disable_pings_if_enabled' ), 10, 2 );
		add_action( 'admin_menu', array( __CLASS__, 'remove_comment_menu_items' ), 999 );
		add_action( 'wp_before_admin_bar_render', array( __CLASS__, 'remove_comment_menu_bar' ) );
		add_filter( 'comments_array', array( __CLASS__, 'disable_comments_array' ), 10, 2 );
		add_filter( 'get_comments_number', array( __CLASS__, 'disable_comments_number' ), 10, 2 );
		add_action( 'widgets_init', array( __CLASS__, 'remove_comment_widgets' ), 1 );
		add_filter( 'wp_headers', array( __CLASS__, 'remove_comment_feed' ), 11, 1 );
	}

	/**
	 * Get WP comments
	 * This should return the forms list
	 *
	 * @return Array $forms_list
	 */
	public static function get_forms( $forms_list ) {
		// Assign unique form id
		$fid = self::get_form_id( 'comments' );
		
		// Load up to 50 recent posts with open comments (cached for 5 min).
		$cache_key           = 'formshield_posts_with_comments';
		$posts_with_comments = wp_cache_get( $cache_key, 'formshield' );
		if ( false === $posts_with_comments ) {
			$posts_with_comments = get_posts( array(
				'post_type'      => 'post',
				'post_status'    => 'publish',
				'posts_per_page' => 50,
				'comment_status' => 'open',
				'orderby'        => 'date',
				'order'          => 'DESC',
			) );
			wp_cache_set( $cache_key, $posts_with_comments, 'formshield', 300 );
		}
		
		// Ако има страници с коментари, добавяме ги
		if (!empty($posts_with_comments)) {
			foreach ($posts_with_comments as $post) {
				$forms_list[] = array(
					'id'          => 'comments_' . $post->ID,
					'enabled'     => 1,
					'name'        => $post->post_title . ' - Comments',
					'type'        => 'comments',
					'location'    => $post->post_title,
					'page_id'     => $post->ID,
					'blocked_attempts' => 0,
					'submissions' => 0,
					'activity'    => FormShieldForms::get_latest_form_activity( $fid, $post->post_modified )
				);
			}
		} else {
			// Ако няма страници с коментари, добавяме общата система
			$forms_list[] = array(
				'id'          => $fid,
				'enabled'     => 1,
				'name'        => 'WordPress Comments System',
				'type'        => 'comments',
				'location'    => 'Site-wide Comments',
				'page_id'     => 0,
				'blocked_attempts' => 0,
				'submissions' => 0,
				'activity'    => FormShieldForms::get_latest_form_activity( $fid, current_time('mysql') )
			);
		}

		return $forms_list;
	}

	/**
	 * Validate comments before approval (early protection)
	 *
	 * @param int|string $approved - Comment approval status
	 * @param array $commentdata - Comment data
	 *
	 * @return int|string - Modified approval status
	 */
	public static function validate_comment_before_approval( $approved, $commentdata ) {
		// Skip if user is logged in or if it's an order note
		if ( is_user_logged_in() || ( isset( $commentdata['comment_type'] ) && 'order_note' == $commentdata['comment_type'] ) ) {
			return $approved;
		}
		
		// Skip WooCommerce product reviews - we don't have WooCommerce integration yet
		// Check if WooCommerce is active and if this is a product review
		if ( class_exists( 'WooCommerce' ) ) {
			// Check if comment is on a product (WooCommerce product review)
			if ( isset( $commentdata['comment_post_ID'] ) ) {
				$post_id = absint( $commentdata['comment_post_ID'] );
				$post_type = get_post_type( $post_id );
				
				// If it's a product, skip our protection (WooCommerce handles its own reviews)
				if ( 'product' === $post_type ) {
					return $approved; // Let WooCommerce handle product reviews
				}
			}
		}
		
		// Check if comments are completely disabled
		$options = FormShield::get_options();
		$disable_comments = isset( $options['disable_comments_completely'] ) ? $options['disable_comments_completely'] : false;
		
		if ( $disable_comments ) {
			// Block completely - don't even save as spam
			wp_die(
				__( 'Коментарите са деактивирани на този сайт.', 'formshield' ),
				__( 'Коментарите са деактивирани', 'formshield' ),
				array( 'response' => 403, 'back_link' => true )
			);
		}
		
		// Check if comment protection is enabled in settings
		$protect_comments = isset( $options['protect_comments'] ) ? $options['protect_comments'] : true;
		
		// If comment protection is disabled, skip all checks
		if ( !$protect_comments ) {
			return $approved;
		}
		
		// Get comment content
		$content = isset( $commentdata['comment_content'] ) ? $commentdata['comment_content'] : '';
		$email = isset( $commentdata['comment_author_email'] ) ? $commentdata['comment_author_email'] : '';
		$author = isset( $commentdata['comment_author'] ) ? $commentdata['comment_author'] : '';
		
		$form_id = self::get_form_id( 'comments' );

		// Quick spam checks (fast, before full validation).
		// Pass 'spam' attack type so handle_suspicious_form_activity counts it correctly in one DB write.
		if ( self::is_obvious_spam( $content, $email, $author ) ) {
			FormShieldForms::handle_suspicious_form_activity( $form_id, 'spam' );
			wp_die(
				__( 'Коментарът не може да бъде публикуван. Моля, премахнете линковете и опитайте отново.', 'formshield' ),
				__( 'Коментарът е блокиран', 'formshield' ),
				array( 'response' => 403, 'back_link' => true )
			);
		}

		// Score-based check (only when form protection is explicitly enabled).
		if (
			is_array( $options ) &&
			! empty( $options['formshield_forms'][ $form_id ]['form_enabled'] )
		) {
			$spam_score    = self::calculate_comment_spam_score( $content, $email, $author );
			$spam_threshold = apply_filters( 'formshield_comment_spam_threshold', 50, $commentdata );

			if ( $spam_score >= $spam_threshold ) {
				FormShieldForms::handle_suspicious_form_activity( $form_id, 'spam' );
				wp_die(
					__( 'Коментарът не може да бъде публикуван. Моля, опитайте отново.', 'formshield' ),
					__( 'Коментарът е блокиран', 'formshield' ),
					array( 'response' => 403, 'back_link' => true )
				);
			}
		}
		
		return $approved;
	}
	
	/**
	 * Check for obvious spam patterns (fast check)
	 *
	 * @param string $content Comment content
	 * @param string $email Comment author email
	 * @param string $author Comment author name
	 * @return bool True if obvious spam
	 */
	private static function is_obvious_spam( $content, $email, $author ) {
		// 1. Comment contains ONLY URL(s) - no other text
		$content_trimmed = trim( strip_tags( $content ) );
		if ( empty( $content_trimmed ) ) {
			return false;
		}
		
		// Check if content is only URLs
		$url_pattern = '/(http|https|ftp):\/\/[^\s]+/i';
		preg_match_all( $url_pattern, $content_trimmed, $urls );
		$url_count = count( $urls[0] );
		
		// Remove URLs from content to check if anything else remains
		$content_without_urls = preg_replace( $url_pattern, '', $content_trimmed );
		$content_without_urls = trim( preg_replace( '/\s+/', ' ', $content_without_urls ) );
		
		// If content is only URLs (or URLs + minimal text), it's spam
		if ( $url_count > 0 && strlen( $content_without_urls ) < 10 ) {
			return true;
		}
		
		// 2. Short URL services (common spam indicator) - IMMEDIATE SPAM
		$short_url_domains = array(
			'shorturl.fm', 'bit.ly', 'tinyurl.com', 't.co', 'goo.gl', 'ow.ly',
			'is.gd', 'buff.ly', 'adf.ly', 'shorte.st', 'bc.vc', 'adfly.com',
			'u.to', 'v.gd', 'qr.net', 'short.link', 'rebrand.ly', 'rb.gy',
			'cutt.ly', 'tiny.cc', 'shorturl', 'surl.li'
		);
		
		foreach ( $short_url_domains as $domain ) {
			if ( stripos( $content, $domain ) !== false ) {
				return true;
			}
		}
		
		// 3. YouTube links (especially shorts) in comments - usually spam
		if ( preg_match( '/youtube\.com\/shorts|youtu\.be/i', $content ) ) {
			// YouTube shorts in comments are almost always spam
			return true;
		}
		
		// 3.1 YouTube watch links with marketing text - also spam
		if ( preg_match( '/youtube\.com\/watch/i', $content ) && $url_count > 0 ) {
			// YouTube links in comments are suspicious
			return true;
		}
		
		// 4. INSTANT BLOCK PATTERNS (same as Divi) - блокира веднага
		$instant_block_patterns = array(
			// Комбинация: затруднявате се + линк
			'/затруднявате\s+се.*https?:\/\//iu',
			'/struggling.*https?:\/\//i',
			// Комбинация: клиенти/трафик + линк
			'/(клиенти|трафик|traffic|clients|visitors).*https?:\/\//iu',
			'/https?:\/\/.*(клиенти|трафик|traffic|clients|visitors)/iu',
			// Гледайте това + линк
			'/гледайте\s+(това|видеото).*https?:\/\//iu',
			'/watch\s+this.*https?:\/\//i',
			// Вижте това/тук + линк
			'/вижте\s+(това|тук).*https?:\/\//iu',
			'/see\s+(this|here).*https?:\/\//i',
			// Привлечете клиенти + линк
			'/привлечете.*клиенти.*https?:\/\//iu',
			'/attract.*clients.*https?:\/\//i',
		);
		
		foreach ( $instant_block_patterns as $pattern ) {
			if ( preg_match( $pattern, $content ) ) {
				return true;
			}
		}
		
		// 5. Marketing keywords + URL combination (high spam probability)
		$marketing_keywords = array(
			// English
			'/traffic|clients|customers|leads|visitors|seo|marketing|advertising|promotion|promote/i',
			'/artificial intelligence|ai|machine learning|ml|increase.*traffic|boost.*traffic/i',
			'/targeted traffic|organic traffic|paid advertising|ppc|campaign/i',
			'/generate.*leads|attract.*clients|drive.*traffic|get.*visitors/i',
			// Bulgarian
			'/трафик|клиенти|посетители|реклама|маркетинг|промоция|промотиране/iu',
			'/изкуствен интелект|ai|увеличи.*трафик|увеличаване.*трафик/iu',
			'/целеви трафик|органичен трафик|платена реклама|кампания/iu',
			'/генериране.*клиенти|привличане.*клиенти|увеличаване.*посетители/iu',
			'/затруднявате|целеви|уебсайт/iu',
		);
		
		$has_marketing_keyword = false;
		foreach ( $marketing_keywords as $pattern ) {
			if ( preg_match( $pattern, $content ) ) {
				$has_marketing_keyword = true;
				break;
			}
		}
		
		// If has marketing keyword AND URL, it's spam
		if ( $has_marketing_keyword && $url_count > 0 ) {
			return true;
		}
		
		// 6. Generic email patterns (numbers + common names)
		if ( preg_match( '/^[a-zA-Z]+\d+@/i', $email ) ) {
			// Pattern like "Elizabeth1076@gmail.com" - suspicious
			if ( strlen( $content ) < 50 ) {
				return true;
			}
		}
		
		// 7. Author name matches email pattern (suspicious)
		if ( !empty( $author ) && !empty( $email ) ) {
			$email_local = substr( $email, 0, strpos( $email, '@' ) );
			if ( strtolower( $author ) === strtolower( $email_local ) ) {
				// Author name matches email - might be spam
				if ( strlen( $content ) < 30 || $url_count > 0 ) {
					return true;
				}
			}
		}
		
		return false;
	}
	
	/**
	 * Calculate spam score for comment (similar to Divi spam detection)
	 *
	 * @param string $content Comment content
	 * @param string $email Comment author email
	 * @param string $author Comment author name
	 * @return int Spam score (0-100)
	 */
	private static function calculate_comment_spam_score( $content, $email, $author ) {
		$score = 0;
		
		// Get spam protection instance
		$spam_protection = FormShieldSpamProtection::get_instance();
		
		// Use reflection to access private method (or make it public)
		// For now, let's use a simplified version
		$ip = formshield_get_validated_ip( 'Unknown' );
		
		// 1. URL-only content (high score)
		$url_pattern = '/(http|https|ftp):\/\/[^\s]+/i';
		preg_match_all( $url_pattern, $content, $urls );
		$url_count = count( $urls[0] );
		
		if ( $url_count > 0 ) {
			$content_without_urls = trim( preg_replace( $url_pattern, '', strip_tags( $content ) ) );
			if ( strlen( $content_without_urls ) < 20 ) {
				$score += 40; // URL-only or mostly URL content
			} else {
				$score += 15; // Has URLs but also text
			}
		}
		
		// 2. Short URL services (high spam indicator)
		$short_url_domains = array( 
			'shorturl.fm', 'bit.ly', 'tinyurl.com', 't.co', 'goo.gl', 'ow.ly',
			'is.gd', 'buff.ly', 'adf.ly', 'shorte.st', 'bc.vc', 'adfly.com',
			'u.to', 'v.gd', 'qr.net', 'short.link', 'rebrand.ly'
		);
		foreach ( $short_url_domains as $domain ) {
			if ( stripos( $content, $domain ) !== false ) {
				$score += 35; // Increased from 30
				break;
			}
		}
		
		// 3. YouTube links (especially shorts) - high spam probability
		if ( preg_match( '/youtube\.com\/shorts/i', $content ) ) {
			$score += 40; // YouTube shorts in comments are almost always spam
		} elseif ( preg_match( '/youtu\.be|youtube\.com/i', $content ) ) {
			$score += 25; // Regular YouTube links also suspicious in comments
		}
		
		// 4. Marketing keywords (AI, traffic, clients, etc.)
		$marketing_patterns = array(
			// English marketing phrases
			'/\b(artificial intelligence|ai|machine learning)\b.*\b(traffic|clients|customers|leads|visitors)\b/i',
			'/\b(increase|boost|drive|generate|attract|get).*\b(traffic|clients|customers|leads|visitors)\b/i',
			'/\b(targeted|organic|paid).*\b(traffic|advertising|marketing)\b/i',
			'/\b(seo|marketing|advertising|promotion|promote|campaign)\b/i',
			'/\b(web.*site|website).*\b(problems|issues|low.*traffic|no.*clients)\b/i',
			'/\b(cost.*less|cheaper|affordable).*\b(than|advertising|marketing)\b/i',
			// Bulgarian marketing phrases
			'/\b(изкуствен интелект|ai)\b.*\b(трафик|клиенти|посетители)\b/i',
			'/\b(увеличи|увеличаване|генериране|привличане|получаване).*\b(трафик|клиенти|посетители)\b/i',
			'/\b(целеви|органичен|платена).*\b(трафик|реклама|маркетинг)\b/i',
			'/\b(реклама|маркетинг|промоция|промотиране|кампания)\b/i',
			'/\b(уебсайт|сайт).*\b(проблеми|нисък.*трафик|малко.*клиенти)\b/i',
			'/\b(струва.*по.*малко|по.*евтино|достъпно).*\b(от|реклама|маркетинг)\b/i'
		);
		
		$marketing_score = 0;
		foreach ( $marketing_patterns as $pattern ) {
			if ( preg_match( $pattern, $content ) ) {
				$marketing_score += 20; // Each marketing pattern adds 20 points
			}
		}
		$score += min( 40, $marketing_score ); // Cap marketing score at 40
		
		// 5. Marketing keyword + URL combination (very suspicious)
		if ( $marketing_score > 0 && $url_count > 0 ) {
			$score += 30; // Additional penalty for marketing + URL
		}
		
		// 6. Generic email patterns
		if ( preg_match( '/^[a-zA-Z]+\d+@/i', $email ) ) {
			$score += 20;
		}
		
		// 7. Very short comments
		if ( strlen( strip_tags( $content ) ) < 10 ) {
			$score += 25;
		}
		
		// 8. Traditional spam keywords (viagra, casino, etc.)
		$spam_keywords = array(
			'/viagra|cialis|casino|porn|sex/i',
			'/buy.*cheap|discount.*now|special.*offer/i',
			'/click.*here|visit.*now|check.*link/i'
		);
		
		foreach ( $spam_keywords as $pattern ) {
			if ( preg_match( $pattern, $content ) ) {
				$score += 25;
				break;
			}
		}
		
		// Allow filtering of score
		$score = apply_filters( 'formshield_comment_spam_score', $score, $content, $email, $author );
		
		return min( 100, max( 0, $score ) );
	}

	/**
	 * Validate comments (backup protection)
	 *
	 * @param String $id - Comment ID
	 * @param Object $comment - Comment object
	 *
	 * @return Void
	 */
	public static function validate_forms( $id, $comment ) {
		if ( 'order_note' == $comment->comment_type || is_user_logged_in()) {
			return;
		}
		
		// Skip WooCommerce product reviews - we don't have WooCommerce integration yet
		if ( class_exists( 'WooCommerce' ) ) {
			$post_id = isset( $comment->comment_post_ID ) ? absint( $comment->comment_post_ID ) : 0;
			if ( $post_id > 0 ) {
				$post_type = get_post_type( $post_id );
				// If it's a product, skip our protection (WooCommerce handles its own reviews)
				if ( 'product' === $post_type ) {
					return; // Let WooCommerce handle product reviews
				}
			}
		}
		
		// Check if comments are completely disabled
		$options = FormShield::get_options();
		$disable_comments = isset( $options['disable_comments_completely'] ) ? $options['disable_comments_completely'] : false;
		
		if ( $disable_comments ) {
			// Mark as spam if comments are disabled
			wp_set_comment_status( $id, 'spam' );
			return;
		}
		
		// Check if comment protection is enabled in settings
		$protect_comments = isset( $options['protect_comments'] ) ? $options['protect_comments'] : true;
		
		// If comment protection is disabled, skip all checks
		if ( !$protect_comments ) {
			return;
		}
		
		// If HP protection enabled, validate new comments
		$form_id = self::get_form_id( 'comments' );
		if ( is_array( $options ) && array_key_exists( 'formshield_forms', $options ) && isset( $options['formshield_forms'][ $form_id ] ) ) {
			$hp_form_enabled = $options['formshield_forms'][ $form_id ]['form_enabled'];
			if ( $hp_form_enabled ) {
				$return_url = wp_get_referer();
				$return_url = $return_url ? esc_url_raw( $return_url ) : '';
				// If the detection check fails, prevent the form submission and display an error message.
				$validation_failed = FormShieldForms::fail_form_validation();
				if ( $validation_failed ) {
					// Record suspicious activity
					FormShieldForms::handle_suspicious_form_activity( $form_id );
					// Mark comment as spam instead of deleting
					wp_set_comment_status( $id, 'spam' );
				}
			}
		}
	}

	/*
	 * This is for the autoprotect process and should enable all forms for validation.
	 * This should be added to the formshield_autoprotect_forms action.
	 * This should implement the FormShieldForms::enable_forms() static method to enable each form
	 */
	public static function enable_forms( $unattended ) {
		FormShieldForms::enable_forms( self::get_form_id( 'comments' ), 1, $unattended );
	}
	
	/**
	 * Get unique form ID for comments
	 *
	 * @param string $type
	 * @return string
	 */
	public static function get_form_id( $type ) {
		return 'wp_comments_' . $type;
	}
	
	/**
	 * Add protected badge to WordPress comment forms
	 * 
	 * @param array $defaults Comment form defaults
	 * @return array Modified defaults with badge
	 */
	public static function add_comment_badge( $defaults ) {
		// Check if we should show the badge
		if ( !FormShield::should_show_badge() ) {
			return $defaults;
		}
		
		// Add badge to the comment form HTML
		add_action( 'comment_form_after', function() {
			$badge_html = FormShield::badge_html( 'WordPress Comments' );
			if ( $badge_html ) {
				echo wp_kses_post($badge_html);
			}
		});
		
		return $defaults;
	}
	
	/**
	 * Disable comments if option is enabled
	 */
	public static function disable_comments_if_enabled( $open, $post_id ) {
		$options = FormShield::get_options();
		$disable_comments = isset( $options['disable_comments_completely'] ) ? $options['disable_comments_completely'] : false;
		
		if ( $disable_comments ) {
			return false;
		}
		
		return $open;
	}
	
	/**
	 * Disable pings if comments are disabled
	 */
	public static function disable_pings_if_enabled( $open, $post_id ) {
		$options = FormShield::get_options();
		$disable_comments = isset( $options['disable_comments_completely'] ) ? $options['disable_comments_completely'] : false;
		
		if ( $disable_comments ) {
			return false;
		}
		
		return $open;
	}
	
	/**
	 * Remove comment menu items from admin
	 */
	public static function remove_comment_menu_items() {
		$options = FormShield::get_options();
		$disable_comments = isset( $options['disable_comments_completely'] ) ? $options['disable_comments_completely'] : false;
		
		if ( $disable_comments ) {
			// Remove comment menu
			remove_menu_page( 'edit-comments.php' );
			
			// Remove comment submenu from posts/pages
			remove_submenu_page( 'edit.php', 'edit-comments.php' );
			remove_submenu_page( 'edit.php?post_type=page', 'edit-comments.php' );
		}
	}
	
	/**
	 * Remove comment menu from admin bar
	 */
	public static function remove_comment_menu_bar() {
		$options = FormShield::get_options();
		$disable_comments = isset( $options['disable_comments_completely'] ) ? $options['disable_comments_completely'] : false;
		
		if ( $disable_comments ) {
			global $wp_admin_bar;
			$wp_admin_bar->remove_menu( 'comments' );
		}
	}
	
	/**
	 * Disable comments array (hide existing comments)
	 */
	public static function disable_comments_array( $comments, $post_id ) {
		$options = FormShield::get_options();
		$disable_comments = isset( $options['disable_comments_completely'] ) ? $options['disable_comments_completely'] : false;
		
		if ( $disable_comments ) {
			return array(); // Return empty array to hide all comments
		}
		
		return $comments;
	}
	
	/**
	 * Set comments number to 0
	 */
	public static function disable_comments_number( $count, $post_id ) {
		$options = FormShield::get_options();
		$disable_comments = isset( $options['disable_comments_completely'] ) ? $options['disable_comments_completely'] : false;
		
		if ( $disable_comments ) {
			return 0;
		}
		
		return $count;
	}
	
	/**
	 * Remove comment widgets
	 */
	public static function remove_comment_widgets() {
		$options = FormShield::get_options();
		$disable_comments = isset( $options['disable_comments_completely'] ) ? $options['disable_comments_completely'] : false;
		
		if ( $disable_comments ) {
			unregister_widget( 'WP_Widget_Recent_Comments' );
		}
	}
	
	/**
	 * Remove comment feed from headers
	 */
	public static function remove_comment_feed( $headers ) {
		$options = FormShield::get_options();
		$disable_comments = isset( $options['disable_comments_completely'] ) ? $options['disable_comments_completely'] : false;
		
		if ( $disable_comments ) {
			// Remove comment feed link from headers
			remove_action( 'wp_head', 'feed_links_extra', 3 );
		}
		
		return $headers;
	}
}

add_action( 'plugins_loaded', function() { new FormShieldWPCommentsIntegration(); });
