<?php

class HappyForms_Message_Admin {

	/**
	 * The singleton instance.
	 *
	 * @since 1.0
	 *
	 * @var HappyForms_Message_Admin
	 */
	private static $instance;

	/**
	 * The form the form filter is pointing to.
	 *
	 * @since 1.0
	 *
	 * @var array
	 */
	private $current_form;

	/**
	 * The IDs of the forms the form filter is pointing to.
	 *
	 * @since 1.0
	 *
	 * @var array
	 */
	private $current_form_ids = array();

	/**
	 * The name of the Column Count option in the
	 * Screen Options tab.
	 *
	 * @since 1.0
	 *
	 * @var string
	 */
	private $column_count_option = 'happyforms-message-admin-col-count';

	/**
	 * The default amount of rows to show.
	 *
	 * @var int
	 */
	private $row_count = 20;

	/**
	 * The default amount of columns to show.
	 *
	 * @var int
	 */
	private $column_count = 1;


	/**
	 * The default amount of parts per submission to show.
	 *
	 * @var int
	 */
	private $parts_per_submission = 10;

	private $filter_status = 'activity_status';

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

		self::$instance->hook();

		return self::$instance;
	}

	/**
	 * Register hooks.
	 *
	 * @since 1.0
	 *
	 * @return void
	 */
	public function hook() {
		$controller = happyforms_get_message_controller();
		$this->post_type = $controller->post_type;

		add_action( 'parse_request', array( $this, 'parse_request' ) );
		add_action( 'admin_head', array( $this, 'output_styles' ) );
		add_filter( 'post_updated_messages', array( $this, 'post_updated_messages' ) );
		add_filter( 'bulk_post_updated_messages', array( $this, 'bulk_post_updated_messages' ), 10, 2 );
		add_action( 'load-edit.php', array( $this, 'define_screen_settings' ) );
		add_filter( 'screen_settings', array( $this, 'render_screen_settings' ), 10, 2 );
		add_filter( 'the_title', array( $this, 'filter_row_title' ), 10, 2 );
		add_filter( "manage_{$this->post_type}_posts_columns", array( $this, 'column_headers' ), PHP_INT_MAX );
		add_filter( "manage_edit-{$this->post_type}_sortable_columns", array( $this, 'sortable_columns' ), PHP_INT_MAX );
		add_action( "manage_{$this->post_type}_posts_custom_column", array( $this, 'column_content' ), 10, 2 );
		add_filter( 'list_table_primary_column', array( $this, 'table_primary_column' ), 10, 2 );
		add_filter( "views_edit-{$this->post_type}", array( $this, 'table_views' ) );
		add_filter( 'post_date_column_status', array( $this, 'post_date_column_status' ) );
		add_action( 'pre_get_posts', array( $this, 'pre_get_posts' ) );
		add_filter( 'post_class', array( $this, 'post_class' ), 10, 3 );
		add_action( 'restrict_manage_posts', array( $this, 'restrict_manage_posts' ), PHP_INT_MAX );
		add_filter( "bulk_actions-edit-{$this->post_type}", array( $this, 'bulk_actions' ) );
		add_filter( "handle_bulk_actions-edit-{$this->post_type}", array( $this, 'handle_bulk_actions' ), 10, 3 );
		add_filter( 'post_row_actions', array( $this, 'row_actions' ), 10, 2 );
		add_action( 'edit_form_after_title', array( $this, 'edit_screen' ) );
		add_filter( 'admin_footer_text', 'happyforms_admin_footer' );
		add_action( 'admin_notices', array( $this, 'print_activity_title_with_form_link' ) );
	}

	/**
	 * Action: set the current form and form ids
	 * depending on the value of the form filter.
	 *
	 * @since 1.0
	 *
	 * @hooked action parse_request
	 *
	 * @return void
	 */
	public function parse_request() {
		$form_id = isset( $_GET['form_id'] ) ? intval( $_GET['form_id'] ) : 0;

		if ( $form_id ) {
			$this->current_form = happyforms_get_form_controller()->get( $form_id );
			$this->current_form_ids = array( $form_id );
		} else {
			$this->current_form_ids = happyforms_get_form_controller()->get( array(), true );
		}
	}

	/**
	 * Action: output styles in the admin header of the Messages screen.
	 *
	 * @since 1.0
	 *
	 * @hooked action admin_head
	 *
	 * @return void
	 */
	public function output_styles() {
		global $pagenow;

		$post_type = happyforms_get_message_controller()->post_type;

		if ( 'edit.php' === $pagenow ) : ?>
		<style>
		#adv-settings fieldset {
			display: none;
		}
		#adv-settings fieldset:first-child {
			display: block;
		}
		</style>
		<?php endif;
	}

	/**
	 * Filter: tweak the text of the message post actions admin notices.
	 *
	 * @since 1.0
	 *
	 * @hooked filter post_updated_messages
	 *
	 * @param array $messages The messages configuration.
	 *
	 * @return array
	 */
	public function post_updated_messages( $messages ) {
		$post_type = happyforms_get_message_controller()->post_type;
		$permalink = get_permalink();
		$preview_url = get_preview_post_link();
		$view_form_link_html = sprintf(
			' <a href="%1$s">%2$s</a>',
			esc_url( $permalink ),
			__( 'Edit activity' )
		);
		$preview_post_link_html = sprintf(
			' <a target="_blank" href="%1$s">%2$s</a>',
			esc_url( $preview_url ),
			__( 'Preview activity' )
		);

		$messages[$post_type] = array(
			'',
			__( 'Activity updated.' ) . $view_form_link_html,
			__( 'Custom field updated.' ),
			__( 'Custom field deleted.' ),
			__( 'Activity updated.' ),
			isset($_GET['revision']) ? sprintf( __( 'Activity restored to revision from %s.' ), wp_post_revision_title( (int) $_GET['revision'], false ) ) : false,
			__( 'Activity published.' ) . $view_form_link_html,
			__( 'Activity saved.' ),
			__( 'Activity submitted.' ),
			__( 'Activity scheduled.' ),
			__( 'Activity draft updated.' ) . $preview_post_link_html,
		);

		return $messages;
	}

	/**
	 * Filter: tweak the text of the message post
	 * bulk actions admin notices.
	 *
	 * @since 1.0
	 *
	 * @hooked filter bulk_post_updated_messages
	 *
	 * @param array $messages The messages configuration.
	 * @param int   $count    The amount of posts for each bulk action.
	 *
	 * @return array
	 */
	public function bulk_post_updated_messages( $messages, $count ) {
		$post_type = happyforms_get_message_controller()->post_type;

		$messages[$post_type] = array(
			'updated'   => _n( '%s response updated.', '%s responses updated.', $count['updated'] ),
			'locked'    => _n( '%s response not updated, somebody is editing it.', '%s responses not updated, somebody is editing them.', $count['locked'] ),
			'deleted'   => _n( '%s response permanently deleted.', '%s responses permanently deleted.', $count['deleted'] ),
			'trashed'   => _n( '%s response moved to the Trash.', '%s responses moved to the Trash.', $count['trashed'] ),
			'untrashed' => _n( '%s submission restored from the Trash.', '%s submissions restored from the Trash.', $count['untrashed'] ),
		);

		return $messages;
	}

	/**
	 * Action: configure additional options for the Screen Options tab.
	 *
	 * @since 1.0
	 *
	 * @hooked action load-edit.php
	 *
	 * @return void
	 */
	public function define_screen_settings() {
		$screen = get_current_screen();
		$post_type = happyforms_get_message_controller()->post_type;
		$user_id = get_current_user_id();

		$row_count_option = 'edit_' . $post_type . '_per_page';

		if ( isset( $_REQUEST[$row_count_option] ) ) {
			$row_count = max( intval( $_REQUEST[$row_count_option] ), 1 );
			update_user_option( $user_id, $row_count_option, $row_count, true );
		}

		$parts_per_submission_option = 'edit_' . $post_type . '_parts_per_submission';

		if ( isset( $_REQUEST[$parts_per_submission_option] ) ) {
			$parts_per_submission = max( intval( $_REQUEST[$parts_per_submission_option] ), 1 );
			update_user_option( $user_id, $parts_per_submission_option, $parts_per_submission, true );
		}

		$row_count = get_user_option( $row_count_option, $user_id );
		$parts_per_submission = get_user_option( $parts_per_submission_option, $user_id );
		$row_count = ( false !== $row_count ) ? $row_count : $this->row_count;
		$parts_per_submission = ( false !== $parts_per_submission ) ? $parts_per_submission : $this->parts_per_submission;
		$this->row_count = max( intval( $row_count ), 1 );
		$this->parts_per_submission = max( intval( $parts_per_submission ), 1 );
	}

	/**
	 * Filter: output additional options in the Screen Options tab.
	 *
	 * @since 1.0
	 *
	 * @hooked filter screen_settings
	 *
	 * @param array     $settings The currently configured options.
	 * @param WP_Screen $count    The current screen object.
	 *
	 * @return void
	 */
	public function render_screen_settings( $settings, $screen ) {
		$post_type = happyforms_get_message_controller()->post_type;

		if ( 'edit-' . $post_type !== $screen->id ) {
			return $settings;
		}

		ob_start();
		?>
		<fieldset style="display: block;" class="happyforms-activity-settings-parts">
			<legend><?php _e( 'Fields', 'happyforms' ); ?></legend>
			<label for=""><?php _e( 'Number of fields per submission:', 'happyforms' ); ?></label>
			<input type="number" min="1" max="99" maxlength="2" name="edit_<?php echo esc_attr( $post_type ); ?>_parts_per_submission" value="<?php echo esc_attr( $this->parts_per_submission ); ?>">
			<input type="hidden" name="wp_screen_options[option]" value="<?php echo esc_attr( "edit_{$post_type}_parts_per_submission" ); ?>">
			<input type="hidden" name="wp_screen_options[value]" value="10">
		</fieldset>
		<fieldset style="display: block;" class="happyforms-activity-settings-pagination">
			<legend><?php _e( 'Pagination', 'happyforms' ); ?></legend>
			<label for=""><?php _e( 'Number of items per page:', 'happyforms' ); ?></label>
			<input type="number" min="1" max="99" maxlength="2" name="edit_<?php echo esc_attr( $post_type ); ?>_per_page" value="<?php echo esc_attr( $this->row_count ); ?>">
		</fieldset>
		<?php
		return ob_get_clean();
	}

	/**
	 * Filter: output table views links above table.
	 *
	 * @hooked filter views_edit-happyforms-message
	 *
	 * @param array     $views Currently configured views.
	 *
	 * @return void
	 */
	public function table_views( $default_views ) {
		$message_controller = happyforms_get_message_controller();
		$post_type = $message_controller->post_type;
		$counters = $message_controller->get_counters();
		$link_format = '<a href="%s" class="%s">%s <span class="count">(%s)</span></a>';

		$all_link = add_query_arg( array(
			'post_type' => $post_type,
		), 'edit.php' );
		$all_class = 'current';

		if ( isset( $_GET['post_status'] ) && 'all' !== $_GET['post_status'] ) {
			$all_class = '';
		}

		$unread_link = add_query_arg( array(
			'post_type' => $post_type,
			'activity_status' => 'unread'
		), 'edit.php' );
		$unread_class = '';

		$read_link = add_query_arg( array(
			'post_type' => $post_type,
			'activity_status' => 'read'
		), 'edit.php' );
		$read_class = '';

		$spam_link = add_query_arg( array(
			'post_type' => $post_type,
			'activity_status' => 'spam'
		), 'edit.php' );
		$spam_class = '';

		$trash_link = add_query_arg( array(
			'post_type' => $post_type,
			'post_status' => 'trash'
		), 'edit.php' );
		$trash_class = '';

		if ( isset( $_GET['activity_status'] ) ) {
			$all_class = '';

			switch ( $_GET['activity_status'] ) {
				case 'unread':
					$unread_class = 'current';
					break;
				case 'read':
					$read_class = 'current';
					break;
				case 'spam':
					$spam_class = 'current';
					break;
			}
		}

		if ( isset( $_GET['post_status'] ) && ( 'trash' === $_GET['post_status'] ) ) {
			$trash_class = 'current';
		}

		$views_all = sprintf(
			$link_format, $all_link, $all_class,
			__( 'All', 'happyforms' ),
			$counters['total']
		);

		$views_unread = sprintf(
			$link_format, $unread_link, $unread_class,
			__( 'Unread', 'happyforms' ),
			$counters['unread']
		);

		$views_read = sprintf(
			$link_format, $read_link, $read_class,
			__( 'Read', 'happyforms' ),
			$counters['read']
		);

		$views_spam = sprintf(
			$link_format, $spam_link, $spam_class,
			__( 'Spam', 'happyforms' ),
			$counters['spam']
		);

		$views_trash = sprintf(
			$link_format, $trash_link, $trash_class,
			__( 'Trash', 'happyforms' ),
			$this->count_trashed()
		);

		$views = array(
			'all' => $views_all,
			'unread' => $views_unread,
			'read' => $views_read,
			'spam' => $views_spam,
			'trash' => $views_trash,
		);

		return $views;
	}

	private function count_trashed() {
		global $wpdb;

		$post_type = happyforms_get_message_controller()->post_type;

		$result = $wpdb->get_col( "
			SELECT COUNT(ID)
			FROM $wpdb->posts
			WHERE post_status = 'trash'
			AND post_type = '$post_type'
		" );
		$result = $result[0];

		return $result;
	}

	public function table_primary_column( $default, $screen_id ) {
		$default = 'submission';

		return $default;
	}

	public function get_column_parts( $parts ) {
		$parts = array_filter( $parts, function( $part ) {
			return apply_filters( 'happyforms_message_part_visible', true, $part );
		} );
		$parts = array_values( $parts );

		return $parts;
	}

	/**
	 * Filter: filter the column headers for the
	 * All Messages admin screen table.
	 *
	 * @since 1.0
	 *
	 * @hooked filter manage_happyforms-message_posts_columns
	 *
	 * @param array $columns  The original table headers.
	 *
	 * @return array          The filtered table headers.
	 */
	public function column_headers( $columns ) {
		$cb_column = $columns['cb'];
		$columns = array( 'cb' => $cb_column );

		$forms = happyforms_get_form_controller()->get();
		$part_lists = wp_list_pluck( $forms, 'parts' );
		$part_lists = array_map( array( $this, 'get_column_parts' ), $part_lists );
		$part_counts = array_map( 'count', $part_lists );

		$columns['contact'] = __( 'Contact', 'happyforms' );
		$columns['submission'] = __( 'Submission', 'happyforms' );
		$columns['form'] = __( 'In Response To', 'happyforms' );
		$columns['datetime'] = __( 'Submitted On', 'happyforms' );

		if ( ! $this->current_form ) {
			return $columns;
		}

		$parts = $this->get_column_parts( $this->current_form['parts'] );

		/**
		 * Filter the column headers of responses admin table.
		 *
		 * @since 1.4.5
		 *
		 * @param array  $columns Current column headers.
		 *
		 * @return array
		 */
		$columns = apply_filters( 'happyforms_manage_response_column_headers', $columns );

		return $columns;
	}

	public function sortable_columns( $columns ) {
		$columns['contact'] = 'contact';
		$columns['form'] = 'form';
		$columns['datetime'] = 'datetime';

		return $columns;
	}

	/**
	 * Filter: output the columns content for the
	 * All Messages admin screen table.
	 *
	 * @since 1.0
	 *
	 * @hooked filter manage_happyforms-message_posts_custom_column
	 *
	 * @param array      $column   The current column header.
	 * @param int|string $id       The current message post object ID.
	 *
	 * @return void
	 */
	public function column_content( $column, $id ) {
		$message = happyforms_get_message_controller()->get( $id );
		$form_controller = happyforms_get_form_controller();
		$form = $form_controller->get( $message['form_id'] );

		$email_part = $form_controller->get_first_part_by_type( $form, 'email' );
		$email_value = '';

		if ( $email_part ) {
			$email_value = happyforms_get_message_part_value( $message['parts'][$email_part['id']], $email_part );
		}

		switch( $column ) {
			case 'form':
				$form_html = '';

				if ( $form ) {
					$messages_url = admin_url( "/edit.php?post_type=happyforms-message&form_id={$form['ID']}" );
					$message_counter = happyforms_get_message_controller()->get_counters( $form['ID'] );
					$form_html = '<div class="response-links">';

					if ( 'publish' === $form['post_status'] && current_user_can( 'happyforms_manage_forms' ) ) {
						$form_html .= sprintf(
							'<a href="%s" class="%s">%s</a>',
							happyforms_get_form_edit_link( $form['ID'] ),
							'comments-edit-item-link',
							$form['post_title']
						);
					} else {
						$form_html .= "<b>{$form['post_title']}</b>";
					}

					$referral_link = happyforms_get_meta( $id, 'client_referer', true );

					if ( $referral_link ) {
						$form_html .= sprintf(
							'<a href="%s" class="%s">%s</a>',
							$referral_link,
							'comments-view-item-link',
							__( 'View Referral', 'happyforms' )
						);
					}

					if ( 0 < $message_counter['total'] ) {
						$form_html .= '<div class="happyforms-responses-count-wrapper" data-form-id="'. $form['ID'] .'">';
						$form_html .= sprintf(
							'<a href="%s" class="happyforms-responses-count happyforms-responses-count-read">
								<span class="responses-count-read">%d</span>
								<span class="screen-reader-text">%d %s</span>
							</a>',
							$messages_url,
							$message_counter['total'],
							$message_counter['total'],
							__( 'read responses', 'happyforms' )
						);

						if ( 0 < $message_counter['unread'] ) {
							$messages_url_unread = add_query_arg( 'read', 'unread', $messages_url );
							$form_html .= sprintf(
								'<a href="%s" class="happyforms-responses-count happyforms-responses-count-unread">
									<span class="responses-count-unread">%d</span>
									<span class="screen-reader-text">%d %s</span>
								</a>',
								$messages_url_unread,
								$message_counter['unread'],
								$message_counter['unread'],
								__( 'unread responses', 'happyforms' )
							);
						}

						$form_html .= '</div>';
					}

					$form_html .= '</div>';
				}

				echo $form_html;
				break;

			case 'unique_id':
				echo $message['tracking_id'];
				break;

			case 'datetime':
				$submitted = sprintf(
					__( '%1$s at %2$s' ),
					get_post_time( __( 'Y/m/d' ), false, $id ),
					get_post_time( __( 'g:i a' ), false, $id )
				);

				echo $submitted;
				break;

			case 'contact':
				$content = sprintf(
					'%s —',
					get_avatar( false, 32 )
				);

				if ( ! empty( $email_value ) ) {
					$content = sprintf(
						'%s<a href="mailto:%s">%s</a>',
						get_avatar( $email_value, 32 ),
						$email_value,
						$email_value
					);
				}

				$ip_address = happyforms_get_meta( $id, 'client_ip', true );

				if ( $ip_address ) {
					$content .= '<br><br>';

					$content .= sprintf(
						'<a href="%s">%s</a>',
						admin_url( "edit.php?post_type={$message['post_type']}&s={$ip_address}" ),
						$ip_address
					);
				}

				echo $content;
				break;

			case 'submission':
				$avatar = get_avatar( $email_value, 32 );

				$content = sprintf(
					'<div class="author-info">%s —</div>',
					$avatar
				);

				if ( ! empty( $email_value ) ) {
					$content = sprintf(
						'<div class="author-info">%s<a href="mailto:%s">%s</a></div>',
						$avatar,
						$email_value,
						$email_value
					);
				}

				$parts = $this->get_column_parts( $form['parts'] );
				$parts = array_slice( $parts, 0, $this->parts_per_submission );

				$content .= '<div class="submission-data">';

				foreach ( $parts as $part ) {
					$part_id = $part['id'];
					$value = happyforms_get_message_part_value( $message['parts'][$part_id], $part, 'admin-column' );

					$content .= "{$part['label']}: {$value}" . "<br>";
				}

				$content .= '</div>';

				echo $content;
				break;

			default:
				if ( $form ) {
					$column_index = preg_match( '/column_(\d+)?/', $column, $matches );

					if ( $column_index ) {
						$column_index = intval( $matches[1] );
					}

					$parts = $this->get_column_parts( $form['parts'] );

					if ( count( $parts ) > $column_index ) {
						$part = $parts[$column_index];
						$part_id = $part['id'];

						if ( isset( $message['parts'][$part_id] ) ) {
							echo happyforms_get_message_part_value( $message['parts'][$part_id], $part, 'admin-column' );
						}
					}
				}
				break;
		}
	}

	/**
	 * Filter: silence the standard date column content.
	 *
	 * @since 1.0
	 *
	 * @hooked filter post_date_column_status
	 *
	 * @return void
	 */
	public function post_date_column_status() {
		return '';
	}

	public function pre_get_posts( $query ) {
		if ( ! is_admin() ) {
			return;
		}

		$post_type = $query->get( 'post_type' );
		$controller = happyforms_get_message_controller();

		if ( $post_type !== $controller->post_type ) {
			return;
		}

		// Only responses bound to a valid form.
		$query_vars = &$query->query_vars;
		$meta_query = array();
		$form_ids = (
			count( $this->current_form_ids ) > 0 ?
			$this->current_form_ids :
			happyforms_get_form_controller()->get( array(), true )
		);

		$form_clause = array();
		$form_clause['key'] = '_happyforms_form_id';
		$form_clause['value'] = $form_ids;
		$form_clause['compare'] = 'IN';
		$meta_query['form_clause'] = $form_clause;

		// Only responses that aren't spam,
		// if not explicitly requested.
		$read_clause = array(
			'key' => '_happyforms_read',
			'compare' => '!=',
			'value' => 2,
			'type' => 'NUMERIC',
		);

		if ( isset( $_GET[$this->filter_status] ) ) {
			switch( $_GET[$this->filter_status] ) {
				case 'unread':
					$read_clause['compare'] = '=';
					$read_clause['value'] = '';
					$read_clause['type'] = 'CHAR';
					break;
				case 'read':
					$read_clause['compare'] = '=';
					$read_clause['value'] = 1;
					$read_clause['type'] = 'NUMERIC';
					break;
				case 'spam':
					$read_clause['compare'] = '=';
					$read_clause['value'] = 2;
					$read_clause['type'] = 'NUMERIC';
					break;
			}
		}

		if ( ! isset( $_GET['post_status'] ) || ( 'trash' !== $_GET['post_status'] ) ) {
			$meta_query['read_clause'] = $read_clause;
		}

		// Expose email as a sortable value
		// for Contact column
		$email_clause = array(
			'relation' => 'OR',
			'email_address' => array(
				'key' => '_happyforms_email_',
				'compare_key' => 'LIKE',
			),
			'no_email_address' => array(
				'key' => '_happyforms_email_',
				'compare_key' => 'NOT EXISTS',
			),
		);

		if ( version_compare( get_bloginfo( 'version' ), '5.3', '>=' ) ) {
			$meta_query['email_clause'] = $email_clause;
		}

		$query_vars['meta_query'] = $meta_query;

		// Handle search query
		if ( $query->is_search ) {
			$term = $query_vars['s'];
			$metas = $controller->search_metas( $term );

			if ( count( $metas ) > 0 ) {
				$post_ids = wp_list_pluck( $metas, 'post_id' );
				$query_vars['post__in'] = $post_ids;
				$query_vars['s'] = '';

				// Pass the term to template anyway.
				add_filter( 'get_search_query', function() use ( $term ) {
					return $term;
				} );
			}
		}

		// Handle sorting
		$orderby = $query->get( 'orderby');

		if ( 'form' === $orderby ) {
			$query->set( 'meta_key', '_happyforms_form_id' );
			$query->set( 'orderby', 'meta_value_num' );
		}

		if ( 'contact' === $orderby ) {
			$query->set( 'orderby', 'email_address ID' );
		}
	}

	/**
	 * Filter: add custom HTML classes to message entries
	 * in the All Form admin screen table to represent
	 * read/unread status.
	 *
	 * @since 1.0
	 *
	 * @hooked filter post_date_column_status
	 *
	 * @param array      $class   Array of post classes.
	 * @param array      $classes Array of additional post classes.
	 * @param int|string $id      The message post object ID.
	 *
	 * @return array
	 */
	public function post_class( $class, $classes, $id ) {
		$message = happyforms_get_message_controller()->get( $id );

		if ( ! $message['read'] ) {
			$classes[] = 'happyforms-message-unread';
		}

		return $classes;
	}

	/**
	 * Filter: tweak the Title column content in the
	 * All Messages admin screen table.
	 *
	 * @since 1.0
	 *
	 * @hooked filter the_title
	 *
	 * @param string $title The current post object title.
	 * @param int    $id    The message post object ID.
	 *
	 * @return string
	 */
	public function filter_row_title( $title, $id ) {
		$message = happyforms_get_message_controller()->get( $id );
		$form = happyforms_get_form_controller()->get( $message['form_id'] );

		if ( empty( $form['parts'] ) ) {
			return $title;
		}

		$first_form_part = $form['parts'][0];
		$title = $first_form_part['label'];

		return $title;
	}

	/**
	 * Action: output the Form filter dropdown
	 * above the All Messages admin screen table.
	 *
	 * @since 1.0
	 *
	 * @hooked action restrict_manage_posts
	 *
	 * @return void
	 */
	public function restrict_manage_posts( $post_type ) {
		if ( happyforms_get_message_controller()->post_type === $post_type ) {
			// Remove any previous output.
			ob_clean();
			$forms = happyforms_get_form_controller()->get();
			$form_id = isset( $_GET['form_id'] ) ? intval( $_GET['form_id'] ) : '';
			?>
			<select name="form_id" id="">
				<option value=""><?php _e( 'From all forms', 'happyforms' ); ?></option>
				<?php foreach ( $forms as $form ) : ?>
					<?php if ( 'trash' !== $form['post_status'] ) : ?>
						<option value="<?php echo esc_attr( $form['ID'] ); ?>" <?php selected( $form_id, $form['ID'] ); ?>><?php _e( 'From', 'happyforms' ); ?> "<?php echo esc_html( $form['post_title'] ); ?>"</option>
					<?php endif; ?>
				<?php endforeach; ?>
			</select>
			<?php

			/**
			 * Output additional content in the
			 * responses admin table filters area.
			 *
			 * @since 1.4.5
			 *
			 * @param string $post_type Response post type.
			 *
			 * @return void
			 */
			do_action( 'happyforms_restrict_manage_responses', $post_type );
		}
	}

	/**
	 * Filter: modify the post query to account for
	 * the Form filter.
	 *
	 * @since 1.0
	 *
	 * @hooked filter parse_query
	 *
	 * @param WP_Query $query The current post query.
	 *
	 * @return void
	 */
	public function parse_query( $query ) {
		global $pagenow;

		if ( 'edit.php' !== $pagenow  ) {
			return;
		}

		$query_vars = &$query->query_vars;
		$post_type = happyforms_get_message_controller()->post_type;

		if ( $post_type !== $query->query['post_type'] ) {
			return;
		}

		$meta_query = array();
		$form_ids = (
			count( $this->current_form_ids ) > 0 ?
			$this->current_form_ids :
			happyforms_get_form_controller()->get( array(), true )
		);

		$form_clause = array();
		$form_clause['key'] = '_happyforms_form_id';
		$form_clause['value'] = $form_ids;
		$form_clause['compare'] = 'IN';
		$meta_query['form_clause'] = $form_clause;

		$read_clause = array(
			'key' => '_happyforms_read',
			'compare' => '!=',
			'value' => 2,
			'type' => 'NUMERIC',
		);

		if ( isset( $_GET['read'] ) ) {
			switch( $_GET['read'] ) {
				case 'unread':
					$read_clause['compare'] = '=';
					$read_clause['value'] = '';
					$read_clause['value'] = 'CHAR';
					break;
				case 'read':
					$read_clause['compare'] = '=';
					$read_clause['value'] = 1;
					$read_clause['value'] = 'NUMERIC';
					break;
				case 'spam':
					$read_clause['value'] = 2;
					$read_clause['value'] = 'NUMERIC';
					break;
			}
		}

		$meta_query['read_clause'] = $read_clause;
		$query_vars['meta_query'] = $meta_query;

		do_action( 'happyforms_message_admin_parse_query', $query );
	}

	/**
	 * Filter: add custom bulk actions for the
	 * All Messages admin screen table.
	 *
	 * @since 1.0
	 *
	 * @hooked filter bulk_actions-edit-happyforms-message
	 *
	 * @param array $actions Original bulk actions.
	 *
	 * @return array
	 */
	public function bulk_actions( $actions ) {
		$mark_unread = array( 'mark_unread' => __( 'Mark as Unread', 'happyforms' ) );
		$mark_read = array( 'mark_read' => __( 'Mark as Read', 'happyforms' ) );
		$mark_spam = array( 'mark_spam' => __( 'Mark as Spam', 'happyforms' ) );
		$mark_not_spam = array( 'mark_not_spam' => __( 'Not Spam', 'happyforms' ) );
		$trash = array( 'trash' => __( 'Move to Trash', 'happyforms' ) );
		$untrash = array( 'untrash' => __( 'Restore', 'happyforms' ) );
		$delete = array( 'delete' => __( 'Delete Permanently', 'happyforms' ) );
		$export_csv = array( 'export_csv' => __( 'Export to CSV', 'happyforms' ) );

		if ( ! isset( $_GET[$this->filter_status] ) && ! isset( $_GET['post_status'] ) ) {
			$actions = array_merge(
				$mark_unread,
				$mark_read,
				$mark_spam,
				$trash
			);
		} elseif ( isset( $_GET['post_status'] ) && 'trash' === $_GET['post_status'] ) {
			$actions = array_merge(
				$mark_spam,
				$untrash,
				$delete
			);
		} elseif ( isset( $_GET[$this->filter_status] ) && 'unread' === $_GET[$this->filter_status] ) {
			$actions = array_merge(
				$mark_read,
				$mark_spam,
				$trash
			);
		} elseif ( isset( $_GET[$this->filter_status] ) && 'read' === $_GET[$this->filter_status] ) {
			$actions = array_merge(
				$mark_unread,
				$mark_spam,
				$trash
			);
		} elseif ( isset( $_GET[$this->filter_status] ) && 'spam' === $_GET[$this->filter_status] ) {
			$actions = array_merge(
				$mark_not_spam,
				$delete
			);
		}

		if ( $this->current_form ) {
			$actions['export_csv'] = __( 'Export to CSV', 'happyforms' );
		}

		return $actions;
	}

	/**
	 * Filter: handle messages custom bulk actions.
	 *
	 * @since 1.0
	 *
	 * @hooked filter handle_bulk_actions-edit-happyforms-message
	 *
	 * @param string $redirect_to The url to redirect to
	 *                            after actions have been handled.
	 * @param string $action      The current bulk action.
	 * @param array  $ids         The array of message post object IDs.
	 *
	 * @return string
	 */
	public function handle_bulk_actions( $redirect_to, $action, $ids ) {
		switch( $action ) {
			case 'mark_read':
				foreach ( $ids as $id ) {
					happyforms_update_meta( $id, 'read', 1 );
				}
				happyforms_get_message_controller()->update_counters();
				break;
			case 'mark_unread':
				foreach ( $ids as $id ) {
					happyforms_update_meta( $id, 'read', '' );
				}
				happyforms_get_message_controller()->update_counters();
				break;
			case 'mark_spam':
				foreach ( $ids as $id ) {
					$current_status = happyforms_get_meta( $id, 'read', true );

					if ( 2 !== $current_status ) {
						happyforms_update_meta( $id, 'previously_read', $current_status );
					}

					happyforms_update_meta( $id, 'read', 2 );
					wp_untrash_post( $id );
				}
				happyforms_get_message_controller()->update_counters();
				break;
			case 'mark_not_spam':
				foreach ( $ids as $id ) {
					$status = '';

					if( happyforms_meta_exists( $id, 'previously_read' ) ) {
						$status = happyforms_get_meta( $id, 'previously_read', true );
					}

					happyforms_update_meta( $id, 'read', $status );
				}
				happyforms_get_message_controller()->update_counters();
				break;
			case 'export_csv':
				$this->export_csv( $ids );
				break;
		}

		return $redirect_to;
	}

	/**
	 * Filter: filter the row actions contents for the
	 * All Messages admin screen table.
	 *
	 * @since 1.0
	 *
	 * @hooked filter post_row_actions
	 *
	 * @param array   $actions The original array of action contents.
	 * @param WP_Post $post    The current post object.
	 *
	 * @return array           The filtered array of action contents.
	 */
	public function row_actions( $actions, $post ) {
		$controller = happyforms_get_message_controller();
		$post_type = $controller->post_type;

		if ( $post->post_type !== $post_type ) {
			return $actions;
		}

		$link_template = '<a href="%s">%s</a>';
		$url = happyforms_get_response_mark_link( $post->ID );
		$url_mark_as_read = add_query_arg( 'status', 'read', $url );
		$url_mark_as_unread = add_query_arg( 'status', 'unread', $url );
		$url_mark_as_spam = add_query_arg( 'status', 'spam', $url );
		$url_mark_as_not_spam = add_query_arg( 'status', 'not_spam', $url );
		$url_edit = get_edit_post_link( $post->ID );
		$url_restore = wp_nonce_url( add_query_arg( 'action', 'untrash', $url_edit ), 'untrash-post_' . $post->ID );
		$url_trash = get_delete_post_link( $post->ID, '' );
		$url_destroy = get_delete_post_link( $post->ID, '', true );

		$link_mark_as_read = array(
			__( 'Mark as Read', 'happyforms' ),
			$url_mark_as_read,
		);

		$link_mark_as_unread = array(
			__( 'Mark as Unread', 'happyforms' ),
			$url_mark_as_unread,
		);

		$link_mark_as_spam = array(
			__( 'Spam', 'happyforms' ),
			$url_mark_as_spam,
		);

		$link_mark_as_not_spam = array(
			__( 'Not Spam', 'happyforms' ),
			$url_mark_as_not_spam,
		);

		$link_edit = array(
			__( 'View', 'happyforms' ),
			$url_edit,
		);

		$link_trash = array(
			__( 'Trash', 'happyforms' ),
			$url_trash,
		);

		$link_destroy = array(
			__( 'Delete Permanently', 'happyforms' ),
			$url_destroy,
		);

		$link_restore = array(
			__( 'Restore', 'happyforms' ),
			$url_restore
		);

		$actions = array();
		$links = array();
		$response_status = happyforms_get_meta( $post->ID, 'read', true );

		if ( 'trash' !== $post->post_status ) {
			if ( 1 == $response_status ) {
				$links = array(
					'mark_unread' => $link_mark_as_unread,
					'edit' => $link_edit,
					'mark_spam' => $link_mark_as_spam,
					'trash' => $link_trash,
				);
			} else if ( 2 == $response_status ) {
				$links = array(
					'mark_not_spam' => $link_mark_as_not_spam,
					'delete' => $link_destroy,
				);
			} else if ( '' === $response_status ) {
				$links = array(
					'mark_read' => $link_mark_as_read,
					'edit' => $link_edit,
					'mark_spam' => $link_mark_as_spam,
					'trash' => $link_trash,
				);
			}
		} else {
			$links = array(
				'mark_spam' => $link_mark_as_spam,
				'untrash' => $link_restore,
				'delete' => $link_destroy
			);
		}

		foreach( $links as $key => $values ) {
			$actions[$key] = sprintf( $link_template, $values[1], $values[0] );
		}

		return $actions;
	}

	/**
	 * Action: output custom markup for the
	 * Message Edit admin screen.
	 *
	 * @since 1.0
	 *
	 * @hooked action edit_form_after_title
	 *
	 * @param WP_Post $post The message post object.
	 *
	 * @return void
	 */
	public function edit_screen( $post ) {
		global $message, $form;

		$message = happyforms_get_message_controller()->get( $post->ID );
		$form = happyforms_get_form_controller()->get( $message['form_id'] );
		$this->setup_message_navigation( $post->ID, $form['ID'] );

		require_once( happyforms_get_include_folder() . '/templates/admin-message-edit.php' );
	}

	private function export_csv( $ids = array() ) {
		global $wpdb;

		$this->parse_request();

		if ( ! $this->current_form ) {
			return;
		}

		require_once( happyforms_get_include_folder() . '/classes/class-exporter-csv.php' );

		$exporter = new HappyForms_Exporter_CSV( $this->current_form['ID'], 'messages.csv' );
		$exporter->export( $ids );
	}

	public function print_activity_title_with_form_link() {
		$post_type = ( isset( $_GET['post_type'] ) ) ? $_GET['post_type'] : '';

		if ( $this->post_type !== $post_type ) {
			return;
		}

		if ( ! isset( $_GET['form_id'] ) || empty( $_GET['form_id'] ) ) {
			return;
		}

		$form = happyforms_get_form_controller()->get( intval( $_GET['form_id'] ) );

		if ( ! $form ) {
			return;
		}

		$title = sprintf(
			'<h1 class="wp-heading-inline happyforms-activity-title">%s "<a href="%s">%s</a>"</h1>',
			__( 'Activity from', 'happyforms' ),
			happyforms_get_form_edit_link( $form['ID'] ),
			$form['post_title']
		);

		echo $title;
	}

}

/**
 * Initialize the HappyForms_Message_Admin class immediately.
 */
HappyForms_Message_Admin::instance();
