<?php
/**
 * Class VK Blocks ScrollHintRenderer
 *
 * @package vk_blocks
 */

/**
 * VK Blocks ScrollHintRenderer
 */
class VK_Blocks_ScrollHintRenderer {

	/**
	 * Initialize the ScrollHintRenderer.
	 */
	public static function init() {
		add_filter( 'render_block', array( __CLASS__, 'render_with_scroll_hint' ), 9, 2 );
	}

	/**
	 * Add scroll hint to blocks with the appropriate class name.
	 *
	 * @param string $block_content The content of the block.
	 * @param array  $block The block data.
	 * @return string Modified block content with scroll hint.
	 */
	public static function render_with_scroll_hint( $block_content, $block ) {

		// $block_content においてクラス名に 'is-style-vk-*-scrollable' が含まれ、なおかつ data-output-scroll-hint="true" が存在するか確認
		if (
			! preg_match( '/is-style-vk-[a-zA-Z0-9_-]+-scrollable/', $block_content ) ||
			strpos( $block_content, 'data-output-scroll-hint="true"' ) === false
		) {
			return $block_content;
		}

		// WordPressバージョンが6.2以上の場合に WP_HTML_Tag_Processor クラスをロード
		if ( ! class_exists( 'WP_HTML_Tag_Processor' ) ) {
			return $block_content;
		}

		$processor = new WP_HTML_Tag_Processor( $block_content );

		// 'is-style-vk-*-scrollable' クラスを持つ最初のタグにスクロールヒントを適用
		if ( $processor->next_tag() && preg_match( '/is-style-vk-[a-zA-Z0-9_-]+-scrollable/', $processor->get_attribute( 'class' ) ) ) {
			// vk_hidden や vk_hidden-XXX のすべてのクラスを抽出
			$hidden_classes = array();
			if ( preg_match_all( '/vk_hidden(-[a-zA-Z0-9_-]+)?/', $processor->get_attribute( 'class' ), $matches ) ) {
				$hidden_classes = $matches[0]; // すべての vk_hidden や vk_hidden-XXX クラスを取得
			}

			$scroll_hint = self::generate_scroll_hint( $block, $hidden_classes );

			// 空のスクロールヒントの場合は何もしない
			if ( empty( $scroll_hint ) ) {
				return $block_content;
			}

			// マッチした最初のタグの前にスクロールヒントを挿入（limit=1で最初のマッチのみ）
			$block_content = preg_replace( '/(<[^>]*class="[^"]*is-style-vk-[a-zA-Z0-9_-]+-scrollable[^"]*"[^>]*>)/i', $scroll_hint . '$1', $block_content, 1 );
		}

		return $block_content;
	}

	/**
	 * Generate the scroll hint HTML.
	 *
	 * @param array $block The block data.
	 * @param array $hidden_classes Optional hidden classes to add to the scroll hint.
	 * @return string The scroll hint HTML.
	 */
	public static function generate_scroll_hint( $block, $hidden_classes = array() ) {

		// ブロックタイプに応じてデフォルトのブレークポイントを設定
		$default_breakpoint = 'table-scrollable-mobile';
		if ( isset( $block['blockName'] ) ) {
			if ( 'core/group' === $block['blockName'] ) {
				$default_breakpoint = 'group-scrollable-mobile';
			} elseif ( 'core/table' === $block['blockName'] ) {
				$default_breakpoint = 'table-scrollable-mobile';
			}
		}

		// デフォルトの設定を一括で処理
		$default_attrs = array(
			'scrollMessageText' => __( 'You can scroll', 'vk-blocks' ),
			'iconOutputLeft'    => true,
			'iconOutputRight'   => true,
			'scrollIconLeft'    => 'fa-solid fa-caret-left',
			'scrollIconRight'   => 'fa-solid fa-caret-right',
			'scrollBreakpoint'  => apply_filters( 'vk_blocks_default_scroll_breakpoint', $default_breakpoint, $block ),
			'showScrollMessage' => false,
		);

		// ブロックの属性をデフォルト設定で上書き
		$block_attrs = isset( $block['attrs'] ) ? $block['attrs'] : array();
		$attrs       = wp_parse_args( $block_attrs, $default_attrs );

		// アイコンHTMLを生成
		$left_icon_html  = $attrs['iconOutputLeft'] ? '<i class="' . esc_attr( $attrs['scrollIconLeft'] ) . '"></i>' : '';
		$right_icon_html = $attrs['iconOutputRight'] ? '<i class="' . esc_attr( $attrs['scrollIconRight'] ) . '"></i>' : '';

		// スクロールブレイクポイントをスペースで連結
		$scroll_breakpoint_attr = implode( ' ', (array) $attrs['scrollBreakpoint'] );

		// データ属性を組み立て
		$attributes  = sprintf( 'data-scroll-breakpoint="%s"', esc_attr( $scroll_breakpoint_attr ) );
		$attributes .= sprintf( ' data-output-scroll-message="%s"', $attrs['showScrollMessage'] ? 'true' : 'false' );
		$attributes .= sprintf( ' data-icon-output-left="%s"', $attrs['iconOutputLeft'] ? 'true' : 'false' );
		$attributes .= sprintf( ' data-icon-output-right="%s"', $attrs['iconOutputRight'] ? 'true' : 'false' );

		// アイコンがある場合、data-hint-icon 属性を追加
		if ( $attrs['iconOutputLeft'] && ! empty( $attrs['scrollIconLeft'] ) ) {
			$attributes .= sprintf( ' data-hint-icon-left="%s"', esc_attr( $attrs['scrollIconLeft'] ) );
		}
		if ( $attrs['iconOutputRight'] && ! empty( $attrs['scrollIconRight'] ) ) {
			$attributes .= sprintf( ' data-hint-icon-right="%s"', esc_attr( $attrs['scrollIconRight'] ) );
		}

		// vk_hidden クラスがあればクラスに追加
		$extra_classes = 'vk-scroll-hint';
		if ( ! empty( $hidden_classes ) ) {
			$extra_classes .= ' ' . implode( ' ', array_map( 'esc_attr', $hidden_classes ) );
		}

		// スクロールヒントのHTMLを生成して返す
		return sprintf(
			'<div class="%s" %s>
				%s
				<span>%s</span>
				%s
			</div>',
			esc_attr( $extra_classes ),
			$attributes,
			$left_icon_html,
			esc_html( $attrs['scrollMessageText'] ),
			$right_icon_html
		);
	}
}
