<?php
/**
 * Context Resolver for the Create Fundraiser Form block.
 *
 * Determines root fundraiser, parent, and nesting configuration from the
 * current page context so the block can render appropriately without extra
 * user input.
 *
 * @package AmbassadorHub\Fundraisers\Blocks\CreateFundraiserForm
 */

namespace AmbassadorHub\Fundraisers\Blocks\CreateFundraiserForm;

if ( ! defined( 'ABSPATH' ) ) {
	exit;
}

use AmbassadorHub\Fundraisers\FundraisersHelpers;
use AmbassadorHub\Fundraisers\FundraisersModule;

/**
 * Resolves page context into the parameters needed by the Create Fundraiser Form block.
 */
final class ContextResolver {

	/**
	 * Resolve form context for the current page request.
	 *
	 * @param array $attributes Block attributes.
	 *
	 * @return array
	 */
	public static function resolve( array $attributes = array() ): array {
		global $post;

		$force_child      = ! empty( $attributes['forceChildFundraiser'] );
		$force_individual = ! empty( $attributes['forceIndividualFundraiser'] );
		$context_mode     = $attributes['contextMode'] ?? 'auto';
		$root_id          = 0;
		$parent_id        = 0;

		// Resolve forced fundraiser type: 'team', 'individual', 'fundraiser', or '' (let ambassador choose).
		$forced_type = '';
		$attr_type   = $attributes['forceType'] ?? '';
		if ( in_array( $attr_type, array( 'team', 'individual', 'fundraiser' ), true ) ) {
			$forced_type = $attr_type;
		}
		// Legacy: forceIndividualFundraiser maps to forced_type = 'individual'.
		if ( $force_individual && '' === $forced_type ) {
			$forced_type = 'individual';
		}

		// --- Preset mode: use block-editor-configured IDs, bypass all detection ---
		if ( 'preset' === $context_mode ) {
			$preset_root   = (int) ( $attributes['presetRootId'] ?? 0 );
			$preset_parent = (int) ( $attributes['presetParentId'] ?? 0 );

			if ( $preset_parent > 0 ) {
				$parent_post = get_post( $preset_parent );
				if ( $parent_post && FundraisersModule::POST_TYPE === $parent_post->post_type ) {
					$parent_id = $preset_parent;
					$root_id   = FundraisersHelpers::get_root_fundraiser_id( $parent_id );
				}
			}

			if ( $preset_root > 0 && 0 === $root_id ) {
				$root_id = $preset_root;
			}

			return self::build_result( $root_id, $parent_id, $force_child, $force_individual, $forced_type );
		}

		// --- Query parameter overrides (highest priority) ---
		$qp_root   = isset( $_GET['root_id'] ) ? absint( $_GET['root_id'] ) : 0;       // phpcs:ignore WordPress.Security.NonceVerification.Recommended
		$qp_parent = isset( $_GET['parent_id'] ) ? absint( $_GET['parent_id'] ) : 0;       // phpcs:ignore WordPress.Security.NonceVerification.Recommended
		$qp_type   = isset( $_GET['type'] ) ? sanitize_key( $_GET['type'] ) : '';      // phpcs:ignore WordPress.Security.NonceVerification.Recommended
		if ( in_array( $qp_type, array( 'team', 'individual', 'fundraiser' ), true ) ) {
			$forced_type = $qp_type;
		}

		if ( $qp_parent > 0 ) {
			if ( FundraisersHelpers::is_valid_parent_fundraiser( $qp_parent ) ) {
				$parent_id = $qp_parent;
				$root_id   = FundraisersHelpers::get_root_fundraiser_id( $parent_id );
			}
		}

		if ( $qp_root > 0 && 0 === $root_id ) {
			$root_post = get_post( $qp_root );
			if ( $root_post && FundraisersModule::POST_TYPE === $root_post->post_type && 0 === (int) $root_post->post_parent ) {
				$root_id = $qp_root;
			}
		}

		// --- Page context (fallback when no query params are set) ---
		if ( 0 === $root_id && 0 === $parent_id && $post ) {
			$post_type = get_post_type( $post );

			if ( FundraisersModule::POST_TYPE === $post_type ) {
				if ( 0 === (int) $post->post_parent ) {
					$root_id = $post->ID;
				} else {
					$parent_id = $post->ID;
					$root_id   = FundraisersHelpers::get_root_fundraiser_id( $parent_id );
				}
			}
		}

		return self::build_result( $root_id, $parent_id, $force_child, $force_individual, $forced_type );
	}

	/**
	 * Build the final context array.
	 *
	 * @param int    $root_id          Resolved root fundraiser ID (0 = unknown).
	 * @param int    $parent_id        Resolved parent fundraiser ID (0 = none).
	 * @param bool   $force_child      From block attributes.
	 * @param bool   $force_individual From block attributes.
	 * @param string $forced_type      Pre-resolved forced type ('team', 'individual', 'fundraiser', or '').
	 *
	 * @return array
	 */
	private static function build_result( int $root_id, int $parent_id, bool $force_child, bool $force_individual, string $forced_type = '' ): array {
		$skip_root_step  = $root_id > 0;
		$nesting_enabled = FundraisersHelpers::root_allows_teams( $root_id );

		// Depth labels for use in headings.
		$depth_labels = array(
			2 => array(
				'singular' => __( 'Team', 'ambassadorhub' ),
				'plural'   => __( 'Teams', 'ambassadorhub' ),
			),
			3 => array(
				'singular' => __( 'Team', 'ambassadorhub' ),
				'plural'   => __( 'Teams', 'ambassadorhub' ),
			),
			4 => array(
				'singular' => __( 'Individual', 'ambassadorhub' ),
				'plural'   => __( 'Individuals', 'ambassadorhub' ),
			),
		);

		// When no explicit parent is set, children will be created directly under the root.
		$effective_parent = $parent_id > 0 ? $parent_id : $root_id;

		$parent_allows_nested_team = FundraisersHelpers::fundraiser_allows_nested_team( $effective_parent );
		$team_creation_possible    = FundraisersHelpers::team_creation_allowed( $root_id, $parent_id );
		$individual_allowed        = FundraisersHelpers::individual_creation_allowed( $effective_parent );
		$sub_fundraiser_allowed    = FundraisersHelpers::sub_fundraiser_creation_allowed( $effective_parent );

		// Show the type-selection step whenever no type is forced.
		$has_type_step = '' === $forced_type;

		// Detect impossible combinations for pre-forced types so the template can warn.
		$type_conflict = '';
		if ( 'team' === $forced_type ) {
			if ( $root_id > 0 && ! $nesting_enabled ) {
				$type_conflict = 'root_no_teams';
			} elseif ( $parent_id > 0 && $parent_id !== $root_id && ! $parent_allows_nested_team ) {
				$type_conflict = 'parent_no_nested';
			}
		}

		if ( '' !== $type_conflict ) {
			$forced_type = 'individual';
		}

		$fundraiser_end_date_enabled = $root_id > 0 && get_post_meta( $root_id, FundraisersModule::META_FUNDRAISER_END_DATE_ENABLED, true ) === '1';
		$root_end_date_gmt           = $root_id > 0 ? (string) get_post_meta( $root_id, FundraisersModule::META_END_DATE, true ) : '';

		return array(
			'root_id'                     => $root_id,
			'root_title'                  => $root_id > 0 ? get_the_title( $root_id ) : '',
			'parent_id'                   => $parent_id,
			'parent_title'                => $parent_id > 0 ? get_the_title( $parent_id ) : '',
			'nesting_enabled'             => $nesting_enabled,
			'skip_root_step'              => $skip_root_step,
			'can_create_root'             => FundraisersHelpers::ambassadors_can_create_root(),
			'depth_labels'                => $depth_labels,
			'force_child'                 => $force_child,
			'force_individual'            => $force_individual,
			'forced_type'                 => $forced_type,
			'has_type_step'               => $has_type_step,
			'type_conflict'               => $type_conflict,
			'individual_allowed'          => $individual_allowed,
			'team_allowed'                => $team_creation_possible,
			'sub_fundraiser_allowed'      => $sub_fundraiser_allowed,
			'fundraiser_end_date_enabled' => $fundraiser_end_date_enabled,
			'root_end_date_gmt'           => $root_end_date_gmt,
		);
	}
}
