<?php
/**
 * Filterable HowTo block limits with hard caps.
 *
 * @package SEOvaultSEO\Blocks
 */

namespace SEOvaultSEO\Blocks;

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

/**
 * Soft defaults + hard maximums for HowTo block attributes.
 */
class HowToBlockLimits {

	const DEFAULT_MAX_STEPS              = 20;
	const HARD_MAX_STEPS                 = 40;
	const DEFAULT_MAX_SUPPLIES           = 20;
	const HARD_MAX_SUPPLIES              = 40;
	const DEFAULT_MAX_TOOLS              = 20;
	const HARD_MAX_TOOLS                 = 40;
	const DEFAULT_MAX_NAME_LENGTH        = 160;
	const HARD_MAX_NAME_LENGTH           = 320;
	const DEFAULT_MAX_DESCRIPTION_LENGTH = 600;
	const HARD_MAX_DESCRIPTION_LENGTH    = 2000;
	const DEFAULT_MAX_STEP_NAME_LENGTH   = 160;
	const HARD_MAX_STEP_NAME_LENGTH      = 320;
	const DEFAULT_MAX_STEP_TEXT_LENGTH   = 2000;
	const HARD_MAX_STEP_TEXT_LENGTH      = 8000;
	const DEFAULT_MAX_SUPPLY_LENGTH      = 160;
	const HARD_MAX_SUPPLY_LENGTH         = 320;
	const DEFAULT_MAX_TOOL_LENGTH        = 160;
	const HARD_MAX_TOOL_LENGTH           = 320;
	const DEFAULT_MAX_PAYLOAD_BYTES      = 65536;
	const HARD_MAX_PAYLOAD_BYTES         = 131072;

	/**
	 * Allowed display modes.
	 *
	 * @return string[]
	 */
	public static function display_modes() {
		return array( 'numbered', 'cards', 'compact' );
	}

	/**
	 * Allowed style presets.
	 *
	 * @return string[]
	 */
	public static function style_presets() {
		return array(
			'clean',
			'bordered',
			'soft-cards',
			'editorial',
			'minimal',
			'dark',
		);
	}

	/**
	 * Allowed color presets.
	 *
	 * @return string[]
	 */
	public static function color_presets() {
		return array( 'blue', 'green', 'purple', 'orange', 'dark', 'neutral' );
	}

	/**
	 * Allowed density values.
	 *
	 * @return string[]
	 */
	public static function densities() {
		return array( 'compact', 'comfortable', 'spacious' );
	}

	/**
	 * Resolve one filterable limit clamped to hard max.
	 *
	 * @param string $key      Limit key.
	 * @param int    $default  Soft default.
	 * @param int    $hard_max Hard cap.
	 * @param array  $context  Optional overrides.
	 * @return int
	 */
	public static function get( $key, $default, $hard_max, array $context = array() ) {
		if ( isset( $context[ $key ] ) ) {
			$value = (int) $context[ $key ];
		} else {
			/**
			 * Filter a HowTo block limit.
			 *
			 * @param int    $default Soft default.
			 * @param string $key     Limit key.
			 * @param array  $context Context.
			 */
			$value = (int) apply_filters( 'seovaultseo_howto_block_limits', $default, $key, $context );
			if ( is_array( $value ) ) {
				$value = isset( $value[ $key ] ) ? (int) $value[ $key ] : $default;
			}
		}

		$value = max( 0, $value );
		return min( $value, (int) $hard_max );
	}

	/**
	 * Snapshot of active limits.
	 *
	 * @param array $context Overrides.
	 * @return array<string,int>
	 */
	public static function all( array $context = array() ) {
		return array(
			'max_steps'              => self::get( 'max_steps', self::DEFAULT_MAX_STEPS, self::HARD_MAX_STEPS, $context ),
			'max_supplies'           => self::get( 'max_supplies', self::DEFAULT_MAX_SUPPLIES, self::HARD_MAX_SUPPLIES, $context ),
			'max_tools'              => self::get( 'max_tools', self::DEFAULT_MAX_TOOLS, self::HARD_MAX_TOOLS, $context ),
			'max_name_length'        => self::get( 'max_name_length', self::DEFAULT_MAX_NAME_LENGTH, self::HARD_MAX_NAME_LENGTH, $context ),
			'max_description_length' => self::get( 'max_description_length', self::DEFAULT_MAX_DESCRIPTION_LENGTH, self::HARD_MAX_DESCRIPTION_LENGTH, $context ),
			'max_step_name_length'   => self::get( 'max_step_name_length', self::DEFAULT_MAX_STEP_NAME_LENGTH, self::HARD_MAX_STEP_NAME_LENGTH, $context ),
			'max_step_text_length'   => self::get( 'max_step_text_length', self::DEFAULT_MAX_STEP_TEXT_LENGTH, self::HARD_MAX_STEP_TEXT_LENGTH, $context ),
			'max_supply_length'      => self::get( 'max_supply_length', self::DEFAULT_MAX_SUPPLY_LENGTH, self::HARD_MAX_SUPPLY_LENGTH, $context ),
			'max_tool_length'        => self::get( 'max_tool_length', self::DEFAULT_MAX_TOOL_LENGTH, self::HARD_MAX_TOOL_LENGTH, $context ),
			'max_payload_bytes'      => self::get( 'max_payload_bytes', self::DEFAULT_MAX_PAYLOAD_BYTES, self::HARD_MAX_PAYLOAD_BYTES, $context ),
		);
	}
}
