<?php
/**
 * Header option field visibility — single source of truth.
 *
 * Used by Admin UI (HeaderPage) and save normalization (Dashboard).
 *
 * @package Kutby
 * @since   2.6.1
 */

declare(strict_types=1);

namespace Kutby\Header\Services;

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

/**
 * Class HeaderVisibility
 */
final class HeaderVisibility {

	/**
	 * Schema keys reserved for experimental components — never Admin-visible.
	 *
	 * @var array<int, string>
	 */
	private const EXPERIMENTAL = array(
		'show_theme_toggle',
		'show_account',
		'show_social',
	);

	/**
	 * Keys always shown for the header panel (any layout).
	 *
	 * @var array<int, string>
	 */
	public const ALWAYS_VISIBLE = array( 'layout', 'sticky' );

	/**
	 * Resolve visible schema keys for a layout id.
	 *
	 * @param string $layout_id Layout id (empty → classic).
	 * @return array<int, string>
	 */
	public static function visible_keys( string $layout_id = '' ): array {
		$layout_id = sanitize_key( $layout_id );
		if ( '' === $layout_id ) {
			$layout_id = HeaderManager::DEFAULT_LAYOUT;
		}

		$allowed  = self::ALWAYS_VISIBLE;
		$registry = HeaderRegistry::instance();
		$layout   = $registry->make( $layout_id );

		if ( null === $layout ) {
			$layout = $registry->make( HeaderManager::DEFAULT_LAYOUT );
		}

		if ( null !== $layout ) {
			$allowed = array_merge( $allowed, $layout->option_keys() );
		}

		$allowed = array_values( array_unique( $allowed ) );
		$allowed = array_values( array_diff( $allowed, self::EXPERIMENTAL ) );

		return $allowed;
	}

	/**
	 * Resolve visible keys from posted/current header option arrays.
	 *
	 * @param array<string, mixed> $posted  Posted header group (may be empty).
	 * @param array<string, mixed> $current Stored header group (fallback for layout).
	 * @return array<int, string>
	 */
	public static function visible_keys_from_values( array $posted, array $current = array() ): array {
		$layout_id = '';
		if ( isset( $posted['layout'] ) && is_scalar( $posted['layout'] ) ) {
			$layout_id = sanitize_key( (string) $posted['layout'] );
		}
		if ( '' === $layout_id && isset( $current['layout'] ) && is_scalar( $current['layout'] ) ) {
			$layout_id = sanitize_key( (string) $current['layout'] );
		}

		return self::visible_keys( $layout_id );
	}

	/**
	 * Whether a schema key is visible for the given layout.
	 *
	 * @param string $key       Field key.
	 * @param string $layout_id Layout id.
	 * @return bool
	 */
	public static function is_visible( string $key, string $layout_id = '' ): bool {
		return in_array( sanitize_key( $key ), self::visible_keys( $layout_id ), true );
	}
}
