<?php
/**
 * The BW Guides design kit: reusable block patterns for authoring guides.
 *
 * Every pattern is CORE BLOCKS ONLY, because client sites do not have Kadence
 * Blocks (nor this site's theme palette). Appearance is carried by plain
 * className attributes — bw-callout, bw-steps and friends — which the client
 * plugin's stylesheet renders. Nothing here relies on theme.json presets:
 * WordPress does not load global styles in wp-admin, where guides are read, so
 * preset colour classes would render colourless on the client.
 *
 * Patterns are registered only for the bw_guide post type.
 *
 * @package BW_Guides_Server
 */

defined( 'ABSPATH' ) || exit;

class BW_Guides_Server_Patterns {

	const CATEGORY = 'bw-guides';

	public function register() {
		add_action( 'init', array( $this, 'register_patterns' ) );
		add_action( 'enqueue_block_assets', array( $this, 'enqueue_editor_styles' ) );
		add_filter( 'allowed_block_types_all', array( $this, 'restrict_block_types' ), 10, 2 );
	}

	/**
	 * Blocks a guide may be built from.
	 *
	 * This is an allowlist rather than "core blocks only", because three core
	 * blocks are also broken in the client's render path. Clients render with
	 * do_blocks() alone — never the full the_content chain — so:
	 *
	 *   core/embed     the oEmbed filters never run; the block renders as a
	 *                  bare URL rather than an embedded player.
	 *   core/shortcode shortcodes are never expanded; the literal [shortcode]
	 *                  text is printed to the reader.
	 *   core/html      wp_kses_post strips iframes and scripts, so the author
	 *                  sees something quite different from what ships.
	 *
	 * Third-party blocks (Kadence et al) are excluded for a different reason:
	 * their plugin isn't installed on client sites, so static blocks render as
	 * unstyled markup (their CSS is generated per-uniqueID by the plugin, and
	 * their colours come from the Kadence *theme* palette) while dynamic blocks
	 * render as nothing at all.
	 *
	 * @param bool|string[]           $allowed Current allowed types.
	 * @param WP_Block_Editor_Context $context Editor context.
	 * @return bool|string[]
	 */
	public function restrict_block_types( $allowed, $context ) {
		if ( empty( $context->post ) || BW_Guides_Server_CPT::POST_TYPE !== $context->post->post_type ) {
			return $allowed;
		}

		return array(
			// Text.
			'core/paragraph',
			'core/heading',
			'core/list',
			'core/list-item',
			'core/quote',
			'core/pullquote',
			'core/code',
			'core/preformatted',
			'core/details',
			'core/table',
			// Media. Note these still hotlink from the hub until image
			// sideloading lands — see the roadmap in HANDOFF-NOTES.
			'core/image',
			'core/gallery',
			'core/cover',
			'core/media-text',
			'core/video',
			'core/audio',
			'core/file',
			// Layout.
			'core/group',
			'core/columns',
			'core/column',
			'core/buttons',
			'core/button',
			'core/separator',
			'core/spacer',
		);
	}

	/**
	 * Mirror of the client's component CSS so the hub editor previews what
	 * client sites will actually render. Loaded in the editor only.
	 */
	public function enqueue_editor_styles() {
		if ( ! is_admin() ) {
			return;
		}
		$screen = function_exists( 'get_current_screen' ) ? get_current_screen() : null;
		if ( ! $screen || BW_Guides_Server_CPT::POST_TYPE !== $screen->post_type ) {
			return;
		}
		wp_enqueue_style(
			'bw-guides-server-editor',
			BW_GUIDES_SERVER_URL . 'assets/css/editor.css',
			array(),
			BW_GUIDES_SERVER_VERSION
		);
	}

	public function register_patterns() {
		if ( ! function_exists( 'register_block_pattern' ) ) {
			return;
		}

		if ( function_exists( 'register_block_pattern_category' ) ) {
			register_block_pattern_category(
				self::CATEGORY,
				array( 'label' => __( 'BW Guides', 'bw-guides-server' ) )
			);
		}

		foreach ( $this->patterns() as $slug => $pattern ) {
			register_block_pattern(
				'bw-guides/' . $slug,
				array(
					'title'       => $pattern['title'],
					'description' => $pattern['description'],
					'categories'  => array( self::CATEGORY ),
					'postTypes'   => array( BW_Guides_Server_CPT::POST_TYPE ),
					'content'     => $pattern['content'],
				)
			);
		}
	}

	/**
	 * @return array<string, array{title:string, description:string, content:string}>
	 */
	private function patterns() {
		$patterns = array();

		$patterns['note'] = array(
			'title'       => __( 'Note callout', 'bw-guides-server' ),
			'description' => __( 'A blue box for a helpful aside.', 'bw-guides-server' ),
			'content'     => <<<'HTML'
<!-- wp:group {"className":"bw-callout"} -->
<div class="wp-block-group bw-callout"><!-- wp:paragraph {"className":"bw-callout-label"} -->
<p class="bw-callout-label">Note</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>Replace this with the point worth drawing attention to.</p>
<!-- /wp:paragraph --></div>
<!-- /wp:group -->
HTML,
		);

		$patterns['important'] = array(
			'title'       => __( 'Important callout', 'bw-guides-server' ),
			'description' => __( 'An amber box for a warning or a caveat.', 'bw-guides-server' ),
			'content'     => <<<'HTML'
<!-- wp:group {"className":"bw-callout bw-callout-warning"} -->
<div class="wp-block-group bw-callout bw-callout-warning"><!-- wp:paragraph {"className":"bw-callout-label"} -->
<p class="bw-callout-label">Important</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>Replace this with the thing that will cause trouble if it is missed.</p>
<!-- /wp:paragraph --></div>
<!-- /wp:group -->
HTML,
		);

		$patterns['steps'] = array(
			'title'       => __( 'Numbered steps', 'bw-guides-server' ),
			'description' => __( 'A procedure with large numbered markers.', 'bw-guides-server' ),
			'content'     => <<<'HTML'
<!-- wp:heading -->
<h2 class="wp-block-heading">How to do it</h2>
<!-- /wp:heading -->

<!-- wp:list {"ordered":true,"className":"bw-steps"} -->
<ol class="wp-block-list bw-steps"><!-- wp:list-item -->
<li>Describe the first action, starting with the verb.</li>
<!-- /wp:list-item -->

<!-- wp:list-item -->
<li>Describe the second action, and what the person should see happen.</li>
<!-- /wp:list-item -->

<!-- wp:list-item -->
<li>Describe the last action, and how they know it worked.</li>
<!-- /wp:list-item --></ol>
<!-- /wp:list -->
HTML,
		);

		$patterns['do-dont'] = array(
			'title'       => __( 'Do / Don\'t columns', 'bw-guides-server' ),
			'description' => __( 'Two side-by-side boxes contrasting good and bad practice.', 'bw-guides-server' ),
			'content'     => <<<'HTML'
<!-- wp:columns -->
<div class="wp-block-columns"><!-- wp:column -->
<div class="wp-block-column"><!-- wp:group {"className":"bw-callout bw-callout-success"} -->
<div class="wp-block-group bw-callout bw-callout-success"><!-- wp:paragraph {"className":"bw-callout-label"} -->
<p class="bw-callout-label">Do</p>
<!-- /wp:paragraph -->

<!-- wp:list -->
<ul class="wp-block-list"><!-- wp:list-item -->
<li>The habit worth having.</li>
<!-- /wp:list-item -->

<!-- wp:list-item -->
<li>Another one.</li>
<!-- /wp:list-item --></ul>
<!-- /wp:list --></div>
<!-- /wp:group --></div>
<!-- /wp:column -->

<!-- wp:column -->
<div class="wp-block-column"><!-- wp:group {"className":"bw-callout bw-callout-danger"} -->
<div class="wp-block-group bw-callout bw-callout-danger"><!-- wp:paragraph {"className":"bw-callout-label"} -->
<p class="bw-callout-label">Don't</p>
<!-- /wp:paragraph -->

<!-- wp:list -->
<ul class="wp-block-list"><!-- wp:list-item -->
<li>The thing that causes support tickets.</li>
<!-- /wp:list-item -->

<!-- wp:list-item -->
<li>Another one.</li>
<!-- /wp:list-item --></ul>
<!-- /wp:list --></div>
<!-- /wp:group --></div>
<!-- /wp:column --></div>
<!-- /wp:columns -->
HTML,
		);

		$patterns['faq'] = array(
			'title'       => __( 'FAQ accordion', 'bw-guides-server' ),
			'description' => __( 'Collapsible questions and answers.', 'bw-guides-server' ),
			'content'     => <<<'HTML'
<!-- wp:heading -->
<h2 class="wp-block-heading">Common questions</h2>
<!-- /wp:heading -->

<!-- wp:details -->
<details class="wp-block-details"><summary>The first question, in the words a client would use</summary><!-- wp:paragraph -->
<p>The answer, kept short.</p>
<!-- /wp:paragraph --></details>
<!-- /wp:details -->

<!-- wp:details -->
<details class="wp-block-details"><summary>The second question</summary><!-- wp:paragraph -->
<p>The answer, kept short.</p>
<!-- /wp:paragraph --></details>
<!-- /wp:details -->
HTML,
		);

		$patterns['reference-table'] = array(
			'title'       => __( 'Reference table', 'bw-guides-server' ),
			'description' => __( 'A two-column lookup table, e.g. setting and where to find it.', 'bw-guides-server' ),
			'content'     => <<<'HTML'
<!-- wp:table -->
<figure class="wp-block-table"><table><thead><tr><th>What you want to change</th><th>Where to find it</th></tr></thead><tbody><tr><td>Your logo</td><td>Appearance &gt; Customise</td></tr><tr><td>Page content</td><td>Pages &gt; All Pages</td></tr></tbody></table><figcaption class="wp-element-caption">Where the common settings live.</figcaption></figure>
<!-- /wp:table -->
HTML,
		);

		$patterns['button-row'] = array(
			'title'       => __( 'Button row', 'bw-guides-server' ),
			'description' => __( 'One or two buttons linking to a screen.', 'bw-guides-server' ),
			'content'     => <<<'HTML'
<!-- wp:buttons -->
<div class="wp-block-buttons"><!-- wp:button -->
<div class="wp-block-button"><a class="wp-block-button__link wp-element-button" href="#">Take me there</a></div>
<!-- /wp:button --></div>
<!-- /wp:buttons -->
HTML,
		);

		return $patterns;
	}
}
