<?php

defined( 'ABSPATH' ) || exit;

/**
 * White-label branding resolver.
 *
 * Single source of truth for the three brand keys:
 *   - plugin_display_name  (shown in plugins.php list + Settings submenu title)
 *   - block_category_label (the Gutenberg category clients see in the inserter)
 *   - block_title_prefix   (prepended to every bw-dev block's display title)
 *
 * The category slug `bw-dev-blocks` is registered server-side and is stable.
 * The title/category LABEL rewrites happen JS-side via a `blocks.registerBlockType`
 * filter — see assets/js/branding.js.
 *
 * Scope per the Phase 7 plan: "Blocks + plugin admin name". The tab labels
 * inside Settings → BW Dev intentionally stay BW-branded since clients don't
 * visit there.
 *
 * @package BW_Dev
 */

class BW_Dev_Brand {

	const CATEGORY_SLUG = 'bw-dev-blocks';

	/**
	 * @var BW_Dev_Settings
	 */
	private $settings;

	/**
	 * Built-in defaults. Overridden by the persisted brand (under
	 * bw_dev_settings.brand) and finally by the `bw_dev_brand` filter.
	 *
	 * @var array
	 */
	private $defaults = array(
		'plugin_display_name'  => 'BW Dev',
		'block_category_label' => 'BW Blocks',
		'block_title_prefix'   => 'BW ',
	);

	public function __construct( BW_Dev_Settings $settings ) {
		$this->settings = $settings;
	}

	/**
	 * Resolved brand config. Persisted overrides first, then the filter.
	 */
	public function resolve(): array {
		$persisted = (array) $this->settings->get( 'brand', null, array() );
		$resolved  = $this->defaults;
		foreach ( $this->defaults as $key => $_default ) {
			if ( isset( $persisted[ $key ] ) && '' !== (string) $persisted[ $key ] ) {
				$resolved[ $key ] = (string) $persisted[ $key ];
			}
		}
		/**
		 * Filter the resolved brand config. Useful for mu-plugins that need
		 * to force a brand without persisting it to wp_options.
		 *
		 * @param array $resolved {plugin_display_name, block_category_label, block_title_prefix}
		 */
		return (array) apply_filters( 'bw_dev_brand', $resolved );
	}

	public function defaults(): array {
		return $this->defaults;
	}

	public function register(): void {
		add_filter( 'all_plugins',                array( $this, 'filter_plugin_name' ) );
		add_filter( 'block_categories_all',       array( $this, 'register_block_category' ) );
		add_action( 'enqueue_block_editor_assets', array( $this, 'enqueue_branding_filter' ) );
	}

	/**
	 * Replace the "BW Dev" display name in the wp-admin plugins list with
	 * the resolved brand name. Falls back silently if our row isn't found.
	 */
	public function filter_plugin_name( $plugins ): array {
		$basename = plugin_basename( BW_DEV_FILE );
		if ( ! is_array( $plugins ) || ! isset( $plugins[ $basename ] ) ) {
			return is_array( $plugins ) ? $plugins : array();
		}
		$brand                         = $this->resolve();
		$plugins[ $basename ]['Name'] = $brand['plugin_display_name'];
		return $plugins;
	}

	/**
	 * Register a `bw-dev-blocks` block category at the top of the inserter,
	 * labeled with the resolved brand. Slug is stable so saved post content
	 * doesn't need rewriting when the brand label changes.
	 */
	public function register_block_category( $categories ): array {
		$brand = $this->resolve();
		array_unshift(
			$categories,
			array(
				'slug'  => self::CATEGORY_SLUG,
				'title' => $brand['block_category_label'],
				'icon'  => null,
			)
		);
		return $categories;
	}

	/**
	 * Inject the resolved brand into the block editor as window.bwDevBrand,
	 * then enqueue the JS filter that rewrites block titles + categories
	 * for all bw-dev/* blocks at registerBlockType time.
	 */
	public function enqueue_branding_filter(): void {
		wp_enqueue_script(
			'bw-dev-branding',
			BW_DEV_URL . 'assets/js/branding.js',
			array( 'wp-hooks', 'wp-blocks' ),
			BW_DEV_VERSION,
			false
		);
		$brand = $this->resolve();
		wp_add_inline_script(
			'bw-dev-branding',
			'window.bwDevBrand = ' . wp_json_encode( array(
				'block_title_prefix'   => $brand['block_title_prefix'],
				'block_category_slug'  => self::CATEGORY_SLUG,
				'block_category_label' => $brand['block_category_label'],
				'default_title_prefix' => $this->defaults['block_title_prefix'],
			) ) . ';',
			'before'
		);
	}
}
