<?php
declare( strict_types = 1 );
namespace Automattic\WooCommerce\EmailEditor\Integrations\WooCommerce\Renderer\Blocks;
if (!defined('ABSPATH')) exit;
use Automattic\WooCommerce\EmailEditor\Engine\Renderer\ContentRenderer\Rendering_Context;
use Automattic\WooCommerce\EmailEditor\Integrations\Utils\Dom_Document_Helper;
use Automattic\WooCommerce\EmailEditor\Integrations\Utils\Styles_Helper;
use Automattic\WooCommerce\EmailEditor\Integrations\Utils\Table_Wrapper_Helper;
class Product_Image extends Abstract_Product_Block_Renderer {
 protected function render_content( string $block_content, array $parsed_block, Rendering_Context $rendering_context ): string {
 $product = $this->get_product_from_context( $parsed_block );
 if ( ! $product ) {
 return '';
 }
 $attributes = $this->parse_attributes( $parsed_block['attrs'] ?? array() );
 $image_data = $this->get_product_image_data( $product, $attributes );
 if ( ! $image_data ) {
 return '';
 }
 $parsed_block = $this->add_image_size_when_missing( $parsed_block, $rendering_context );
 $attributes = $this->parse_attributes( $parsed_block['attrs'] ?? array() );
 $image_html = $this->build_image_html( $image_data, $attributes, $rendering_context );
 $inner_blocks = $this->process_inner_blocks( $parsed_block, $product, $rendering_context );
 $combined_content = $this->create_overlay_structure(
 $image_html,
 $inner_blocks['badges'],
 $inner_blocks['other_content'],
 $inner_blocks['badge_alignment'],
 $product,
 $attributes['showProductLink']
 );
 return $this->apply_email_wrapper( $combined_content, $parsed_block, $rendering_context );
 }
 private function process_inner_blocks( array $parsed_block, \WC_Product $product, Rendering_Context $rendering_context ): array {
 $badges = '';
 $other_content = '';
 $badge_alignment = 'left';
 if ( ! empty( $parsed_block['innerBlocks'] ) ) {
 foreach ( $parsed_block['innerBlocks'] as $inner_block ) {
 $inner_block['context'] = $inner_block['context'] ?? array();
 $inner_block['context']['postId'] = $product->get_id();
 if ( 'woocommerce/product-sale-badge' === $inner_block['blockName'] ) {
 $badges .= $this->render_overlay_badge( $inner_block, $product, $rendering_context );
 $badge_alignment = $inner_block['attrs']['align'] ?? 'left';
 } else {
 $other_content .= render_block( $inner_block );
 }
 }
 }
 return array(
 'badges' => $badges,
 'other_content' => $other_content,
 'badge_alignment' => $badge_alignment,
 );
 }
 private function render_overlay_badge( array $badge_block, \WC_Product $product, Rendering_Context $rendering_context ): string {
 if ( ! $product->is_on_sale() ) {
 return '';
 }
 $sale_text = apply_filters( 'woocommerce_sale_badge_text', __( 'Sale', 'woocommerce' ), $product );
 $badge_attributes = array_replace_recursive(
 array(
 'textColor' => '#43454b',
 'backgroundColor' => '#fff',
 'style' => array(
 'border' => array(
 'width' => '1px',
 'radius' => '4px',
 'color' => '#43454b',
 ),
 'spacing' => array(
 'padding' => '4px 12px',
 ),
 'typography' => array(
 'fontSize' => '14px',
 'fontWeight' => '600',
 'textTransform' => 'uppercase',
 'lineHeight' => '1.5',
 ),
 ),
 ),
 wp_parse_args( $badge_block['attrs'] ?? array() )
 );
 $block_styles = Styles_Helper::get_block_styles(
 $badge_attributes,
 $rendering_context,
 array( 'border', 'background-color', 'color', 'typography', 'spacing' )
 );
 $additional_styles = array(
 'display' => 'inline-block',
 'width' => 'fit-content',
 'box-sizing' => 'border-box',
 );
 $final_styles = Styles_Helper::extend_block_styles( $block_styles, $additional_styles );
 return sprintf(
 '<span class="wc-block-components-product-sale-badge__text" style="%s">%s</span>',
 esc_attr( $final_styles['css'] ),
 esc_html( $sale_text )
 );
 }
 private function create_overlay_structure(
 string $image_html,
 string $badges_html,
 string $other_content,
 string $badge_alignment,
 ?\WC_Product $product = null,
 bool $show_product_link = false
 ): string {
 if ( empty( $badges_html ) ) {
 $linked_image_html = $image_html;
 if ( $show_product_link && $product ) {
 $linked_image_html = $this->wrap_with_link( $image_html, $product );
 }
 return $linked_image_html . $other_content;
 }
 $image_width = $this->extract_image_width( $image_html );
 $image_height = $this->extract_image_height( $image_html );
 $linked_image_html = $image_html;
 if ( $show_product_link && $product ) {
 $linked_image_html = $this->wrap_with_link( $image_html, $product );
 }
 $vml_side = ( 'left' === $badge_alignment ) ? 'left' : 'right';
 $overlay_html = sprintf(
 '<table cellpadding="0" cellspacing="0" border="0" style="width: %dpx; height: %dpx; table-layout: fixed;">
 <tr>
 <td style="font-size: 0; line-height: 0; padding: 0; height: %dpx; width: %dpx;">
 <div style="max-height:0; position:relative; opacity:0.999;">
 <!--[if mso]>
 <v:rect xmlns:v="urn:schemas-microsoft-com:vml" stroked="false" filled="false" style="mso-width-percent: 1000; position:absolute; top:16px; ' . esc_attr( $vml_side ) . ':16px;">
 <v:textbox inset="0,0,0,0">
 <![endif]-->
 <div style="padding: 12px; box-sizing: border-box; display: inline-block; width: 100%%; text-align: %s;">
 %s
 </div>
 <!--[if mso]>
 </v:textbox>
 </v:rect>
 <![endif]-->
 </div>
 %s
 </td>
 </tr>
 </table>%s',
 $image_width,
 $image_height,
 $image_height,
 $image_width,
 $badge_alignment,
 $badges_html,
 $linked_image_html,
 $other_content
 );
 return $overlay_html;
 }
 private function extract_image_width( string $image_html ): float {
 $width = ( new Dom_Document_Helper( $image_html ) )->get_attribute_value_by_tag_name( 'img', 'width' ) ?? '';
 if ( $width ) {
 return Styles_Helper::parse_value( $width );
 }
 return 300;
 }
 private function extract_image_height( string $image_html ): float {
 $height = ( new Dom_Document_Helper( $image_html ) )->get_attribute_value_by_tag_name( 'img', 'height' ) ?? '';
 if ( $height ) {
 return Styles_Helper::parse_value( $height );
 }
 return 300;
 }
 private function add_image_size_when_missing( array $parsed_block, Rendering_Context $rendering_context ): array {
 if ( isset( $parsed_block['attrs']['width'] ) ) {
 return $parsed_block;
 }
 if ( ! isset( $parsed_block['email_attrs']['width'] ) ) {
 $parsed_block['attrs']['width'] = '100%';
 return $parsed_block;
 }
 $parsed_block['attrs']['width'] = $rendering_context->get_layout_width_without_padding();
 return $parsed_block;
 }
 private function parse_attributes( array $attributes ): array {
 return wp_parse_args(
 $attributes,
 array(
 'showProductLink' => true,
 'imageSizing' => 'single',
 'scale' => 'cover',
 'showSaleBadge' => false,
 'saleBadgeAlign' => 'right',
 )
 );
 }
 private function get_product_image_data( \WC_Product $product, array $attributes ): ?array {
 $image_size = 'single' === $attributes['imageSizing'] ? 'woocommerce_single' : 'woocommerce_thumbnail';
 $image_id = (int) $product->get_image_id();
 if ( ! $image_id ) {
 $placeholder = wc_placeholder_img_src( $image_size );
 return array(
 'url' => $placeholder,
 'alt' => $product->get_name(),
 'width' => 300,
 'height' => 300,
 );
 }
 $image_url = wp_get_attachment_image_url( $image_id, $image_size );
 if ( ! $image_url ) {
 return null;
 }
 $alt_text = get_post_meta( $image_id, '_wp_attachment_image_alt', true );
 $image_meta = wp_get_attachment_metadata( $image_id );
 return array(
 'url' => $image_url,
 'alt' => $alt_text ? $alt_text : $product->get_name(),
 'width' => $image_meta['width'] ?? 300,
 'height' => $image_meta['height'] ?? 300,
 );
 }
 private function build_image_html( array $image_data, array $attributes, Rendering_Context $rendering_context ): string {
 $style_parts = array(
 'max-width' => '100%',
 'height' => 'auto',
 'display' => 'block',
 );
 if ( ! empty( $attributes['scale'] ) ) {
 $style_parts['object-fit'] = $attributes['scale'];
 }
 if ( ! empty( $attributes['width'] ) ) {
 $style_parts['width'] = $attributes['width'];
 }
 if ( ! empty( $attributes['height'] ) ) {
 $style_parts['height'] = $attributes['height'];
 }
 if ( ! empty( $attributes['aspectRatio'] ) ) {
 $style_parts['aspect-ratio'] = $attributes['aspectRatio'];
 }
 $width = ! empty( $attributes['width'] ) ? Styles_Helper::parse_value( $attributes['width'] ) : $image_data['width'];
 $layout_width = Styles_Helper::parse_value( $rendering_context->get_layout_width_without_padding() );
 if ( $width > $layout_width ) {
 $width = $layout_width;
 $aspect_ratio = $image_data['height'] / $image_data['width'];
 $attributes['height'] = round( $width * $aspect_ratio ) . 'px';
 }
 $height = $image_data['height'];
 if ( ! empty( $attributes['height'] ) ) {
 $height = Styles_Helper::parse_value( $attributes['height'] );
 } elseif ( ! empty( $attributes['width'] ) && $image_data['width'] > 0 ) {
 $aspect_ratio = $image_data['height'] / $image_data['width'];
 $height = round( $width * $aspect_ratio );
 }
 return sprintf(
 '<img class="email-editor-product-image skip-lazy" data-skip-lazy="1" loading="eager" decoding="auto" src="%s" alt="%s" style="%s" width="%d" height="%d" />',
 esc_url( $image_data['url'] ),
 esc_attr( $image_data['alt'] ),
 esc_attr( \WP_Style_Engine::compile_css( $style_parts, '' ) ),
 $width,
 $height
 );
 }
 private function wrap_with_link( string $image_html, \WC_Product $product ): string {
 $product_url = $product->get_permalink();
 return sprintf(
 '<a href="%s" style="display: block; text-decoration: none;">%s</a>',
 esc_url( $product_url ),
 $image_html
 );
 }
 private function apply_email_wrapper( string $image_html, array $parsed_block, Rendering_Context $rendering_context ): string {
 $width = $parsed_block['attrs']['width'] ?? '';
 $wrapper_width = ( $width && '100%' !== $width ) ? $width : 'auto';
 $image_height = $this->extract_image_height( $image_html ) . 'px';
 $wrapper_styles = array(
 'border-collapse' => 'separate',
 'width' => $wrapper_width,
 );
 $cell_styles = array(
 'overflow' => 'hidden',
 'vertical-align' => 'top',
 );
 $align = $parsed_block['attrs']['align'] ?? 'left';
 $cell_styles['text-align'] = $align;
 $outer_table_attrs = array(
 'style' => \WP_Style_Engine::compile_css(
 array(
 'border-collapse' => 'collapse',
 'border-spacing' => '0px',
 'width' => '100%',
 'height' => $image_height,
 ),
 ''
 ),
 'width' => '100%',
 );
 $outer_cell_attrs = array(
 'align' => $align,
 );
 $inner_table_attrs = array(
 'style' => \WP_Style_Engine::compile_css( $wrapper_styles, '' ),
 'width' => $wrapper_width,
 'height' => $image_height,
 );
 $inner_cell_attrs = array(
 'style' => \WP_Style_Engine::compile_css( $cell_styles, '' ),
 );
 $inner_content = Table_Wrapper_Helper::render_table_wrapper( $image_html, $inner_table_attrs, $inner_cell_attrs );
 return Table_Wrapper_Helper::render_table_wrapper( $inner_content, $outer_table_attrs, $outer_cell_attrs );
 }
}
