<?php
/**
 * Theme Builder admin navigation registry (tabs + sidebar groups).
 *
 * @package Sifency_Addons
 */

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

/**
 * Loads, filters, and caches theme builder admin tabs and nav structure.
 */
class Sifency_Addons_Themebuilder_Navigation_Registry {

	/** @var array<string, array>|null */
	private static $tabs_cache = null;

	/** @var array<string, array>|null */
	private static $nav_cache = null;

	/**
	 * Filtered theme builder tabs (tab slug => config).
	 *
	 * @return array<string, array>
	 */
	public static function get_tabs(): array {
		if ( null !== self::$tabs_cache ) {
			return self::$tabs_cache;
		}

		$tabs = function_exists( 'sifency_addons_themebuilder_get_default_tabs' )
			? sifency_addons_themebuilder_get_default_tabs()
			: array();

		/**
		 * Filter theme builder admin tabs before exclusions.
		 *
		 * @param array<string, array> $tabs Tab slug => [ label, icon, sync_state, ... ].
		 */
		$tabs = apply_filters( 'sifency_addons_themebuilder_tabs', $tabs );

		$excluded = apply_filters( 'sifency_addons_excluded_themebuilder_tabs', array() );
		if ( is_array( $excluded ) && ! empty( $excluded ) ) {
			foreach ( $excluded as $tab_slug ) {
				unset( $tabs[ (string) $tab_slug ] );
			}
		}

		self::$tabs_cache = is_array( $tabs ) ? $tabs : array();

		return self::$tabs_cache;
	}

	/**
	 * Filtered sidebar navigation structure for the theme builder admin page.
	 *
	 * @return array<string, array>
	 */
	public static function get_nav_structure(): array {
		if ( null !== self::$nav_cache ) {
			return self::$nav_cache;
		}

		$structure = function_exists( 'sifency_addons_themebuilder_get_default_nav_structure' )
			? sifency_addons_themebuilder_get_default_nav_structure()
			: array();

		/**
		 * Filter theme builder sidebar navigation groups and single links.
		 *
		 * @param array<string, array> $structure Nav group key => group config.
		 */
		$structure = apply_filters( 'sifency_addons_themebuilder_nav_structure', $structure );

		$excluded_groups = apply_filters( 'sifency_addons_excluded_themebuilder_nav_groups', array() );
		if ( is_array( $excluded_groups ) && ! empty( $excluded_groups ) ) {
			foreach ( $excluded_groups as $group_key ) {
				unset( $structure[ (string) $group_key ] );
			}
		}

		$structure = self::prune_nav_structure( $structure, self::get_tabs() );

		self::$nav_cache = $structure;

		return self::$nav_cache;
	}

	/**
	 * Clears in-request cache.
	 */
	public static function clear_cache(): void {
		self::$tabs_cache = null;
		self::$nav_cache  = null;
	}

	/**
	 * Removes nav items whose tab was excluded; drops empty groups.
	 *
	 * @param array<string, array> $structure Nav structure.
	 * @param array<string, array> $tabs      Available tabs.
	 * @return array<string, array>
	 */
	private static function prune_nav_structure( array $structure, array $tabs ): array {
		foreach ( $structure as $group_key => $group_data ) {
			if ( ! is_array( $group_data ) ) {
				unset( $structure[ $group_key ] );
				continue;
			}

			if ( isset( $group_data['type'] ) && 'single' === $group_data['type'] ) {
				$slug = $group_data['slug'] ?? '';
				if ( '' === $slug || ! isset( $tabs[ $slug ] ) ) {
					unset( $structure[ $group_key ] );
				}
				continue;
			}

			if ( isset( $group_data['type'] ) && 'group' === $group_data['type'] && ! empty( $group_data['items'] ) && is_array( $group_data['items'] ) ) {
				$group_data['items'] = array_values(
					array_filter(
						$group_data['items'],
						static function ( $tab_slug ) use ( $tabs ) {
							return isset( $tabs[ (string) $tab_slug ] );
						}
					)
				);

				if ( empty( $group_data['items'] ) ) {
					unset( $structure[ $group_key ] );
					continue;
				}

				$structure[ $group_key ] = $group_data;
			}
		}

		return $structure;
	}
}
