<?php

namespace GP_Entry_Blocks\Blocks;
use GFAPI, GP_Entry_Blocks;
use GP_Entry_Blocks\GF_Queryer;
use function GP_Entry_Blocks\replace_merge_tags;

/**
 * Block that displays entries in a table format.
 *
 * Displayed columns are configured using attributes. This block does not accept inner blocks.
 *
 * @since 1.0
 */
class Entries_Table extends Block {
	public $tag = 'table';

	public function __construct( $path ) {
		parent::__construct( $path );
	}

	public function render( $attributes, $content, $block ) {
		$form_id = rgar( $block->context, 'gp-entry-blocks/formId' );
		$form    = GFAPI::get_form( $form_id );

		/**
		 * @todo does there need to be any type of allow-list of what columns can be passed as the order_by param for security? e.g. pull from the summary columns
		 *       and only allow them.
		 */
		$queryer = GF_Queryer::attach( $block->context );

		if ( ! $queryer->is_entries() ) {
			return '';
		}

		if ( ! $form_id || ! $form ) {
			return esc_html__( 'Please select a form.', 'gp-entry-blocks' );
		}

		return $this->render_table_contents( $form, $attributes, $block );
	}

	public function render_table_contents( $form, $attributes, $block ) {
		/**
		 * @todo formFields needs renamed to Summary Columns to match the actual control label.
		 */
		$form_fields = rgar( $attributes, 'formFields' );

		if ( ! $form_fields || ! count( $form_fields ) ) {
			return '<p>' . esc_html__( 'Please select form fields to display.', 'gp-entry-blocks' ) . '</p>';
		}

		$entries = GF_Queryer::attach( $block->context )->entries;

		if ( ! $entries || ! count( $entries ) || is_wp_error( $entries ) ) {
			$no_entries_found_message = rgar( $attributes, 'noEntriesFoundMessage', esc_html__( 'No entries found.', 'gp-entry-blocks' ) );
			return '<p>' . replace_merge_tags( $no_entries_found_message, $form ) . '</p>';
		}

		/*
		 * Check if any entry can be edited by the current user. If not, skip showing the table heading for the
		 * edit/delete columns
		 */
		$can_edit_any_entry = false;

		foreach ( $entries as $entry ) {
			if ( gp_entry_blocks()->permissions->can_current_user_edit_entry( $entry ) ) {
				$can_edit_any_entry = true;
				break;
			}
		}

		$items   = array();
		$columns = array();

		foreach ( $form_fields as $form_field ) {
			$sorting_id = null;
			$meta       = is_array( rgar( $form_field, 'meta' ) ) ? rgar( $form_field, 'meta' ) : array();

			switch ( rgar( $form_field, 'type' ) ) {
				/**
				 * Do not show Edit, Delete, and Duplicate columns to those who can't use them.
				 */
				case 'edit-link':
				case 'delete-link':
				case 'duplicate-link':
					if ( ! $can_edit_any_entry ) {
						continue 2;
					}
					break;

				case 'field':
					if ( rgar( $meta, 'sortingId' ) ) {
						$sorting_id = rgar( $meta, 'sortingId' );
					} else {
						$sorting_id = rgar( $meta, 'fieldId' );
					}

					break;

				case 'meta':
					$sorting_id = rgar( $meta, 'metaKey' );
					break;

				case 'id':
				case 'date_created':
				case 'date_updated':
				case 'payment_status':
				case 'payment_method':
					$sorting_id = rgar( $form_field, 'type' );
					break;
			}

			$columns[] = new Entries_Table\Column(
				rgar( $form_field, 'type' ),
				array_merge(
					array(
						'form' => $form,
					),
					$meta
				),
				$sorting_id
			);
		}

		foreach ( $entries as $entry ) {
			$items[] = new Entries_Table\Row(
				/** This filter is documented in /includes/blocks/class-entries-loop.php */
				apply_filters( 'gpeb_entry', $entry, $form, $block ),
				/** This filter is documented in /includes/blocks/class-entries-loop.php */
				apply_filters( 'gpeb_entry_form', $form, $entry, $block )
			);
		}

		$table = new Entries_Table\Table( $items, $columns );

		return $table->render();
	}
}
