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

defined( 'ABSPATH' ) || exit;

/**
 * Rsmspark_Content_Widgets_Widget_Image
 *
 * Refactored in compat branch - Phase 2
 */
class Rsmspark_Content_Widgets_Widget_Image {

	const REGISTRY_ID = 'image';

	/**
	 * @var bool
	 */
	private static $so_shell_hooks_registered = false;

	/**
	 * Whether a lightbox instance rendered this request.
	 *
	 * @var bool
	 */
	private static $lightbox_assets_needed = false;

	/**
	 * @return bool
	 */
	public static function needs_lightbox_assets() {
		return self::$lightbox_assets_needed;
	}

	/**
	 * @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(
			'image',
			array(
				'api_version'     => 3,
				'title'           => __( 'RSM Image', 'rsm-content-widgets' ),
				'description'     => __( 'Media image with size, alignment, corners, and optional border.', 'rsm-content-widgets' ),
				'category'        => Rsmspark_Content_Widgets_Blocks::BLOCK_CATEGORY,
				'icon'            => 'format-image',
				'keywords'        => array( 'image', 'photo', 'media', '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-image-styles.php';
		require_once RSMSPARK_CONTENT_WIDGETS_PATH . 'includes/class-rsmspark-content-widgets-focal-point.php';
	}

	/**
	 * @return array<string, array<string, mixed>>
	 */
	public static function block_attributes() {
		return array(
			'image'            => array( 'type' => 'number', 'default' => 0 ),
			'image_src'        => array( 'type' => 'string', 'default' => '' ),
			'alt_text'         => array( 'type' => 'string', 'default' => '' ),
			'link'             => array( 'type' => 'string', 'default' => '' ),
			'image_width'      => array( 'type' => 'number', 'default' => 100 ),
			'max_width'        => array( 'type' => 'number', 'default' => 0 ),
			'min_frame_height' => array( 'type' => 'number', 'default' => 0 ),
			'align_horizontal' => array( 'type' => 'string', 'default' => 'center' ),
			'align_vertical'   => array( 'type' => 'string', 'default' => 'center' ),
			'corners'          => array( 'type' => 'string', 'default' => 'rounded' ),
			'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 ),
			'focal_preset'     => array( 'type' => 'string', 'default' => 'center' ),
			'focal_x'          => array( 'type' => 'number', 'default' => 50 ),
			'focal_y'          => array( 'type' => 'number', 'default' => 50 ),
			'aspect_ratio'     => array( 'type' => 'string', 'default' => 'auto' ),
			'lightbox_enable'  => array( 'type' => 'boolean', 'default' => false ),
			'lightbox_caption' => array( 'type' => 'string', 'default' => '' ),
		);
	}

	/**
	 * @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.
	 * @return string
	 */
	public static function render_block( $attributes ) {
		return self::render( self::prepare_template_vars( self::instance_from_atts( is_array( $attributes ) ? $attributes : array() ) ) );
	}

	/**
	 * @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['layout'] ) || isset( $atts['design'] ) ) {
			return $atts;
		}

		return array(
			'content' => array(
				'image'     => $atts['image'] ?? 0,
				'image_src' => (string) ( $atts['image_src'] ?? '' ),
				'alt_text'  => (string) ( $atts['alt_text'] ?? '' ),
				'link'      => (string) ( $atts['link'] ?? '' ),
				'lightbox_enable'  => Rsmspark_Content_Widgets_Render::boolish( $atts['lightbox_enable'] ?? false ),
				'lightbox_caption' => (string) ( $atts['lightbox_caption'] ?? '' ),
			),
			'layout'  => array(
				'image_width'      => absint( $atts['image_width'] ?? 100 ),
				'max_width'        => absint( $atts['max_width'] ?? 0 ),
				'min_frame_height' => absint( $atts['min_frame_height'] ?? 0 ),
				'align_horizontal' => sanitize_key( (string) ( $atts['align_horizontal'] ?? 'center' ) ),
				'align_vertical'   => sanitize_key( (string) ( $atts['align_vertical'] ?? 'center' ) ),
				'focal_preset'     => sanitize_key( (string) ( $atts['focal_preset'] ?? 'center' ) ),
				'focal_x'          => absint( $atts['focal_x'] ?? 50 ),
				'focal_y'          => absint( $atts['focal_y'] ?? 50 ),
				'aspect_ratio'     => sanitize_key( (string) ( $atts['aspect_ratio'] ?? 'auto' ) ),
			),
			'design'  => array(
				'corners'        => sanitize_key( (string) ( $atts['corners'] ?? 'rounded' ) ),
				'corner_radius'  => absint( $atts['corner_radius'] ?? 12 ),
				'border_enable'  => ! empty( $atts['border_enable'] ),
				'border_width'   => absint( $atts['border_width'] ?? 1 ),
				'border_color'   => (string) ( $atts['border_color'] ?? '#e2e8f0' ),
				'border_opacity' => absint( $atts['border_opacity'] ?? 100 ),
			),
		);
	}

	/**
	 * @param array<string, mixed> $instance SiteOrigin widget instance.
	 * @return array<string, mixed>
	 */
	public static function prepare_from_instance( array $instance ) {
		return array(
			'content' => Rsmspark_Content_Widgets_Render::section_instance( $instance, 'content' ),
			'layout'  => Rsmspark_Content_Widgets_Render::section_instance( $instance, 'layout' ),
			'design'  => Rsmspark_Content_Widgets_Render::section_instance( $instance, 'design' ),
		);
	}

	/**
	 * @param array<string, mixed> $instance Widget instance with content/layout/design.
	 * @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(
				'image'     => '',
				'image_src' => '',
				'alt_text'  => '',
				'link'      => '',
				'lightbox_enable'  => false,
				'lightbox_caption' => '',
			)
		);
		$layout = wp_parse_args(
			isset( $instance['layout'] ) && is_array( $instance['layout'] ) ? $instance['layout'] : array(),
			array(
				'image_width'      => 100,
				'max_width'        => 0,
				'min_frame_height' => 0,
				'align_horizontal' => 'center',
				'align_vertical'   => 'center',
				'focal_preset'     => 'center',
				'focal_x'          => 50,
				'focal_y'          => 50,
				'aspect_ratio'     => 'auto',
			)
		);
		$design = wp_parse_args(
			isset( $instance['design'] ) && is_array( $instance['design'] ) ? $instance['design'] : array(),
			array(
				'corners'        => 'rounded',
				'corner_radius'  => 12,
				'border_enable'  => false,
				'border_width'   => 1,
				'border_color'   => '#e2e8f0',
				'border_opacity' => 100,
			)
		);

		$align_h = sanitize_key( (string) $layout['align_horizontal'] );
		if ( ! array_key_exists( $align_h, Rsmspark_Content_Widgets_Image_Styles::get_horizontal_align_options() ) ) {
			$align_h = 'center';
		}

		$align_v = sanitize_key( (string) $layout['align_vertical'] );
		if ( ! array_key_exists( $align_v, Rsmspark_Content_Widgets_Image_Styles::get_vertical_align_options() ) ) {
			$align_v = 'center';
		}

		$focal_preset = Rsmspark_Content_Widgets_Focal_Point::sanitize_preset( $layout['focal_preset'] ?? 'center' );
		$focal_x      = Rsmspark_Content_Widgets_Focal_Point::sanitize_coord( $layout['focal_x'] ?? 50 );
		$focal_y      = Rsmspark_Content_Widgets_Focal_Point::sanitize_coord( $layout['focal_y'] ?? 50 );
		$aspect_ratio = Rsmspark_Content_Widgets_Focal_Point::sanitize_aspect_ratio( $layout['aspect_ratio'] ?? 'auto' );
		$aspect_css   = Rsmspark_Content_Widgets_Focal_Point::aspect_ratio_css( $aspect_ratio );

		$layout['focal_preset'] = $focal_preset;
		$layout['focal_x']      = $focal_x;
		$layout['focal_y']      = $focal_y;
		$layout['aspect_ratio'] = $aspect_ratio;
		$layout['object_position'] = Rsmspark_Content_Widgets_Focal_Point::resolve_position( $focal_preset, $focal_x, $focal_y );

		$image_url = self::content_image_url( $content );
		$link_url  = Rsmspark_Content_Widgets_Render::link_url( $content['link'] ?? '' );
		$lightbox_url = self::lightbox_image_url( $content );
		$lightbox_on  = Rsmspark_Content_Widgets_Render::boolish( $content['lightbox_enable'] ?? false )
			&& '' !== $lightbox_url
			&& '' === $link_url;

		$alt = trim( (string) $content['alt_text'] );
		if ( '' === $alt && ! empty( $content['image'] ) ) {
			$attachment_id = is_numeric( $content['image'] ) ? (int) $content['image'] : 0;
			if ( ! $attachment_id && is_array( $content['image'] ) && ! empty( $content['image']['attachment_id'] ) ) {
				$attachment_id = (int) $content['image']['attachment_id'];
			}
			if ( $attachment_id > 0 ) {
				$alt = (string) get_post_meta( $attachment_id, '_wp_attachment_image_alt', true );
			}
		}

		$css_vars     = Rsmspark_Content_Widgets_Image_Styles::build_css_variables( $content, $layout, $design );
		$inline_style = Rsmspark_Content_Widgets_Image_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(
			'image_url'        => $image_url,
			'alt_text'         => $alt,
			'link_url'         => $link_url,
			'align_h'          => $align_h,
			'align_v'          => $align_v,
			'has_image'        => '' !== $image_url,
			'inline_style'     => $inline_style,
			'border_enabled'   => Rsmspark_Content_Widgets_Image_Styles::is_enabled( $design['border_enable'] ?? false ),
			'has_aspect'       => '' !== $aspect_css,
			'lightbox_enabled' => $lightbox_on,
			'lightbox_url'     => $lightbox_url,
			'lightbox_caption' => sanitize_text_field( (string) ( $content['lightbox_caption'] ?? '' ) ),
			'widget_uid'       => 'rsmspark-cw-image-' . wp_unique_id(),
		);
	}

	/**
	 * Full-size URL for lightbox (prefers attachment "full", else display URL).
	 *
	 * @param array<string, mixed> $content Content section.
	 * @return string
	 */
	public static function lightbox_image_url( array $content ) {
		$image = $content['image'] ?? '';
		$id    = 0;

		if ( is_numeric( $image ) ) {
			$id = (int) $image;
		} elseif ( is_array( $image ) ) {
			if ( ! empty( $image['ID'] ) ) {
				$id = (int) $image['ID'];
			} elseif ( ! empty( $image['id'] ) ) {
				$id = (int) $image['id'];
			} elseif ( ! empty( $image['attachment_id'] ) ) {
				$id = (int) $image['attachment_id'];
			}
		}

		if ( $id > 0 ) {
			$full = wp_get_attachment_image_url( $id, 'full' );
			if ( $full ) {
				return (string) $full;
			}
			$url = wp_get_attachment_url( $id );
			return $url ? (string) $url : '';
		}

		return self::content_image_url( $content );
	}

	/**
	 * Resolve image URL from block editor src fallback or attachment id.
	 *
	 * @param array<string, mixed> $content Content section.
	 * @return string
	 */
	public static function content_image_url( array $content ) {
		$direct = esc_url_raw( trim( (string) ( $content['image_src'] ?? '' ) ) );
		if ( '' !== $direct ) {
			return $direct;
		}

		$image = $content['image'] ?? '';
		if ( is_array( $image ) ) {
			return Rsmspark_Content_Widgets_Render::media_url( $image );
		}

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

		return '';
	}

	/**
	 * Register SiteOrigin shell border reset hooks (called from SO widget only).
	 *
	 * @return void
	 */
	public static function register_so_shell_hooks() {
		if ( self::$so_shell_hooks_registered ) {
			return;
		}
		self::$so_shell_hooks_registered = true;

		add_filter( 'siteorigin_widgets_wrapper_classes_rsm-image', array( __CLASS__, 'filter_so_wrapper_classes' ), 10, 3 );
		add_filter( 'siteorigin_widgets_wrapper_classes_image', array( __CLASS__, 'filter_so_wrapper_classes' ), 10, 3 );
		add_action( 'siteorigin_widgets_after_widget_rsm-image', array( __CLASS__, 'mark_so_rendered' ), 1, 2 );
		add_action( 'siteorigin_widgets_after_widget_image', array( __CLASS__, 'mark_so_rendered' ), 1, 2 );
		add_action( 'wp_footer', array( __CLASS__, 'print_so_shell_border_reset' ), 9999 );
		add_action( 'admin_print_footer_scripts', array( __CLASS__, 'print_so_shell_border_reset' ), 9999 );
		add_filter( 'siteorigin_panels_widget_classes', array( __CLASS__, 'filter_panels_so_panel_classes' ), 10, 4 );
	}

	/**
	 * @var bool
	 */
	private static $rendered_on_request = false;

	/**
	 * @var bool
	 */
	private static $printed_shell_reset = false;

	/**
	 * @param array              $instance Widget instance.
	 * @param SiteOrigin_Widget $widget    Widget.
	 * @return void
	 */
	public static function mark_so_rendered( $instance, $widget ) {
		unset( $instance, $widget );
		self::$rendered_on_request = true;
	}

	/**
	 * @return void
	 */
	public static function print_so_shell_border_reset() {
		if ( ! self::$rendered_on_request || self::$printed_shell_reset ) {
			return;
		}
		self::$printed_shell_reset = true;

		$css  = 'div.so-widget-rsm-image.rsmspark-cw-image-so-shell,div.so-widget-rsm-image.so-widget-rsm-image-base.rsmspark-cw-image-so-shell,div.so-widget-image.rsmspark-cw-image-so-shell,div.so-widget-image.so-widget-image-base.rsmspark-cw-image-so-shell{border-width:0!important;border-style:none!important;border-color:transparent!important;box-shadow:none!important;outline:none!important;background:transparent!important;padding:0!important;margin:0!important;}';
		$css .= '.so-panel.rsmspark-cw-image-so-panel{border-width:0!important;border-style:none!important;border-color:transparent!important;box-shadow:none!important;outline:none!important;background:transparent!important;}';

		$style_handle = 'rsmspark-cw-image-so-shell-border-reset';
		if ( ! wp_style_is( $style_handle, 'registered' ) ) {
			wp_register_style( $style_handle, false, array(), RSMSPARK_CONTENT_WIDGETS_VERSION );
		}
		wp_enqueue_style( $style_handle );
		wp_add_inline_style( $style_handle, $css );
		wp_print_styles( $style_handle );
	}

	/**
	 * @param string[] $classes      Panel classes.
	 * @param string   $widget_class Widget class key.
	 * @param array    $instance     Instance.
	 * @param array    $widget_info  Metadata.
	 * @return string[]
	 */
	public static function filter_panels_so_panel_classes( $classes, $widget_class, $instance, $widget_info ) {
		unset( $widget_class, $instance, $widget_info );
		if ( is_array( $classes ) && ( in_array( 'widget_rsm-image', $classes, true ) || in_array( 'widget_image', $classes, true ) ) ) {
			$classes[] = 'rsmspark-cw-image-so-panel';
		}
		return $classes;
	}

	/**
	 * @param string[]           $classes  Wrapper classes.
	 * @param array              $instance Instance.
	 * @param SiteOrigin_Widget $widget    Widget.
	 * @return string[]
	 */
	public static function filter_so_wrapper_classes( $classes, $instance, $widget ) {
		unset( $instance, $widget );
		if ( ! is_array( $classes ) ) {
			$classes = array();
		}
		$classes[] = 'rsmspark-cw-image-so-shell';
		return $classes;
	}

	/**
	 * @param array<string, mixed> $vars Template variables.
	 * @return string
	 */
	public static function render( array $vars ) {
		if ( empty( $vars['has_image'] ) ) {
			return '';
		}

		if ( ! empty( $vars['lightbox_enabled'] ) ) {
			self::$lightbox_assets_needed = true;
		}

		return Rsmspark_Content_Widgets_Render::render_template( self::REGISTRY_ID, 'image.php', $vars );
	}
}

function rsmspark_cw_render_image( array $args ) {
	return Rsmspark_Content_Widgets_Widget_Image::render(
		Rsmspark_Content_Widgets_Widget_Image::prepare_template_vars(
			Rsmspark_Content_Widgets_Widget_Image::instance_from_atts( $args )
		)
	);
}
