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

class FormShieldGravityFormsIntegration extends FormShieldIntegration {
	public static $form_prefix = 'gf';

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

		/**
		 * Auto-protect New Gravity Forms
		 */
		add_action( 'gform_after_save_form', array( 'FormShieldAutoProtect', 'init' ), 10, 2 );
		add_action( 'gform_after_duplicate_form', array( 'FormShieldAutoProtect', 'init' ), 10, 2 );
		
		/**
		 * Add protected badges to Gravity Forms
		 */
		add_action( 'wp_footer', array( __CLASS__, 'add_gravity_badges' ) );
	}

	/*
	 * Get Gravity Forms
	 * This should return the forms list
	 *
	 * @return Array $forms_list
	 */
	public static function get_forms( $forms_list ) {
		if ( class_exists( 'GFCommon' ) && class_exists( 'GFAPI' ) ) {
			$additional_forms  = array();
			$gravity_form_list = GFAPI::get_forms();
			if ( is_array( $gravity_form_list ) ) {
				foreach ( $gravity_form_list as $form ) {
					// Assign unique form id
					$fid = self::get_form_id( $form['id'] );
					// Get current form entries count
					$entries = GFAPI::get_entries( $form['id'] );
					// Get last entry date
					$last_entry = array_key_exists( 0, $entries ) ? $entries[0]['date_created'] : null; // Entries are reverse ordered, newest listed first
					// Push to forms list
					$additional_forms[] = array(
						'id'          => $fid,
						'enabled'     => FormShieldSettings::is_form_enabled( $fid ),
						'name'        => $form['title'],
						'type'        => 'Gravity Forms',
						'location'    => 'Gravity Forms: ' . $form['title'] . ' (ID: ' . $form['id'] . ')',
						'submissions' => FormShieldForms::get_form_submissions_ct( $fid, count( $entries ) ),
						'activity'    => FormShieldForms::get_latest_form_activity( $fid, $last_entry )
					);
				}
			}
			self::prune_disabled_forms( $additional_forms );
			$forms_list = array_merge( $forms_list, $additional_forms );
		}

		return $forms_list;
	}

	/**
	 * Validate Gravity forms
	 *
	 * @param Array $validation_result - Array of including the form object properties
	 *
	 * @return Array - $validation_result
	 */
	public static function validate_forms( $validation_result ) {
		// Skip if already invalid
		if ( !$validation_result['is_valid'] ) {
			return $validation_result;
		}
		
		// If FormShield protection enabled, validate the form
		$options = form_shield()->get_options();
		$fid     = self::get_form_id( absint( $validation_result['form']['id'] ) );
		
		if ( is_array( $options ) && array_key_exists( 'formshield_forms', $options ) && isset( $options['formshield_forms'][ $fid ] ) ) {
			$formshield_form_enabled = $options['formshield_forms'][ $fid ]['form_enabled'];

			if ( $formshield_form_enabled ) {
				// Check honeypot field first (quick check)
				$honeypot_value = formshield_get_post_string('formshield_honeypot', '');
				if ( !empty($honeypot_value) ) {
					// Honeypot was filled - definitely a bot
					FormShieldForms::handle_suspicious_form_activity( $fid );
					$validation_result['is_valid'] = false;
				} else {
					// Run FormShield validation
					$validation_failed = FormShieldForms::fail_form_validation();
					
					if ( $validation_failed ) {
						// Record suspicious activity
						FormShieldForms::handle_suspicious_form_activity( $fid );
						
						// Set GF fail flag
						$validation_result['is_valid'] = false;
					}
				}
			}
		}

		return $validation_result;
	}

	/**
	 * Update Gravity Forms Validation Message
	 *
	 * @param String $message - Validation error message
	 * @param Object $form - Gravity forms object (optional)
	 *
	 * @return String
	 */
	function change_gravity_validation_message( $message, $form ) {
		$specific_msg = '';
		$options      = form_shield()->get_options();
		if ( is_array( $options ) && array_key_exists( 'hp_forms', $options ) ) {
			$fid             = self::get_form_id( $form['id'] );
			$hp_form_enabled = $options['hp_forms'][ $fid ]['form_enabled'];

			if ( $hp_form_enabled ) {
				$specific_msg = FormShieldForms::fail_form_error_message();
			}
		}

		return '<div class="validation_error">There was a problem with your submission. Errors have been highlighted below. ' . $specific_msg . '</div>';
	}

	/*
	 * Protect Existing Gravity forms
	 */
	public static function enable_forms( $unattended ) {
		if ( class_exists( 'GFCommon' ) && class_exists( 'GFAPI' ) ) {
			$gravity_form_list = GFAPI::get_forms();
			if ( is_array( $gravity_form_list ) ) {
				foreach ( $gravity_form_list as $form ) {
					// Assign unique form id
					$fid = self::get_form_id( $form['id'] );
					FormShieldForms::enable_forms( $fid, 1, $unattended );
				}
			}
		}
	}
	
	/**
	 * Add protected badges to Gravity Forms
	 */
	public static function add_gravity_badges() {
		$options = FormShield::get_options();
		
		if ( ! isset( $options['formshield_forms'] ) ) {
			return;
		}
		
		// Get protected Gravity Forms
		$protected_gravity_forms = array();
		foreach ( $options['formshield_forms'] as $fid => $form_data ) {
			if ( strpos( $fid, 'gf-' ) === 0 && isset( $form_data['form_enabled'] ) && $form_data['form_enabled'] ) {
				$protected_gravity_forms[] = $fid;
			}
		}
		
		if ( empty( $protected_gravity_forms ) ) {
			return;
		}
		
		// Enqueue badge script
		wp_enqueue_script( 'formshield-gravity-badge', plugins_url( 'js/gravity-forms-badge.js', dirname(__FILE__) ), array('jquery'), FORMSHIELD_VERSION, true );
		
		// Localize script with data
		wp_localize_script( 'formshield-gravity-badge', 'formshieldGravityData', array(
			'protectedForms' => $protected_gravity_forms,
			'badge' => FormShield_Safe::badge_html_for_js( 'Gravity Forms' )
		) );
	}
}

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