<?php
/**
 * Headline widget render layer.
 *
 * Shortcode: [rsmspark_headline]
 *
 * @package Rsmspark_Content_Widgets
 */

defined( 'ABSPATH' ) || exit;

/**
 * Rsmspark_Content_Widgets_Widget_Headline
 */
class Rsmspark_Content_Widgets_Widget_Headline {

	const REGISTRY_ID = 'headline';

	/**
	 * @return void
	 */
	public static function register() {
		self::ensure_dependencies();

		Rsmspark_Content_Widgets_Shortcodes::add(
			Rsmspark_Content_Widgets_Registry::shortcode_tag( self::REGISTRY_ID ),
			array( __CLASS__, 'shortcode' ),
			self::REGISTRY_ID
		);

		Rsmspark_Content_Widgets_Blocks::add(
			'headline',
			array(
				'api_version'     => 3,
				'title'           => __( 'RSM Headline', 'rsm-content-widgets' ),
				'description'     => __( 'Overline, headline, and subheadline with typography and container styling.', 'rsm-content-widgets' ),
				'category'        => Rsmspark_Content_Widgets_Blocks::BLOCK_CATEGORY,
				'icon'            => 'heading',
				'keywords'        => array( 'headline', 'title', 'heading', 'eyebrow', 'rsm' ),
				'supports'        => array( 'html' => false ),
				'attributes'      => self::block_attributes(),
				'render_callback' => array( __CLASS__, 'render_block' ),
			)
		);
	}

	/**
	 * @return void
	 */
	public static function ensure_dependencies() {
		require_once RSMSPARK_CONTENT_WIDGETS_PATH . 'includes/class-rsmspark-content-widgets-headline-styles.php';
		require_once RSMSPARK_CONTENT_WIDGETS_PATH . 'includes/class-rsmspark-content-widgets-features-fonts.php';
	}

	/**
	 * @return array<string, array<string, mixed>>
	 */
	public static function block_attributes() {
		$string = array( 'type' => 'string', 'default' => '' );
		$font   = array( 'type' => 'string', 'default' => 'inherit' );
		$size   = array( 'type' => 'number', 'default' => 0 );
		$color  = array( 'type' => 'string', 'default' => '' );
		$align  = array( 'type' => 'string', 'default' => 'center' );

		return array(
			'overline'                 => $string,
			'headline'                 => array( 'type' => 'string', 'default' => __( 'Your headline here', 'rsm-content-widgets' ) ),
			'subheadline'              => $string,
			'headline_tag'             => array( 'type' => 'string', 'default' => 'h2' ),
			'overline_font'            => $font,
			'overline_font_size'       => $size,
			'overline_color'           => $color,
			'overline_align'           => $align,
			'headline_font'            => $font,
			'headline_font_size'       => $size,
			'headline_color'           => $color,
			'headline_align'           => $align,
			'subheadline_font'         => $font,
			'subheadline_font_size'    => $size,
			'subheadline_color'        => $color,
			'subheadline_align'        => $align,
			'width_pct'                => array( 'type' => 'number', 'default' => 100 ),
			'max_width'                => array( 'type' => 'number', 'default' => 0 ),
			'background_color'         => $color,
			'corners'                  => array( 'type' => 'string', 'default' => 'square' ),
			'corner_radius'            => array( 'type' => 'number', 'default' => 12 ),
			'border_enable'            => array( 'type' => 'boolean', 'default' => false ),
			'border_width'             => array( 'type' => 'number', 'default' => 1 ),
			'border_color'             => array( 'type' => 'string', 'default' => '#e2e8f0' ),
			'border_opacity'           => array( 'type' => 'number', 'default' => 100 ),
		);
	}

	/**
	 * @param array<string, mixed> $atts Shortcode attributes.
	 * @param string               $content Inner content.
	 * @return string
	 */
	public static function shortcode( $atts, $content = '' ) {
		unset( $content );
		return self::render( self::prepare_template_vars( self::instance_from_atts( is_array( $atts ) ? $atts : array() ) ) );
	}

	/**
	 * @param array<string, mixed> $attributes Block attributes.
	 * @param string               $content    Inner block content (unused).
	 * @param WP_Block|null        $block      Block instance.
	 * @return string
	 */
	public static function render_block( $attributes, $content = '', $block = null ) {
		unset( $content );
		$attributes = self::merge_block_attributes( is_array( $attributes ) ? $attributes : array(), $block );
		return self::render( self::prepare_template_vars( self::instance_from_atts( $attributes ) ) );
	}

	/**
	 * Merge parsed block JSON and registration defaults into render attributes.
	 *
	 * @param array<string, mixed> $attributes Render callback attributes.
	 * @param WP_Block|null        $block      Block instance.
	 * @return array<string, mixed>
	 */
	public static function merge_block_attributes( array $attributes, $block = null ) {
		$merged = $attributes;

		if ( $block instanceof WP_Block ) {
			if ( ! empty( $block->parsed_block['attrs'] ) && is_array( $block->parsed_block['attrs'] ) ) {
				$merged = array_merge( $merged, $block->parsed_block['attrs'] );
			}
			if ( ! empty( $block->attributes ) && is_array( $block->attributes ) ) {
				$merged = array_merge( $merged, $block->attributes );
			}
		}

		foreach ( self::block_attributes() as $key => $schema ) {
			if ( ! is_array( $schema ) || ! array_key_exists( 'default', $schema ) ) {
				continue;
			}
			if ( ! array_key_exists( $key, $merged ) ) {
				$merged[ $key ] = $schema['default'];
			}
		}

		return $merged;
	}

	/**
	 * @param array<string, mixed> $atts Raw attributes or SO sections.
	 * @return array<string, mixed>
	 */
	public static function instance_from_atts( array $atts ) {
		if ( isset( $atts['content'] ) || isset( $atts['container'] ) ) {
			return $atts;
		}

		$flat = wp_parse_args( $atts, self::flat_defaults() );

		return array(
			'content' => array(
				'overline'     => (string) ( $flat['overline'] ?? '' ),
				'headline'     => (string) ( $flat['headline'] ?? '' ),
				'subheadline'  => (string) ( $flat['subheadline'] ?? '' ),
				'headline_tag' => (string) ( $flat['headline_tag'] ?? 'h2' ),
			),
			'overline_typography'    => self::extract_line_atts( $flat, 'overline' ),
			'headline_typography'    => self::extract_line_atts( $flat, 'headline' ),
			'subheadline_typography' => self::extract_line_atts( $flat, 'subheadline' ),
			'container'              => array(
				'width_pct'        => absint( $flat['width_pct'] ?? 100 ),
				'max_width'        => absint( $flat['max_width'] ?? 0 ),
				'background_color' => (string) ( $flat['background_color'] ?? '' ),
				'corners'          => sanitize_key( (string) ( $flat['corners'] ?? 'square' ) ),
				'corner_radius'    => absint( $flat['corner_radius'] ?? 12 ),
				'border_enable'    => ! empty( $flat['border_enable'] ),
				'border_width'     => absint( $flat['border_width'] ?? 1 ),
				'border_color'     => (string) ( $flat['border_color'] ?? '#e2e8f0' ),
				'border_opacity'   => absint( $flat['border_opacity'] ?? 100 ),
			),
		);
	}

	/**
	 * @return array<string, mixed>
	 */
	private static function flat_defaults() {
		$defaults = array(
			'overline'      => '',
			'headline'      => '',
			'subheadline'   => '',
			'headline_tag'  => 'h2',
			'width_pct'     => 100,
			'max_width'     => 0,
			'background_color' => '',
			'corners'       => 'square',
			'corner_radius' => 12,
			'border_enable' => false,
			'border_width'  => 1,
			'border_color'  => '#e2e8f0',
			'border_opacity' => 100,
		);

		foreach ( array( 'overline', 'headline', 'subheadline' ) as $line ) {
			$defaults[ $line . '_font' ]      = 'inherit';
			$defaults[ $line . '_font_size' ] = 0;
			$defaults[ $line . '_color' ]     = '';
			$defaults[ $line . '_align' ]     = 'center';
		}

		return $defaults;
	}

	/**
	 * @param array<string, mixed> $flat Flat attributes.
	 * @param string               $line Line prefix.
	 * @return array<string, mixed>
	 */
	private static function extract_line_atts( array $flat, $line ) {
		return array(
			$line . '_font'      => $flat[ $line . '_font' ] ?? 'inherit',
			$line . '_font_size' => $flat[ $line . '_font_size' ] ?? 0,
			$line . '_color'     => $flat[ $line . '_color' ] ?? '',
			$line . '_align'     => $flat[ $line . '_align' ] ?? 'center',
		);
	}

	/**
	 * @param array<string, mixed> $instance SiteOrigin widget instance.
	 * @return array<string, mixed>
	 */
	public static function prepare_from_instance( array $instance ) {
		$merged = array_merge(
			Rsmspark_Content_Widgets_Render::section_instance( $instance, 'content' ),
			Rsmspark_Content_Widgets_Render::section_instance( $instance, 'overline_typography' ),
			Rsmspark_Content_Widgets_Render::section_instance( $instance, 'headline_typography' ),
			Rsmspark_Content_Widgets_Render::section_instance( $instance, 'subheadline_typography' ),
			Rsmspark_Content_Widgets_Render::section_instance( $instance, 'container' )
		);

		return self::instance_from_atts( $merged );
	}

	/**
	 * @param array<string, mixed> $instance SiteOrigin widget instance.
	 * @return array<string, mixed>
	 */
	public static function prepare_from_siteorigin_instance( array $instance ) {
		return self::prepare_from_instance( $instance );
	}

	/**
	 * @param array<string, mixed> $instance Widget instance.
	 * @return array<string, mixed>
	 */
	public static function prepare_template_vars( array $instance ) {
		self::ensure_dependencies();

		$content = wp_parse_args(
			isset( $instance['content'] ) && is_array( $instance['content'] ) ? $instance['content'] : array(),
			array(
				'overline'     => '',
				'headline'     => '',
				'subheadline'  => '',
				'headline_tag' => 'h2',
			)
		);

		$container = wp_parse_args(
			isset( $instance['container'] ) && is_array( $instance['container'] ) ? $instance['container'] : array(),
			array(
				'width_pct'        => 100,
				'max_width'        => 0,
				'background_color' => '',
				'corners'          => 'square',
				'corner_radius'    => 12,
				'border_enable'    => false,
				'border_width'     => 1,
				'border_color'     => '#e2e8f0',
				'border_opacity'   => 100,
			)
		);

		$overline_line = Rsmspark_Content_Widgets_Headline_Styles::normalize_line(
			isset( $instance['overline_typography'] ) && is_array( $instance['overline_typography'] ) ? $instance['overline_typography'] : self::extract_line_atts( $instance, 'overline' ),
			'overline'
		);
		$headline_line = Rsmspark_Content_Widgets_Headline_Styles::normalize_line(
			isset( $instance['headline_typography'] ) && is_array( $instance['headline_typography'] ) ? $instance['headline_typography'] : self::extract_line_atts( $instance, 'headline' ),
			'headline'
		);
		$subheadline_line = Rsmspark_Content_Widgets_Headline_Styles::normalize_line(
			isset( $instance['subheadline_typography'] ) && is_array( $instance['subheadline_typography'] ) ? $instance['subheadline_typography'] : self::extract_line_atts( $instance, 'subheadline' ),
			'subheadline'
		);

		$overline    = Rsmspark_Content_Widgets_Headline_Styles::sanitize_line_html( $content['overline'] ?? '' );
		$headline    = Rsmspark_Content_Widgets_Headline_Styles::sanitize_line_html( $content['headline'] ?? '' );
		$subheadline = Rsmspark_Content_Widgets_Headline_Styles::sanitize_line_html( $content['subheadline'] ?? '' );
		$headline_tag = Rsmspark_Content_Widgets_Headline_Styles::sanitize_headline_tag( $content['headline_tag'] );

		$css_vars     = Rsmspark_Content_Widgets_Headline_Styles::build_css_variables( $overline_line, $headline_line, $subheadline_line, $container );
		$inline_style = Rsmspark_Content_Widgets_Headline_Styles::vars_to_inline_style( $css_vars );
		$global_vars  = Rsmspark_Content_Widgets_Render::inline_style_vars();
		if ( '' !== $global_vars ) {
			$inline_style = $global_vars . ';' . $inline_style;
		}

		return array(
			'overline'         => $overline,
			'headline'         => $headline,
			'subheadline'      => $subheadline,
			'headline_tag'     => $headline_tag,
			'has_overline'     => Rsmspark_Content_Widgets_Headline_Styles::line_has_text( $overline ),
			'has_headline'     => Rsmspark_Content_Widgets_Headline_Styles::line_has_text( $headline ),
			'has_subheadline'  => Rsmspark_Content_Widgets_Headline_Styles::line_has_text( $subheadline ),
			'has_content'      => Rsmspark_Content_Widgets_Headline_Styles::line_has_text( $overline )
				|| Rsmspark_Content_Widgets_Headline_Styles::line_has_text( $headline )
				|| Rsmspark_Content_Widgets_Headline_Styles::line_has_text( $subheadline ),
			'inline_style'     => $inline_style,
			'border_enabled'   => Rsmspark_Content_Widgets_Headline_Styles::is_enabled( $container['border_enable'] ?? false ),
		);
	}

	/**
	 * @param array<string, mixed> $vars Template variables.
	 * @return string
	 */
	public static function render( array $vars ) {
		return Rsmspark_Content_Widgets_Render::render_template( self::REGISTRY_ID, 'headline.php', $vars );
	}
}

/**
 * @param array<string, mixed> $args Arguments.
 * @return string
 */
function rsmspark_cw_render_headline( array $args ) {
	return Rsmspark_Content_Widgets_Widget_Headline::render(
		Rsmspark_Content_Widgets_Widget_Headline::prepare_template_vars(
			Rsmspark_Content_Widgets_Widget_Headline::instance_from_atts( $args )
		)
	);
}
