<?php
/**
 * Hero widget render layer.
 *
 * Shortcode: [rsmspark_hero]
 * Attributes: headline, subheadline, background_image, cta_text, cta_url, layout (centered|split)
 *
 * @package Rsmspark_Content_Widgets
 */

defined( 'ABSPATH' ) || exit;

/**
 * Rsmspark_Content_Widgets_Widget_Hero
 *
 * Refactored in compat branch - Phase 1
 */
class Rsmspark_Content_Widgets_Widget_Hero {

	const REGISTRY_ID = 'hero';

	/**
	 * @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(
			'hero',
			array(
				'api_version'     => 3,
				'title'           => __( 'RSM Hero', 'rsm-content-widgets' ),
				'description'     => __( 'Hero section with headline, background image, and CTA.', 'rsm-content-widgets' ),
				'category'        => Rsmspark_Content_Widgets_Blocks::BLOCK_CATEGORY,
				'icon'            => 'cover-image',
				'keywords'        => array( 'hero', 'banner', 'cta', '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-focal-point.php';
		require_once RSMSPARK_CONTENT_WIDGETS_PATH . 'includes/class-rsmspark-content-widgets-hero-layers.php';
		require_once RSMSPARK_CONTENT_WIDGETS_PATH . 'includes/class-rsmspark-content-widgets-hero-presets.php';
	}

	/**
	 * @return array<string, array<string, mixed>>
	 */
	public static function block_attributes() {
		return array(
			'headline'             => array(
				'type'    => 'string',
				'default' => __( 'Welcome to your site', 'rsm-content-widgets' ),
			),
			'subheadline'          => array(
				'type'    => 'string',
				'default' => __( 'Add a short supporting message and a call to action.', 'rsm-content-widgets' ),
			),
			'background_image'     => array( 'type' => 'string', 'default' => '' ),
			'background_image_src' => array( 'type' => 'string', 'default' => '' ),
			'overlay_opacity'      => array( 'type' => 'number', 'default' => 45 ),
			'min_height'           => array( 'type' => 'number', 'default' => 320 ),
			'cta_text'             => array( 'type' => 'string', 'default' => '' ),
			'cta_url'              => array( 'type' => 'string', 'default' => '' ),
			'layout'               => array( 'type' => 'string', 'default' => 'centered' ),
			'split_ratio'          => array( 'type' => 'string', 'default' => '50-50' ),
			'image_side'           => array( 'type' => 'string', 'default' => 'right' ),
			'vertical_align'       => array( 'type' => 'string', 'default' => 'center' ),
			'mobile_order'         => array( 'type' => 'string', 'default' => 'content-first' ),
			'focal_preset'         => array( 'type' => 'string', 'default' => 'center' ),
			'focal_x'              => array( 'type' => 'number', 'default' => 50 ),
			'focal_y'              => array( 'type' => 'number', 'default' => 50 ),
			'background_layers'    => array(
				'type'    => 'array',
				'default' => array(),
			),
			'preset'               => array(
				'type'    => 'string',
				'default' => '',
			),
		);
	}

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

	/**
	 * @param array<string, mixed> $attributes Block attributes.
	 * @return string
	 */
	public static function render_block( $attributes, $content = '', $block = null ) {
		unset( $content );
		$attributes = self::merge_block_attributes( $attributes, $block );
		return self::render( self::normalize_atts( $attributes ) );
	}

	/**
	 * Merge attributes from WP_Block (parsed block JSON is authoritative).
	 *
	 * @param mixed           $attributes Render callback attributes.
	 * @param WP_Block|null   $block      Block instance.
	 * @return array<string, mixed>
	 */
	public static function merge_block_attributes( $attributes, $block = null ) {
		$merged = is_array( $attributes ) ? $attributes : array();

		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 );
			}
		}

		return $merged;
	}

	/**
	 * @param array<string, mixed> $atts Raw attributes.
	 * @return array<string, mixed>
	 */
	public static function normalize_atts( array $atts ) {
		self::ensure_dependencies();

		$defaults = array(
			'headline'             => __( 'Welcome to your site', 'rsm-content-widgets' ),
			'subheadline'          => __( 'Add a short supporting message and a call to action.', 'rsm-content-widgets' ),
			'background_image'     => '',
			'background_image_src' => '',
			'background_video_url' => '',
			'overlay_opacity'      => 45,
			'min_height'           => 320,
			'parallax'             => false,
			'cta_text'             => '',
			'cta_url'              => '',
			'layout'               => 'centered',
			'split_ratio'          => '50-50',
			'image_side'           => 'right',
			'vertical_align'       => 'center',
			'mobile_order'         => 'content-first',
			'focal_preset'         => 'center',
			'focal_x'              => 50,
			'focal_y'              => 50,
			'background_layers'    => array(),
		);

		$parsed = Rsmspark_Content_Widgets_Render::parse_atts( $atts, $defaults, 'rsmspark_hero' );

		$preset_slug = sanitize_key( (string) ( $parsed['preset'] ?? '' ) );
		if ( '' !== $preset_slug ) {
			$preset_config = Rsmspark_Content_Widgets_Hero_Presets::get_config( $preset_slug );
			if ( is_array( $preset_config ) ) {
				unset( $parsed['preset'] );
				$parsed = array_merge( $preset_config, $parsed );
			}
		}

		$layout = sanitize_key( (string) $parsed['layout'] );
		if ( ! in_array( $layout, array( 'centered', 'split' ), true ) ) {
			$layout = 'centered';
		}

		$image_url = self::background_image_url(
			$parsed['background_image'] ?? '',
			(string) ( $parsed['background_image_src'] ?? '' )
		);

		$overlay = (int) ( $parsed['overlay_opacity'] ?? 45 );
		$overlay = max( 0, min( 100, $overlay ) );

		$min_height = (int) ( $parsed['min_height'] ?? 320 );
		$min_height = max( 200, min( 900, $min_height ) );

		$focal_preset = Rsmspark_Content_Widgets_Focal_Point::sanitize_preset( $parsed['focal_preset'] ?? 'center' );
		$focal_x      = Rsmspark_Content_Widgets_Focal_Point::sanitize_coord( $parsed['focal_x'] ?? 50 );
		$focal_y      = Rsmspark_Content_Widgets_Focal_Point::sanitize_coord( $parsed['focal_y'] ?? 50 );
		$focal_position = Rsmspark_Content_Widgets_Focal_Point::resolve_position( $focal_preset, $focal_x, $focal_y );

		$can_media = false;
		$video_url = '';
		$parallax  = false;

		$layers = Rsmspark_Content_Widgets_Hero_Layers::coerce_layers( $parsed['background_layers'] ?? array() );
		if ( empty( $layers ) ) {
			$layers = Rsmspark_Content_Widgets_Hero_Layers::legacy_layers( $image_url, $video_url, $focal_position, $can_media );
		}
		$layers = Rsmspark_Content_Widgets_Hero_Layers::prepare_for_render( $layers, $can_media );

		if ( $parallax && ! empty( $layers ) && ! Rsmspark_Content_Widgets_Hero_Layers::has_parallax_layer( $layers ) ) {
			$layers[0]['parallax'] = true;
		}

		$has_video = false;
		foreach ( $layers as $layer ) {
			if ( 'video' === ( $layer['type'] ?? '' ) ) {
				$has_video = true;
				break;
			}
		}

		$layer_parallax = Rsmspark_Content_Widgets_Hero_Layers::has_parallax_layer( $layers );

		$split_ratio = sanitize_key( (string) ( $parsed['split_ratio'] ?? '50-50' ) );
		if ( ! in_array( $split_ratio, array( '50-50', '40-60', '60-40' ), true ) ) {
			$split_ratio = '50-50';
		}

		$image_side = sanitize_key( (string) ( $parsed['image_side'] ?? 'right' ) );
		if ( ! in_array( $image_side, array( 'left', 'right' ), true ) ) {
			$image_side = 'right';
		}

		$vertical_align = sanitize_key( (string) ( $parsed['vertical_align'] ?? 'center' ) );
		if ( ! in_array( $vertical_align, array( 'top', 'center', 'bottom' ), true ) ) {
			$vertical_align = 'center';
		}

		$mobile_order = sanitize_key( (string) ( $parsed['mobile_order'] ?? 'content-first' ) );
		if ( ! in_array( $mobile_order, array( 'content-first', 'image-first' ), true ) ) {
			$mobile_order = 'content-first';
		}

		$split_columns = '1fr 1fr';
		if ( '40-60' === $split_ratio ) {
			$split_columns = '2fr 3fr';
		} elseif ( '60-40' === $split_ratio ) {
			$split_columns = '3fr 2fr';
		}

		return array(
			'headline'             => sanitize_text_field( (string) $parsed['headline'] ),
			'subheadline'          => sanitize_textarea_field( (string) $parsed['subheadline'] ),
			'image_url'            => $image_url,
			'background_video_url' => $video_url,
			'overlay_opacity'      => $overlay,
			'min_height'           => $min_height,
			'parallax'             => $parallax,
			'layer_parallax'       => $layer_parallax,
			'background_layers'    => $layers,
			'has_video'            => $has_video,
			'cta_text'             => sanitize_text_field( (string) $parsed['cta_text'] ),
			'cta_url'              => esc_url_raw( (string) $parsed['cta_url'] ),
			'layout'               => $layout,
			'split_ratio'          => $split_ratio,
			'image_side'           => $image_side,
			'vertical_align'       => $vertical_align,
			'mobile_order'         => $mobile_order,
			'focal_preset'         => $focal_preset,
			'focal_x'              => $focal_x,
			'focal_y'              => $focal_y,
			'focal_position'       => $focal_position,
			'split_columns'        => $split_columns,
		);
	}

	/**
	 * Resolve hero background from attachment id, SiteOrigin media value, or URL.
	 *
	 * @param mixed  $image   Raw background_image attribute (attachment id).
	 * @param string $src_url Optional direct image URL from the block editor.
	 * @return string
	 */
	public static function background_image_url( $image, $src_url = '' ) {
		$direct = esc_url_raw( trim( (string) $src_url ) );
		if ( '' !== $direct ) {
			return $direct;
		}

		if ( is_array( $image ) ) {
			return Rsmspark_Content_Widgets_Render::media_url( $image, 'full' );
		}

		if ( is_numeric( $image ) && (int) $image > 0 ) {
			return Rsmspark_Content_Widgets_Render::media_url( (int) $image, 'full' );
		}

		$raw = trim( (string) $image );
		if ( '' === $raw ) {
			return '';
		}

		if ( is_numeric( $raw ) ) {
			return Rsmspark_Content_Widgets_Render::media_url( (int) $raw, 'full' );
		}

		return esc_url_raw( $raw );
	}

	/**
	 * Prepare template variables from a SiteOrigin content section.
	 *
	 * @param array<string, mixed> $content Section instance data.
	 * @return array<string, mixed>
	 */
	public static function prepare_from_instance( array $content ) {
		return self::normalize_atts( $content );
	}

	/**
	 * @param array<string, mixed> $args Normalized render arguments.
	 * @return string
	 */
	public static function render( array $args ) {
		$args['style_vars'] = Rsmspark_Content_Widgets_Render::inline_style_vars();

		return Rsmspark_Content_Widgets_Render::render_template(
			self::REGISTRY_ID,
			'hero.php',
			$args
		);
	}
}

/**
 * Render the hero widget (template helper).
 *
 * @param array<string, mixed> $args Widget arguments.
 * @return string
 */
function rsmspark_cw_render_hero( array $args ) {
	return Rsmspark_Content_Widgets_Widget_Hero::render( Rsmspark_Content_Widgets_Widget_Hero::normalize_atts( $args ) );
}
