<?php

namespace GP_Entry_Blocks\Compatibility;

use GFAPI;
use GP_Entry_Blocks\GF_Queryer;

class GP_Nested_Forms {
	/**
	 * Used for telling GPNF to bypass permissions check for the child entries.
	 *
	 * This strategy is used to put most of the work here on get_submitted_entry_ids() rather than duplicating code.
	 *
	 * @var null|number `null` if not bypassing permissions, ID of the form ID if bypassing.
	 */
	private $_bypass_permissions;

	public function __construct() {
		if ( ! function_exists( 'gp_nested_forms' ) ) {
			return;
		}

		add_action( 'gpeb_before_render_block', array( $this, 'hook_simple_template' ), 10, 3 );
		add_action( 'gpeb_after_render_block', array( $this, 'unhook_simple_template' ), 10, 3 );
		add_filter( 'gpnf_submitted_entry_ids', array( $this, 'get_submitted_entry_ids' ), 10, 3 );
		add_filter( 'gpnf_bypass_entry_permissions', array( $this, 'bypass_edit_permissions' ), 10, 3 );
	}

	/**
	 * Temporarily add an action to `gpnf_template_args` to use the simple template rather than detailed when displayed in GPEB. The primary reason is that
	 * the detailed view is meant for the Entry Details view in the WordPress admin as it outputs links that also link to the admin.
	 *
	 * @param \WP_Block $block The current block.
	 *
	 * @return void
	 */
	public function hook_simple_template( $block ) {
		if ( $block->name !== 'gp-entry-blocks/entries-table' ) {
			return;
		}

		add_filter( 'gpnf_template_args', array( $this, 'use_simple_template' ), 10, 2 );
	}

	/**
	 * Remove our temporary hook to switch the Nested Forms template to simple when displayed via GPEB.
	 *
	 * @param \WP_Block $block The current block.
	 *
	 * @return void
	 */
	public function unhook_simple_template( $block ) {
		remove_filter( 'gpnf_template_args', array( $this, 'use_simple_template' ) );
	}

	/**
	 * Change the GPNF template that's used to be the simple output.
	 *
	 * @param array $args Template args to filter.
	 * @param \GP_Nested_Form_Field $gpnf Nested Form field instance
	 *
	 * @return array
	 */
	public function use_simple_template( $args, $gpnf ) {
		$args['template'] = 'nested-entries-detail-simple';

		return $args;
	}

	/**
	 * Filter the child entry IDs for the current parent entry if it's being edited with GP Entry Blocks.
	 *
	 * Additionally, set _bypass_permissions to control the value of gpnf_bypass_entry_permissions the next time the filter is run.
	 *
	 * Permissions check on the parent is not needed here as Entry Blocks handles it automatically.
	 *
	 * @param number[] $entry_ids The child entry IDs being filtered.
	 * @param array $form The current form having its entries displayed.
	 * @param \GF_Field $field The current Nested Form field.
	 *
	 * @return false|string[] The child entries to display. If allowed, it'll be changed to the child entries of the entry being displayed by GPEB.
	 */
	public function get_submitted_entry_ids( $entry_ids, $form, $field ) {
		// Get the entry ID being edited from GF_Queryer
		$queryer = GF_Queryer::attach_to_current_block();

		if ( ! $queryer || ! method_exists( $queryer, 'get_entry' ) ) {
			return $entry_ids;
		}

		$edit_entry = $queryer->get_entry();

		if ( empty( $entry_ids ) && rgar( $edit_entry, 'id' ) ) {
			$parent_entry = $edit_entry;

			if ( (int) $parent_entry['form_id'] === (int) $form['id'] ) {
				$entry_ids = gp_nested_forms()->get_child_entry_ids_from_value( gp_nested_forms()->get_field_value( $form, $parent_entry, $field->id ) );

				if ( $entry_ids ) {
					$this->_bypass_permissions = $form['id'];
				}
			}
		}

		return $entry_ids;
	}

	/**
	 * @param boolean $bypass_permissions Whether permissions checks (e.g. admin or created entry) should be bypassed for the displayed entries.
	 * @param array $form The current form having its entries displayed.
	 * @param \GF_Field $field The current Nested Form field.
	 *
	 * @return bool|mixed Whether permissions checks should be bypassed.
	 */
	public function bypass_edit_permissions( $bypass_permissions, $form, $field ) {
		if ( $form['id'] !== $this->_bypass_permissions ) {
			return $bypass_permissions;
		}

		if ( $this->_bypass_permissions ) {
			$this->_bypass_permissions = null;
			return true;
		}

		return $bypass_permissions;
	}

}
