<?php

namespace ModernFields\WordPress\Hooks;

use ModernFields\WordPress\Interfaces\Hooks;

use WP_Block_Type_Registry;

defined('ABSPATH') || exit;

/**
 * Handles registration and management of custom Gutenberg blocks.
 *
 * Block naming convention:
 *   modern-fields/*         → field input blocks (field group editor only)
 *   modern-fields-display/* → display blocks (regular editors only)
 *
 * @since 1.0.0
 */
class Blocks implements Hooks
{
  /**
   * @since 1.0.0
   * @return void
   */
  public function registerHooks(): void
  {
    add_action('init', [$this, 'registerBlocks']);
    add_filter('block_categories_all', [$this, 'registerBlockCategories']);
    add_filter('allowed_block_types_all', [$this, 'restrictBlocksToFieldGroup'], 999, 2);
  }

  /**
   * @since 1.0.0
   * @return void
   */
  public function registerBlocks(): void
  {
    wp_register_block_types_from_metadata_collection(
      MODERN_FIELDS_PLUGIN_DIR . 'build/blocks',
      MODERN_FIELDS_PLUGIN_DIR . 'build/blocks-manifest.php'
    );
  }

  /**
   * @since 1.0.0
   * @param array $categories
   * @return array
   */
  public function registerBlockCategories(array $categories): array
  {
    return array_merge(
      [
        ['slug' => 'mf-input-fields', 'title' => __('Input Fields', 'modern-fields')],
        ['slug' => 'mf-select-fields', 'title' => __('Selection Fields', 'modern-fields')],
        ['slug' => 'mf-design-fields', 'title' => __('Design Fields', 'modern-fields')],
        ['slug' => 'mf-date-fields', 'title' => __('Date Fields', 'modern-fields')],
        ['slug' => 'mf-media-fields', 'title' => __('Media Fields', 'modern-fields')],
        ['slug' => 'mf-advanced-fields', 'title' => __('Advanced Fields', 'modern-fields')],
      ],
      $categories,
    );
  }

  /**
   * @since 1.0.0
   * @param array|bool $allowed_blocks
   * @param WP_Block_Editor_Context $editor_context
   * @return array|bool
   */
  public function restrictBlocksToFieldGroup($allowed_blocks, $editor_context): array|bool
  {
    $registry = WP_Block_Type_Registry::get_instance();

    # In a field group: allow field input blocks, exclude display blocks and restricted core blocks
    if (isset($editor_context->post) && $editor_context->post->post_type === MODERN_FIELDS_CPT_SLUG) {
      $block_list = array_keys($registry->get_all_registered());

      $core_blocks_to_disable = apply_filters(
        'modern-fields/blocks/disabled_blocks',
        require MODERN_FIELDS_PLUGIN_DIR . 'data/disabledBlocks.php'
      );

      return array_values(array_filter($block_list, function (string $block) use ($core_blocks_to_disable) {
        return !str_starts_with($block, 'modern-fields-display/')
          && !in_array($block, $core_blocks_to_disable, true);
      }));
    }

    # In all other editors: allow display blocks, exclude field input blocks
    $block_list = is_array($allowed_blocks)
      ? $allowed_blocks
      : array_keys($registry->get_all_registered());

    return array_values(array_filter($block_list, function (string $block) {
      return str_starts_with($block, 'modern-fields-display/')
        || !str_starts_with($block, 'modern-fields/');
    }));
  }
}
