<?php

class HappyForms_Form_Restrict {

	/**
	 * The singleton instance.
	 *
	 * @var HappyForms_Form_Restrict
	 */
	private static $instance;

	private $was_restricted = false;

	/**
	 * The singleton constructor.
	 *
	 * @return HappyForms_Form_Restrict
	 */
	public static function instance() {
		if ( is_null( self::$instance ) ) {
			self::$instance = new self();
		}

		self::$instance->hook();

		return self::$instance;
	}

	/**
	 * Hook into WordPress.
	 *
	 * @return void
	 */
	public function hook() {
		add_filter( 'happyforms_meta_fields', array( $this, 'meta_fields' ) );
		add_filter( 'happyforms_setup_controls', array( $this, 'setup_controls' ) );
		add_filter( 'happyforms_messages_controls', array( $this, 'messages_controls' ) );
		add_filter( 'happyforms_validate_submission', array( $this, 'validate_submission' ), 10, 3 );
		add_filter( 'happyforms_messages_fields', array( $this, 'meta_messages_fields' ) );
		add_filter( 'happyforms_form_template_path', array( $this, 'form_template_path' ), 10, 3 );
	}

	public function meta_fields( $fields ) {
		$restrict_fields = array(
			'restrict_entries' => array(
				'default' => 0,
				'sanitize' => 'happyforms_sanitize_checkbox',
			),
			'max_entries' => array(
				'default' => 1000,
				'sanitize' => 'intval',
			),
			'max_entries_per_user' => array(
				'default' => 1,
				'sanitize' => 'intval',
			),
			'restrict_user_entries' => array(
				'default' => 0,
				'sanitize' => 'happyforms_sanitize_checkbox',
			),
		);

		$fields = array_merge( $fields, $restrict_fields );

		return $fields;
	}
	public function meta_messages_fields( $fields ) {
		$messages_fields = array(
			'max_entries_message' => array(
				'default' => __( "Oops. This form isn't accepting any more replies.", 'happyforms' ),
				'sanitize' => 'sanitize_text_field',
			),
			'max_entries_per_user_message' => array(
				'default' => __( 'Oops. You’ve already replied to this form.',
			'happyforms' ),
				'sanitize' => 'sanitize_text_field',
			),
		);

		$fields = array_merge( $fields, $messages_fields );

		return $fields;
	}

	public function setup_controls( $controls ) {
		$controls[2300] = array(
			'type' => 'checkbox',
			'label' => __( 'Limit submissions', 'happyforms' ),
			// 'tooltip' => __( 'Set limit on number of allowed form submissions.', 'happyforms' ),
			'field' => 'restrict_entries',
		);

		$controls[2301] = array(
			'type' => 'group_start',
			'trigger' => 'restrict_entries'
		);

		$controls[2302] = array(
			'type' => 'number',
			'label' => __( 'Max submissions', 'happyforms' ),
			'min' => 0,
			'field' => 'max_entries',
		);

		$controls[2305] = array(
			'type' => 'group_end'
		);

		$controls[2306] = array(
			'type' => 'checkbox',
			'label' => __( 'Limit submissions per user', 'happyforms' ),
			// 'tooltip' => __( 'Set limit on number of allowed form submissions per user.', 'happyforms' ),
			'field' => 'restrict_user_entries',
		);

		$controls[2307] = array(
			'type' => 'group_start',
			'trigger' => 'restrict_user_entries'
		);

		$controls[2308] = array(
			'type' => 'number',
			'label' => __( 'Max submissions per user', 'happyforms' ),
			'min' => 0,
			'field' => 'max_entries_per_user',
		);

		$controls[2310] = array(
			'type' => 'group_end',
		);

		return $controls;
	}

	public function messages_controls( $controls ) {
		$controls[60] = array(
			'type' => 'text',
			'label' => __( 'Form has reached its reply limit', 'happyforms' ),
			'field' => 'max_entries_message',
		);

		$controls[100] = array(
			'type' => 'text',
			'label' => __( 'Respondent has reached their reply limit', 'happyforms' ),
			'field' => 'max_entries_per_user_message',
		);

		return $controls;
	}

	public function is_restricted( $form = array() ) {
		$restricted = false;

		if ( ! happyforms_get_form_property( $form, 'restrict_entries' ) ) {
			return $restricted;
		}

		$message_controller = happyforms_get_message_controller();
		$max_entries = happyforms_get_form_property( $form, 'max_entries' );
		$form_id = $form['ID'];

		if ( ! $max_entries ) {
			return $restricted;
		}

		$messages = $message_controller->get_by_form( $form_id );

		if ( $max_entries <= count( $messages ) ) {
			$restricted = true;
		}

		return $restricted;
	}

	public function is_restricted_for_user( $form = array(), $request = array() ) {
		$restricted = false;

		if ( ! happyforms_get_form_property( $form, 'restrict_user_entries' ) && ! happyforms_get_form_property( $form, 'restrict_entries' ) ) {
			return $restricted;
		}

		if ( ! happyforms_get_meta( $form['ID'], 'restrict_user_entries', true ) && ! happyforms_get_form_property( $form, 'restrict_entries' ) ) {
			return $restricted;
		}

		$message_controller = happyforms_get_message_controller();
		$form_controller = happyforms_get_form_controller();
		$max_entries_per_user = happyforms_get_form_property( $form, 'max_entries_per_user' );

		if ( ! $max_entries_per_user || empty( $request ) ) {
			return $restricted;
		}

		$part = apply_filters( 'happyforms_submission_identifier_part', false, $form );

		if ( ! $part ) {
			$part = $form_controller->get_first_part_by_type( $form, 'email' );
		}

		if ( ! $part ) {
			return $restricted;
		}

		$part_class = happyforms_get_part_library()->get_part( $part['type'] );

		if ( false === $part_class ) {
			return $restricted;
		}

		$part_id = $part['id'];
		$form_id = $form['ID'];
		$part_name = happyforms_get_part_name( $part, $form );
		$sanitized_value = $part_class->sanitize_value( $part, $form, $request );
		$validated_value = $part_class->validate_value( $sanitized_value, $part, $form );

		if ( is_wp_error( $validated_value ) ) {
			return $restricted;
		}

		$part_value = happyforms_stringify_part_value( $validated_value, $part, $form );

		$messages = $message_controller->get_by_metas( array(
			'form_id' => $form_id,
			$part_id => $part_value,
		) );

		if ( $max_entries_per_user <= count( $messages ) ) {
			$session = happyforms_get_session();
			$session->add_error(
				$part_name,
				happyforms_get_form_property( $form, 'max_entries_per_user_message' )
			);
			$restricted = true;
		}

		return $restricted;
	}

	public function validate_submission( $is_valid, $request, $form ) {
		if ( $this->is_restricted( $form ) ) {
			$this->was_restricted = true;
			$is_valid = false;

			return $is_valid;
		}

		remove_filter( 'happyforms_form_template_path', array( $this, 'form_template_path' ) );

		if ( $this->is_restricted_for_user( $form, $request ) ) {
			$is_valid = false;
		}

		return $is_valid;
	}

	public function form_template_path( $template_path, $form ) {
		if ( $this->was_restricted || $this->is_restricted( $form ) ) {
			$session = happyforms_get_session();
			$session->add_error(
				$form['ID'],
				html_entity_decode( $form['max_entries_message'] )
			);
			$template_path = happyforms_get_include_folder() . '/templates/single-form-restricted.php';
		}

		return $template_path;
	}

}

if ( ! function_exists( 'happyforms_get_form_restrict' ) ):

function happyforms_get_form_restrict() {
	return HappyForms_Form_Restrict::instance();
}

endif;

happyforms_get_form_restrict();
