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

class FormShieldCF7Integration extends FormShieldIntegration {
	public static $form_prefix = 'cf7';

	/**
	 * Build canonical CF7 form ID using numeric post ID.
	 *
	 * @param WP_Post $form
	 * @return string
	 */
	private static function get_canonical_form_id( $form ) {
		return self::get_form_id( (int) $form->ID );
	}

	/**
	 * Build legacy CF7 slug-based form ID.
	 *
	 * @param WP_Post $form
	 * @return string
	 */
	private static function get_legacy_slug_form_id( $form ) {
		$cf7_slug = ! empty( $form->post_name ) ? $form->post_name : $form->ID;
		return self::get_form_id( $cf7_slug );
	}

	/**
	 * Migrate legacy slug key to canonical numeric key.
	 *
	 * @param string $legacy_form_id
	 * @param string $canonical_form_id
	 * @return void
	 */
	private static function migrate_legacy_form_key( $legacy_form_id, $canonical_form_id ) {
		if ( $legacy_form_id === $canonical_form_id ) {
			return;
		}

		$options = FormShield::get_options();
		if ( empty( $options['formshield_forms'] ) || ! is_array( $options['formshield_forms'] ) ) {
			return;
		}
		if ( ! isset( $options['formshield_forms'][ $legacy_form_id ] ) ) {
			return;
		}
		if ( isset( $options['formshield_forms'][ $canonical_form_id ] ) ) {
			unset( $options['formshield_forms'][ $legacy_form_id ] );
			FormShield::update_options( $options );
			return;
		}

		$options['formshield_forms'][ $canonical_form_id ] = $options['formshield_forms'][ $legacy_form_id ];
		unset( $options['formshield_forms'][ $legacy_form_id ] );
		FormShield::update_options( $options );

		if ( defined( 'WP_DEBUG' ) && WP_DEBUG ) {
			error_log(
				sprintf(
					'[FormShield DEBUG] CF7 migrated legacy key %s -> %s',
					(string) $legacy_form_id,
					(string) $canonical_form_id
				)
			);
		}
	}

	/*
	 * This is where you will add filters and actions
	 */
	public function __construct() {
		add_filter( 'formshield_forms_list', array( __CLASS__, 'get_forms' ), 20, 1 );
		add_filter( 'wpcf7_spam', array( __CLASS__, 'validate_forms' ), 10, 1 );
		add_action( 'formshield_autoprotect_forms', array( __CLASS__, 'enable_forms' ), 20, 1 );

		/**
		 * Auto-protect New Contact Form 7 Forms
		 */
		add_action( 'wpcf7_after_create', array( 'FormShieldAutoProtect', 'init' ), 10, 2 );
		add_action( 'wpcf7_after_update', array( 'FormShieldAutoProtect', 'init' ), 10, 2 );
		
		/**
		 * Add protected badge to Contact Form 7 forms
		 */
		add_action( 'wp_footer', array( __CLASS__, 'add_cf7_badge_script' ), 99 );

		// Inject badge at render-time (reliable, no JS dependency)
		add_filter( 'wpcf7_form_elements', array( __CLASS__, 'inject_badge_into_form' ), 99, 1 );
	}

	/*
	 * Get Contact Form 7 forms
	 *
	 * @return Array $forms_list
	 */
	public static function get_forms( $forms_list ) {
		if ( function_exists( 'wpcf7_contact_form' ) ) {
			$additional_forms = array();
			
			$cf7_form_list = get_posts( array(
				'post_type'   => 'wpcf7_contact_form',
				'numberposts' => - 1
			) );
			
			foreach ( $cf7_form_list as $form ) {
				$form_id = self::get_canonical_form_id( $form );
				$legacy_form_id = self::get_legacy_slug_form_id( $form );
				self::migrate_legacy_form_key( $legacy_form_id, $form_id );
				$is_enabled = FormShieldSettings::is_form_enabled( $form_id );
				$is_enabled_legacy = FormShieldSettings::is_form_enabled( $legacy_form_id );
				
				// Push to forms list
				$additional_forms[] = array(
					'id'          => $form_id,
					'enabled'     => $is_enabled,
					'name'        => $form->post_title,
					'type'        => 'Contact Form 7',
					'location'    => 'Contact Form 7: ' . $form->post_title . ' (ID: ' . $form->ID . ')',
					'submissions' => FormShieldForms::get_form_submissions_ct( $form_id, 0 ),
					'activity'    => FormShieldForms::get_latest_form_activity( $form_id, $form->post_modified )
				);

				if ( defined( 'WP_DEBUG' ) && WP_DEBUG ) {
					error_log(
						sprintf(
							'[FormShield DEBUG] CF7 get_forms post_id=%d legacy_id=%s canonical_id=%s enabled_canonical=%s enabled_legacy=%s',
							(int) $form->ID,
							(string) $legacy_form_id,
							(string) $form_id,
							$is_enabled ? 'yes' : 'no',
							$is_enabled_legacy ? 'yes' : 'no'
						)
					);
				}
			}
			self::prune_disabled_forms( $additional_forms );
			$forms_list = array_merge( $forms_list, $additional_forms );
		}
		elseif ( defined( 'WP_DEBUG' ) && WP_DEBUG ) {
			error_log( '[FormShield DEBUG] CF7 get_forms skipped: function wpcf7_contact_form not available at this request.' );
		}

		return $forms_list;
	}

	/**
	 * Validate Contact Form 7 forms
	 *
	 * @param Boolean $spam - Boolean value to return true for spammy submissions
	 *
	 * @return Boolean
	 */
	public static function validate_forms( $spam ) {
		// Skip if already marked as spam
		if ( $spam ) {
			return $spam;
		}
		
		// If HP protection enabled, validate the form
		$options = FormShield::get_options();
		$cf7_id = formshield_get_post_string('_wpcf7');
		
		// Skip if no CF7 ID found
		if ( empty( $cf7_id ) ) {
			return $spam;
		}
		
		// Get the form object to get the correct slug
		$form = get_post( $cf7_id );
		$cf7_slug = $form && ! empty( $form->post_name ) ? $form->post_name : $cf7_id;
		$form_id = self::get_form_id( $cf7_slug );
		$form_id_numeric = self::get_form_id( $cf7_id );
		
		// Check if this form is protected (support both slug and numeric ID in options)
		$formshield_form_enabled = false;
		if ( ! empty( $options['formshield_forms'] ) && is_array( $options['formshield_forms'] ) ) {
			foreach ( array( $form_id, $form_id_numeric ) as $fid ) {
				if ( isset( $options['formshield_forms'][ $fid ]['form_enabled'] ) && $options['formshield_forms'][ $fid ]['form_enabled'] ) {
					$formshield_form_enabled = true;
					$form_id = $fid;
					break;
				}
			}
		}
		if ( $formshield_form_enabled ) {
			// Check honeypot: formshield_honeypot or fs_hp_* (from formshield-protection.js)
				$honeypot_filled = ! empty( formshield_get_post_string( 'formshield_honeypot', '' ) );
				if ( ! $honeypot_filled && ! empty( $_POST ) ) {
					foreach ( array_keys( $_POST ) as $key ) {
						if ( strpos( (string) $key, 'fs_hp_' ) === 0 && ! empty( $_POST[ $key ] ) ) {
							$honeypot_filled = true;
							break;
						}
					}
				}
				if ( $honeypot_filled ) {
					FormShieldForms::handle_suspicious_form_activity( $form_id );
					$spam = true;
				} else {
					// Run FormShield validation
					$validation_failed = FormShieldForms::fail_form_validation();
					
					if ( $validation_failed ) {
						// Record suspicious activity
						FormShieldForms::handle_suspicious_form_activity( $form_id );
						
						// Mark as spam - CF7 will handle the error message
						$spam = true;
					}
				}
		}

		return $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 ) {
		if ( function_exists( 'wpcf7_contact_form' ) ) {
			$cf7_form_list = get_posts( array(
				'post_type'   => 'wpcf7_contact_form',
				'numberposts' => - 1
			) );
			if ( is_array( $cf7_form_list ) ) {
				foreach ( $cf7_form_list as $form ) {
					$form_id = self::get_canonical_form_id( $form );
					FormShieldForms::enable_forms( $form_id, 1, $unattended );
				}
			}
		}
	}
	
	
	/**
	 * Generate JavaScript code for badge injection
	 *
	 * @param array $js_data Data to pass to JavaScript
	 * @return string JavaScript code
	 */
	private static function generate_badge_script($js_data) {
		// Check if script file exists
		$script_path = plugin_dir_path(__FILE__) . '../js/contact-form-7-inline.js';
		
		// Enqueue Contact Form 7 script first
		wp_enqueue_script('wpcf7-forms');
		
		// Enqueue our script with dependency on CF7
		wp_enqueue_script(
			'formshield-cf7-badge',
			plugins_url( 'js/contact-form-7-inline.js', dirname(__FILE__) ),
			array('jquery', 'wpcf7-forms'),
			FORMSHIELD_VERSION,
			true
		);
		
		// Localize script with data
		wp_localize_script( 'formshield-cf7-badge', 'formshieldCF7Data', $js_data );
		
		// Return empty string since we're using enqueue
		return '';
	}

	/**
	 * Get all protected CF7 numeric post IDs from stored options.
	 * Handles both cf7-123 (numeric) and cf7-contact-form-1 (slug) formats.
	 *
	 * @return int[]
	 */
	private static function get_protected_cf7_numeric_ids() {
		$options = FormShield::get_options();
		$protected_ids = array();
		if ( empty( $options['formshield_forms'] ) || ! is_array( $options['formshield_forms'] ) ) {
			return $protected_ids;
		}
		foreach ( $options['formshield_forms'] as $stored_form_id => $form_data ) {
			if (
				strpos( $stored_form_id, 'cf7-' ) !== 0 ||
				empty( $form_data['form_enabled'] )
			) {
				continue;
			}
			$suffix = substr( $stored_form_id, 4 ); // after "cf7-"
			if ( is_numeric( $suffix ) ) {
				$protected_ids[] = (int) $suffix;
			} else {
				// Slug format: resolve to post ID
				$post = get_page_by_path( $suffix, OBJECT, 'wpcf7_contact_form' );
				if ( $post && $post->ID ) {
					$protected_ids[] = (int) $post->ID;
				}
			}
		}
		return array_unique( $protected_ids );
	}

	/**
	 * Inject FormShield badge into CF7 form HTML at render time.
	 * This runs during the CF7 shortcode rendering and does not rely on JS.
	 *
	 * @param string $content Form markup
	 * @return string Modified form markup
	 */
	public static function inject_badge_into_form( $content ) {
		// Show only for admins per FormShield policy
		if ( ! FormShield::should_show_badge() ) {
			return $content;
		}

		$current_form = function_exists( 'wpcf7_get_current_contact_form' ) ? wpcf7_get_current_contact_form() : null;
		if ( ! $current_form ) {
			return $content;
		}

		$protected_ids = self::get_protected_cf7_numeric_ids();
		$form_id = (int) $current_form->id();
		if ( empty( $protected_ids ) || ! in_array( $form_id, $protected_ids, true ) ) {
			return $content;
		}

		$badge_html = FormShield::badge_html( 'Contact Form 7' );
		if ( empty( $badge_html ) ) {
			return $content;
		}

		// Append badge after the form HTML
		return $content . $badge_html;
	}
	
	/**
	 * Add filter for CF7 form elements (used when form is re-rendered via AJAX).
	 */
	public static function add_cf7_badge_script() {
		if ( ! FormShield::should_show_badge() ) {
			return;
		}
		$protected_ids = self::get_protected_cf7_numeric_ids();
		if ( empty( $protected_ids ) ) {
			return;
		}
		$badge_html = FormShield::badge_html( 'Contact Form 7' );
		if ( ! $badge_html ) {
			return;
		}
		add_filter( 'wpcf7_form_elements', function( $content ) use ( $protected_ids, $badge_html ) {
			$current_form = function_exists( 'wpcf7_get_current_contact_form' ) ? wpcf7_get_current_contact_form() : null;
			if ( ! $current_form || ! in_array( (int) $current_form->id(), $protected_ids, true ) ) {
				return $content;
			}
			return $content . $badge_html;
		} );
	}

}

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