<?php
/**
 * Storzen v1.2.1 — New Cart Page Elementor Widgets
 *
 * Adds two widgets to the "Cart" Elementor panel category:
 *
 *  • Storzen_Empty_Cart_Widget       — Custom empty-cart state: illustration,
 *                                      heading, sub-text, and CTA button.
 *                                      Shown only when WC cart is empty;
 *                                      hidden when cart has items so it can
 *                                      sit safely on the Elementor cart page
 *                                      alongside Cart Table without conflict.
 *
 *  • Storzen_Cart_Cross_Sell_Widget  — Cart-page cross-sell section powered
 *                                      entirely by WooCommerce's native
 *                                      woocommerce_cross_sell_display() +
 *                                      woocommerce_cross_sells_columns /
 *                                      woocommerce_cross_sells_limit filters.
 *                                      Gives page-builder positional freedom
 *                                      over the cross-sell block that would
 *                                      otherwise be buried inside the Cart
 *                                      Table collaterals hook.
 *
 * INSTALLATION:
 *   Place this file at:
 *     storzen/elementor/widgets/class-storzen-style-cart-widgets-new.php
 *   Then apply the patch to storzen-elementor-widgets-init.php (see below).
 *
 * The Storzen_Cart_Widget_Helpers trait is defined in the existing
 * class-storzen-style-cart-widgets.php, which is always require_once'd
 * before this file. No re-declaration needed.
 *
 * @package storzen
 * @since   1.2.1
 */

namespace Elementor;

if ( ! defined( 'ABSPATH' ) ) {
	exit;
}

// ─────────────────────────────────────────────────────────────────────────────
// Widget 1: Empty Cart Message
// ─────────────────────────────────────────────────────────────────────────────

/**
 * Custom empty-cart state widget.
 *
 * Renders an illustration (SVG built-in or custom image), a heading,
 * sub-text, and a CTA button when the WooCommerce cart is empty.
 * When the cart has items the widget renders nothing — no wrapper, no
 * hidden div — so it coexists safely with Cart Table on the same page.
 *
 * Toggle key:  cart_empty_message
 * Category:    storzen-cart
 *
 * @since 1.2.1
 */
class Storzen_Empty_Cart_Widget extends Widget_Base {

	use Storzen_Cart_Widget_Helpers;

	// ── Identity ──────────────────────────────────────────────────────────────

	public function get_name() {
		return 'storzen-empty-cart';
	}

	public function get_title() {
		return esc_html__( 'Empty Cart Message', 'storzen' );
	}

	public function get_icon() {
		return 'eicon-cart-light';
	}

	public function get_categories() {
		return array( 'storzen-cart' );
	}

	public function get_keywords() {
		return array( 'empty', 'cart', 'no items', 'placeholder', 'cta', 'storzen' );
	}

	// ── Controls ──────────────────────────────────────────────────────────────

	protected function register_controls() {

		// ── Content tab — Illustration ────────────────────────────────────────

		$this->start_controls_section(
			'section_illustration',
			array(
				'label' => esc_html__( 'Illustration', 'storzen' ),
				'tab'   => Controls_Manager::TAB_CONTENT,
			)
		);

		$this->add_control(
			'illustration_type',
			array(
				'label'   => esc_html__( 'Illustration Type', 'storzen' ),
				'type'    => Controls_Manager::SELECT,
				'default' => 'builtin',
				'options' => array(
					'builtin' => esc_html__( 'Built-in SVG', 'storzen' ),
					'image'   => esc_html__( 'Custom Image', 'storzen' ),
					'none'    => esc_html__( 'None', 'storzen' ),
				),
			)
		);

		$this->add_control(
			'illustration_image',
			array(
				'label'     => esc_html__( 'Custom Image', 'storzen' ),
				'type'      => Controls_Manager::MEDIA,
				'condition' => array( 'illustration_type' => 'image' ),
			)
		);

		$this->add_responsive_control(
			'illustration_width',
			array(
				'label'      => esc_html__( 'Width', 'storzen' ),
				'type'       => Controls_Manager::SLIDER,
				'size_units' => array( 'px', '%' ),
				'range'      => array(
					'px' => array( 'min' => 40, 'max' => 400 ),
					'%'  => array( 'min' => 10, 'max' => 100 ),
				),
				'default'    => array( 'unit' => 'px', 'size' => 140 ),
				'selectors'  => array(
					'{{WRAPPER}} .sz-empty-cart__illustration'     => 'width: {{SIZE}}{{UNIT}};',
					'{{WRAPPER}} .sz-empty-cart__illustration img' => 'width: 100%;',
				),
				'condition'  => array( 'illustration_type!' => 'none' ),
			)
		);

		$this->add_control(
			'illustration_color',
			array(
				'label'     => esc_html__( 'SVG Color', 'storzen' ),
				'type'      => Controls_Manager::COLOR,
				'default'   => '#d1d5db',
				'selectors' => array(
					'{{WRAPPER}} .sz-empty-cart__svg path,
					 {{WRAPPER}} .sz-empty-cart__svg circle,
					 {{WRAPPER}} .sz-empty-cart__svg rect' => 'fill: {{VALUE}};',
				),
				'condition' => array( 'illustration_type' => 'builtin' ),
			)
		);

		$this->end_controls_section();

		// ── Content tab — Text ────────────────────────────────────────────────

		$this->start_controls_section(
			'section_text',
			array(
				'label' => esc_html__( 'Message', 'storzen' ),
				'tab'   => Controls_Manager::TAB_CONTENT,
			)
		);

		$this->add_control(
			'heading',
			array(
				'label'       => esc_html__( 'Heading', 'storzen' ),
				'type'        => Controls_Manager::TEXT,
				'default'     => esc_html__( 'Your cart is empty', 'storzen' ),
				'placeholder' => esc_html__( 'Your cart is empty', 'storzen' ),
				'label_block' => true,
			)
		);

		$this->add_control(
			'heading_tag',
			array(
				'label'   => esc_html__( 'Heading Tag', 'storzen' ),
				'type'    => Controls_Manager::SELECT,
				'default' => 'h2',
				'options' => array(
					'h1' => 'H1',
					'h2' => 'H2',
					'h3' => 'H3',
					'h4' => 'H4',
					'p'  => 'P',
				),
			)
		);

		$this->add_control(
			'subtext',
			array(
				'label'       => esc_html__( 'Sub-text', 'storzen' ),
				'type'        => Controls_Manager::TEXTAREA,
				'rows'        => 3,
				'default'     => esc_html__( 'Looks like you haven\'t added anything to your cart yet.', 'storzen' ),
				'placeholder' => esc_html__( 'Add a short message here…', 'storzen' ),
			)
		);

		$this->end_controls_section();

		// ── Content tab — CTA Button ──────────────────────────────────────────

		$this->start_controls_section(
			'section_cta',
			array(
				'label' => esc_html__( 'CTA Button', 'storzen' ),
				'tab'   => Controls_Manager::TAB_CONTENT,
			)
		);

		$this->add_control(
			'show_cta',
			array(
				'label'        => esc_html__( 'Show Button', 'storzen' ),
				'type'         => Controls_Manager::SWITCHER,
				'label_on'     => esc_html__( 'Show', 'storzen' ),
				'label_off'    => esc_html__( 'Hide', 'storzen' ),
				'return_value' => 'yes',
				'default'      => 'yes',
			)
		);

		$this->add_control(
			'cta_text',
			array(
				'label'     => esc_html__( 'Button Label', 'storzen' ),
				'type'      => Controls_Manager::TEXT,
				'default'   => esc_html__( 'Continue Shopping', 'storzen' ),
				'condition' => array( 'show_cta' => 'yes' ),
			)
		);

		$this->add_control(
			'cta_url',
			array(
				'label'       => esc_html__( 'Button URL', 'storzen' ),
				'type'        => Controls_Manager::URL,
				'placeholder' => esc_html__( 'https://…', 'storzen' ),
				'default'     => array(
					'url'         => function_exists( 'wc_get_page_permalink' )
						? wc_get_page_permalink( 'shop' )
						: '#',
					'is_external' => false,
					'nofollow'    => false,
				),
				'condition'   => array( 'show_cta' => 'yes' ),
			)
		);

		$this->add_control(
			'cta_icon',
			array(
				'label'     => esc_html__( 'Button Icon', 'storzen' ),
				'type'      => Controls_Manager::ICONS,
				'default'   => array(
					'value'   => 'fas fa-arrow-right',
					'library' => 'fa-solid',
				),
				'condition' => array( 'show_cta' => 'yes' ),
			)
		);

		$this->add_control(
			'cta_icon_position',
			array(
				'label'     => esc_html__( 'Icon Position', 'storzen' ),
				'type'      => Controls_Manager::SELECT,
				'default'   => 'after',
				'options'   => array(
					'before' => esc_html__( 'Before', 'storzen' ),
					'after'  => esc_html__( 'After', 'storzen' ),
				),
				'condition' => array( 'show_cta' => 'yes' ),
			)
		);

		$this->end_controls_section();

		// ── Style tab — Layout ────────────────────────────────────────────────

		$this->start_controls_section(
			'section_style_layout',
			array(
				'label' => esc_html__( 'Layout', 'storzen' ),
				'tab'   => Controls_Manager::TAB_STYLE,
			)
		);

		$this->add_control(
			'align',
			array(
				'label'     => esc_html__( 'Alignment', 'storzen' ),
				'type'      => Controls_Manager::CHOOSE,
				'options'   => array(
					'left'   => array( 'title' => esc_html__( 'Left', 'storzen' ),   'icon' => 'eicon-text-align-left' ),
					'center' => array( 'title' => esc_html__( 'Center', 'storzen' ), 'icon' => 'eicon-text-align-center' ),
					'right'  => array( 'title' => esc_html__( 'Right', 'storzen' ),  'icon' => 'eicon-text-align-right' ),
				),
				'default'   => 'center',
				'selectors' => array(
					'{{WRAPPER}} .sz-empty-cart' => 'text-align: {{VALUE}};',
					'{{WRAPPER}} .sz-empty-cart__illustration' => 'margin-inline: auto;',
				),
			)
		);

		$this->add_responsive_control(
			'padding',
			array(
				'label'      => esc_html__( 'Padding', 'storzen' ),
				'type'       => Controls_Manager::DIMENSIONS,
				'size_units' => array( 'px', 'em', '%' ),
				'default'    => array(
					'top'    => '60',
					'right'  => '20',
					'bottom' => '60',
					'left'   => '20',
					'unit'   => 'px',
				),
				'selectors'  => array(
					'{{WRAPPER}} .sz-empty-cart' => 'padding: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};',
				),
			)
		);

		$this->add_responsive_control(
			'gap_between',
			array(
				'label'      => esc_html__( 'Gap Between Elements', 'storzen' ),
				'type'       => Controls_Manager::SLIDER,
				'size_units' => array( 'px', 'em' ),
				'range'      => array( 'px' => array( 'min' => 0, 'max' => 60 ) ),
				'default'    => array( 'unit' => 'px', 'size' => 18 ),
				'selectors'  => array(
					'{{WRAPPER}} .sz-empty-cart' => 'gap: {{SIZE}}{{UNIT}};',
				),
			)
		);

		$this->add_control(
			'bg_color',
			array(
				'label'     => esc_html__( 'Background', 'storzen' ),
				'type'      => Controls_Manager::COLOR,
				'selectors' => array(
					'{{WRAPPER}} .sz-empty-cart' => 'background-color: {{VALUE}};',
				),
			)
		);

		$this->add_group_control(
			Group_Control_Border::get_type(),
			array(
				'name'     => 'container_border',
				'selector' => '{{WRAPPER}} .sz-empty-cart',
			)
		);

		$this->add_control(
			'border_radius',
			array(
				'label'      => esc_html__( 'Border Radius', 'storzen' ),
				'type'       => Controls_Manager::SLIDER,
				'size_units' => array( 'px', '%' ),
				'range'      => array( 'px' => array( 'min' => 0, 'max' => 40 ) ),
				'selectors'  => array(
					'{{WRAPPER}} .sz-empty-cart' => 'border-radius: {{SIZE}}{{UNIT}};',
				),
			)
		);

		$this->end_controls_section();

		// ── Style tab — Heading ───────────────────────────────────────────────

		$this->start_controls_section(
			'section_style_heading',
			array(
				'label' => esc_html__( 'Heading', 'storzen' ),
				'tab'   => Controls_Manager::TAB_STYLE,
			)
		);

		$this->add_control(
			'heading_color',
			array(
				'label'     => esc_html__( 'Color', 'storzen' ),
				'type'      => Controls_Manager::COLOR,
				'default'   => '#111827',
				'selectors' => array(
					'{{WRAPPER}} .sz-empty-cart__heading' => 'color: {{VALUE}};',
				),
			)
		);

		$this->add_group_control(
			Group_Control_Typography::get_type(),
			array(
				'name'     => 'heading_typography',
				'selector' => '{{WRAPPER}} .sz-empty-cart__heading',
			)
		);

		$this->end_controls_section();

		// ── Style tab — Sub-text ──────────────────────────────────────────────

		$this->start_controls_section(
			'section_style_subtext',
			array(
				'label' => esc_html__( 'Sub-text', 'storzen' ),
				'tab'   => Controls_Manager::TAB_STYLE,
			)
		);

		$this->add_control(
			'subtext_color',
			array(
				'label'     => esc_html__( 'Color', 'storzen' ),
				'type'      => Controls_Manager::COLOR,
				'default'   => '#6b7280',
				'selectors' => array(
					'{{WRAPPER}} .sz-empty-cart__subtext' => 'color: {{VALUE}};',
				),
			)
		);

		$this->add_group_control(
			Group_Control_Typography::get_type(),
			array(
				'name'     => 'subtext_typography',
				'selector' => '{{WRAPPER}} .sz-empty-cart__subtext',
			)
		);

		$this->end_controls_section();

		// ── Style tab — CTA Button ────────────────────────────────────────────

		$this->start_controls_section(
			'section_style_cta',
			array(
				'label'     => esc_html__( 'CTA Button', 'storzen' ),
				'tab'       => Controls_Manager::TAB_STYLE,
				'condition' => array( 'show_cta' => 'yes' ),
			)
		);

		$this->start_controls_tabs( 'cta_button_tabs' );

		$this->start_controls_tab(
			'cta_tab_normal',
			array( 'label' => esc_html__( 'Normal', 'storzen' ) )
		);

		$this->add_control(
			'cta_bg',
			array(
				'label'     => esc_html__( 'Background', 'storzen' ),
				'type'      => Controls_Manager::COLOR,
				'default'   => '#FF3636',
				'selectors' => array(
					'{{WRAPPER}} .sz-empty-cart__cta' => 'background-color: {{VALUE}};',
				),
			)
		);

		$this->add_control(
			'cta_text_color',
			array(
				'label'     => esc_html__( 'Text Color', 'storzen' ),
				'type'      => Controls_Manager::COLOR,
				'default'   => '#ffffff',
				'selectors' => array(
					'{{WRAPPER}} .sz-empty-cart__cta' => 'color: {{VALUE}};',
				),
			)
		);

		$this->end_controls_tab();

		$this->start_controls_tab(
			'cta_tab_hover',
			array( 'label' => esc_html__( 'Hover', 'storzen' ) )
		);

		$this->add_control(
			'cta_hover_bg',
			array(
				'label'     => esc_html__( 'Background', 'storzen' ),
				'type'      => Controls_Manager::COLOR,
				'default'   => '#cc2929',
				'selectors' => array(
					'{{WRAPPER}} .sz-empty-cart__cta:hover,
					 {{WRAPPER}} .sz-empty-cart__cta:focus-visible' => 'background-color: {{VALUE}};',
				),
			)
		);

		$this->add_control(
			'cta_hover_text_color',
			array(
				'label'     => esc_html__( 'Text Color', 'storzen' ),
				'type'      => Controls_Manager::COLOR,
				'selectors' => array(
					'{{WRAPPER}} .sz-empty-cart__cta:hover,
					 {{WRAPPER}} .sz-empty-cart__cta:focus-visible' => 'color: {{VALUE}};',
				),
			)
		);

		$this->end_controls_tab();
		$this->end_controls_tabs();

		$this->add_control(
			'cta_border_radius',
			array(
				'label'      => esc_html__( 'Border Radius', 'storzen' ),
				'type'       => Controls_Manager::SLIDER,
				'size_units' => array( 'px', '%' ),
				'range'      => array( 'px' => array( 'min' => 0, 'max' => 60 ) ),
				'default'    => array( 'unit' => 'px', 'size' => 6 ),
				'selectors'  => array(
					'{{WRAPPER}} .sz-empty-cart__cta' => 'border-radius: {{SIZE}}{{UNIT}};',
				),
				'separator'  => 'before',
			)
		);

		$this->add_responsive_control(
			'cta_padding',
			array(
				'label'      => esc_html__( 'Padding', 'storzen' ),
				'type'       => Controls_Manager::DIMENSIONS,
				'size_units' => array( 'px', 'em' ),
				'default'    => array(
					'top'    => '12',
					'right'  => '28',
					'bottom' => '12',
					'left'   => '28',
					'unit'   => 'px',
				),
				'selectors'  => array(
					'{{WRAPPER}} .sz-empty-cart__cta' => 'padding: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};',
				),
			)
		);

		$this->add_group_control(
			Group_Control_Typography::get_type(),
			array(
				'name'     => 'cta_typography',
				'selector' => '{{WRAPPER}} .sz-empty-cart__cta',
			)
		);

		$this->end_controls_section();
	}

	// ── Render ────────────────────────────────────────────────────────────────

	protected function render() {

		// WooCommerce not active at all — show editor placeholder.
		if ( ! function_exists( 'WC' ) ) {
			$this->render_placeholder( esc_html__( 'Empty Cart Message — requires WooCommerce.', 'storzen' ) );
			return;
		}

		$is_editor = $this->is_editor_or_preview();

		// On the real frontend: only render when the cart is genuinely empty.
		// In the editor: always render so the designer can style the widget.
		if ( ! $is_editor ) {
			if ( ! WC()->cart || ! WC()->cart->is_empty() ) {
				return; // Cart has items — nothing to show, no wrapper div.
			}
		}

		$s           = $this->get_settings_for_display();
		$heading     = isset( $s['heading'] ) ? trim( $s['heading'] ) : '';
		$subtext     = isset( $s['subtext'] ) ? trim( $s['subtext'] ) : '';
		$show_cta    = 'yes' === ( $s['show_cta'] ?? 'yes' );
		$cta_text    = isset( $s['cta_text'] ) ? trim( $s['cta_text'] ) : '';
		$cta_url_raw = $s['cta_url'] ?? array();
		$cta_href    = ! empty( $cta_url_raw['url'] ) ? $cta_url_raw['url'] : wc_get_page_permalink( 'shop' );
		$external    = ! empty( $cta_url_raw['is_external'] );
		$nofollow    = ! empty( $cta_url_raw['nofollow'] );
		$ill_type    = $s['illustration_type'] ?? 'builtin';
		$icon_pos    = $s['cta_icon_position'] ?? 'after';

		$heading_tag = isset( $s['heading_tag'] ) && in_array( $s['heading_tag'], array( 'h1', 'h2', 'h3', 'h4', 'p' ), true )
			? $s['heading_tag'] : 'h2';

		echo '<div class="sz-empty-cart szp-cart-widget woocommerce">';

		// ── Illustration ───────────────────────────────────────────────────
		if ( 'builtin' === $ill_type ) {
			echo '<div class="sz-empty-cart__illustration" aria-hidden="true">';
			echo $this->get_builtin_svg(); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- SVG is hardcoded and safe
			echo '</div>';
		} elseif ( 'image' === $ill_type && ! empty( $s['illustration_image']['id'] ) ) {
			echo '<div class="sz-empty-cart__illustration">';
			echo wp_get_attachment_image(
				(int) $s['illustration_image']['id'],
				'medium',
				false,
				array(
					'alt'     => esc_attr__( 'Empty cart', 'storzen' ),
					'loading' => 'lazy',
				)
			);
			echo '</div>';
		}

		// ── Heading ────────────────────────────────────────────────────────
		if ( $heading !== '' ) {
			printf(
				'<%1$s class="sz-empty-cart__heading">%2$s</%1$s>',
				esc_attr( $heading_tag ),
				esc_html( $heading )
			);
		}

		// ── Sub-text ───────────────────────────────────────────────────────
		if ( $subtext !== '' ) {
			printf(
				'<p class="sz-empty-cart__subtext">%s</p>',
				esc_html( $subtext )
			);
		}

		// ── CTA Button ─────────────────────────────────────────────────────
		if ( $show_cta && $cta_text !== '' ) {
			$link_attrs  = 'href="' . esc_url( $cta_href ) . '"';
			$link_attrs .= $external ? ' target="_blank" rel="noopener noreferrer' . ( $nofollow ? ' nofollow' : '' ) . '"' : '';
			$link_attrs .= ! $external && $nofollow ? ' rel="nofollow"' : '';

			// Icon HTML
			$icon_html = '';
			if ( ! empty( $s['cta_icon']['value'] ) ) {
				ob_start();
				Icons_Manager::render_icon( $s['cta_icon'], array( 'aria-hidden' => 'true' ) );
				$icon_html = ob_get_clean();
			}

			$label_html = 'before' === $icon_pos
				? $icon_html . ' ' . esc_html( $cta_text )
				: esc_html( $cta_text ) . ' ' . $icon_html;

			printf(
				'<a %1$s class="sz-empty-cart__cta button">%2$s</a>',
				$link_attrs, // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- attrs escaped above
				wp_kses_post( $label_html )
			);
		}

		echo '</div><!-- .sz-empty-cart -->';
	}

	// ── Helpers ───────────────────────────────────────────────────────────────

	/**
	 * True in Elementor editor or preview iframe.
	 */
	private function is_editor_or_preview() {
		$pl = \Elementor\Plugin::$instance;
		if ( ! empty( $pl->editor ) && method_exists( $pl->editor, 'is_edit_mode' ) && $pl->editor->is_edit_mode() ) {
			return true;
		}
		if ( ! empty( $pl->preview ) && method_exists( $pl->preview, 'is_preview_mode' ) && $pl->preview->is_preview_mode() ) {
			return true;
		}
		return false;
	}

	/**
	 * Editor-only placeholder.
	 *
	 * @param string $label
	 */
	private function render_placeholder( $label ) {
		if ( $this->is_editor_or_preview() ) {
			printf(
				'<div class="szp-cart-widget-placeholder" style="padding:16px;border:1px dashed #ccc;border-radius:6px;background:#f9f9f9;font-size:13px;color:#555;">%s</div>',
				esc_html( $label )
			);
		}
	}

	/**
	 * Returns the built-in empty-cart SVG illustration.
	 * Inline SVG so color can be controlled via CSS/Elementor color picker.
	 *
	 * @return string Safe SVG markup.
	 */
	private function get_builtin_svg() {
		return '<svg class="sz-empty-cart__svg" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 140 140" width="140" height="140" aria-hidden="true" focusable="false">
			<circle cx="70" cy="70" r="68" fill="none" stroke="currentColor" stroke-opacity=".08" stroke-width="2"/>
			<!-- Cart body -->
			<rect x="32" y="54" width="68" height="44" rx="6" fill="currentColor" fill-opacity=".12"/>
			<!-- Cart handle -->
			<path d="M22 38h12l10 38h52l8-28H44" fill="none" stroke="currentColor" stroke-width="5" stroke-linecap="round" stroke-linejoin="round"/>
			<!-- Wheels -->
			<circle cx="54" cy="106" r="6" fill="currentColor"/>
			<circle cx="84" cy="106" r="6" fill="currentColor"/>
			<!-- X mark (empty indicator) -->
			<line x1="58" y1="66" x2="74" y2="82" stroke="#ef4444" stroke-width="4" stroke-linecap="round"/>
			<line x1="74" y1="66" x2="58" y2="82" stroke="#ef4444" stroke-width="4" stroke-linecap="round"/>
		</svg>';
	}
}


// ─────────────────────────────────────────────────────────────────────────────
// Widget 2: Cart Cross-Sell Products
// ─────────────────────────────────────────────────────────────────────────────

/**
 * Cart-page cross-sell section widget.
 *
 * Wraps WooCommerce's native woocommerce_cross_sell_display() function so
 * page-builder layouts can position the cross-sell block independently of
 * the Cart Table widget (which strips it from the collaterals hook).
 *
 * By using the WC function directly the widget inherits:
 *  • Theme template overrides (cart/cross-sells.php)
 *  • storzen_cross_sells_columns / storzen_cross_sells_limit filters
 *  • WooCommerce's own logic for which products to suggest
 *    (products in `$product->get_cross_sell_ids()` for all cart items)
 *
 * Toggle key:  cart_cross_sell_widget
 * Category:    storzen-cart
 *
 * @since 1.2.1
 */
class Storzen_Cart_Cross_Sell_Widget extends Widget_Base {

	use Storzen_Cart_Widget_Helpers;

	// ── Identity ──────────────────────────────────────────────────────────────

	public function get_name() {
		return 'storzen-cart-cross-sell';
	}

	public function get_title() {
		return esc_html__( 'Cross-Sell Products', 'storzen' );
	}

	public function get_icon() {
		return 'eicon-product-related';
	}

	public function get_categories() {
		return array( 'storzen-cart' );
	}

	public function get_keywords() {
		return array( 'cross-sell', 'upsell', 'related', 'cart', 'recommendations', 'storzen' );
	}

	// ── Controls ──────────────────────────────────────────────────────────────

	protected function register_controls() {

		// ── Content tab ───────────────────────────────────────────────────────

		$this->start_controls_section(
			'section_content',
			array(
				'label' => esc_html__( 'Cross-Sell Settings', 'storzen' ),
				'tab'   => Controls_Manager::TAB_CONTENT,
			)
		);

		$this->add_control(
			'section_title',
			array(
				'label'       => esc_html__( 'Section Title', 'storzen' ),
				'type'        => Controls_Manager::TEXT,
				'default'     => esc_html__( 'You May Also Like', 'storzen' ),
				'placeholder' => esc_html__( 'You May Also Like', 'storzen' ),
				'description' => esc_html__( 'Overrides the WooCommerce default "You may be interested in…" heading.', 'storzen' ),
				'label_block' => true,
			)
		);

		$this->add_control(
			'title_tag',
			array(
				'label'   => esc_html__( 'Title Tag', 'storzen' ),
				'type'    => Controls_Manager::SELECT,
				'default' => 'h2',
				'options' => array(
					'h2' => 'H2',
					'h3' => 'H3',
					'h4' => 'H4',
					'p'  => 'P',
				),
			)
		);

		$this->add_control(
			'posts_per_page',
			array(
				'label'       => esc_html__( 'Max Products', 'storzen' ),
				'type'        => Controls_Manager::NUMBER,
				'min'         => 1,
				'max'         => 12,
				'step'        => 1,
				'default'     => 4,
				'description' => esc_html__( 'Controls woocommerce_cross_sells_limit filter.', 'storzen' ),
			)
		);

		$this->add_responsive_control(
			'columns',
			array(
				'label'          => esc_html__( 'Columns', 'storzen' ),
				'type'           => Controls_Manager::SELECT,
				'default'        => '4',
				'tablet_default' => '3',
				'mobile_default' => '2',
				'options'        => array(
					'1' => '1',
					'2' => '2',
					'3' => '3',
					'4' => '4',
					'5' => '5',
				),
			)
		);

		$this->add_control(
			'orderby',
			array(
				'label'   => esc_html__( 'Order By', 'storzen' ),
				'type'    => Controls_Manager::SELECT,
				'default' => 'rand',
				'options' => array(
					'rand'  => esc_html__( 'Random', 'storzen' ),
					'title' => esc_html__( 'Title (A–Z)', 'storzen' ),
					'date'  => esc_html__( 'Date (newest)', 'storzen' ),
					'price' => esc_html__( 'Price', 'storzen' ),
				),
			)
		);

		$this->end_controls_section();

		// ── Style tab — Section Title ─────────────────────────────────────────

		$this->start_controls_section(
			'section_style_title',
			array(
				'label' => esc_html__( 'Section Title', 'storzen' ),
				'tab'   => Controls_Manager::TAB_STYLE,
			)
		);

		$this->add_control(
			'title_color',
			array(
				'label'     => esc_html__( 'Color', 'storzen' ),
				'type'      => Controls_Manager::COLOR,
				'selectors' => array(
					'{{WRAPPER}} .sz-cross-sell-title' => 'color: {{VALUE}};',
				),
			)
		);

		$this->add_group_control(
			Group_Control_Typography::get_type(),
			array(
				'name'     => 'title_typography',
				'selector' => '{{WRAPPER}} .sz-cross-sell-title',
			)
		);

		$this->add_responsive_control(
			'title_margin',
			array(
				'label'      => esc_html__( 'Margin Bottom', 'storzen' ),
				'type'       => Controls_Manager::SLIDER,
				'size_units' => array( 'px', 'em' ),
				'range'      => array( 'px' => array( 'min' => 0, 'max' => 60 ) ),
				'default'    => array( 'unit' => 'px', 'size' => 20 ),
				'selectors'  => array(
					'{{WRAPPER}} .sz-cross-sell-title' => 'margin-bottom: {{SIZE}}{{UNIT}};',
				),
			)
		);

		$this->end_controls_section();

		// ── Style tab — Product Cards ─────────────────────────────────────────

		$this->start_controls_section(
			'section_style_cards',
			array(
				'label' => esc_html__( 'Product Cards', 'storzen' ),
				'tab'   => Controls_Manager::TAB_STYLE,
			)
		);

		$this->add_control(
			'card_bg',
			array(
				'label'     => esc_html__( 'Card Background', 'storzen' ),
				'type'      => Controls_Manager::COLOR,
				'selectors' => array(
					'{{WRAPPER}} .cross-sells ul.products li.product' => 'background-color: {{VALUE}};',
				),
			)
		);

		$this->add_group_control(
			Group_Control_Border::get_type(),
			array(
				'name'     => 'card_border',
				'selector' => '{{WRAPPER}} .cross-sells ul.products li.product',
			)
		);

		$this->add_control(
			'card_radius',
			array(
				'label'      => esc_html__( 'Border Radius', 'storzen' ),
				'type'       => Controls_Manager::SLIDER,
				'size_units' => array( 'px', '%' ),
				'range'      => array( 'px' => array( 'min' => 0, 'max' => 30 ) ),
				'default'    => array( 'unit' => 'px', 'size' => 8 ),
				'selectors'  => array(
					'{{WRAPPER}} .cross-sells ul.products li.product' => 'border-radius: {{SIZE}}{{UNIT}}; overflow: hidden;',
				),
			)
		);

		$this->add_responsive_control(
			'card_gap',
			array(
				'label'      => esc_html__( 'Card Gap', 'storzen' ),
				'type'       => Controls_Manager::SLIDER,
				'size_units' => array( 'px' ),
				'range'      => array( 'px' => array( 'min' => 0, 'max' => 60 ) ),
				'default'    => array( 'unit' => 'px', 'size' => 20 ),
				'selectors'  => array(
					'{{WRAPPER}} .cross-sells ul.products' => 'gap: {{SIZE}}{{UNIT}};',
				),
			)
		);

		$this->end_controls_section();

		// ── Style tab — Add to Cart Button ────────────────────────────────────

		$this->start_controls_section(
			'section_style_atc',
			array(
				'label' => esc_html__( 'Add to Cart Button', 'storzen' ),
				'tab'   => Controls_Manager::TAB_STYLE,
			)
		);

		$this->add_control(
			'atc_bg',
			array(
				'label'     => esc_html__( 'Background', 'storzen' ),
				'type'      => Controls_Manager::COLOR,
				'default'   => '#FF3636',
				'selectors' => array(
					'{{WRAPPER}} .cross-sells .add_to_cart_button,
					 {{WRAPPER}} .cross-sells .button' => 'background-color: {{VALUE}}; border-color: {{VALUE}};',
				),
			)
		);

		$this->add_control(
			'atc_color',
			array(
				'label'     => esc_html__( 'Text Color', 'storzen' ),
				'type'      => Controls_Manager::COLOR,
				'default'   => '#ffffff',
				'selectors' => array(
					'{{WRAPPER}} .cross-sells .add_to_cart_button,
					 {{WRAPPER}} .cross-sells .button' => 'color: {{VALUE}};',
				),
			)
		);

		$this->add_control(
			'atc_hover_bg',
			array(
				'label'     => esc_html__( 'Hover Background', 'storzen' ),
				'type'      => Controls_Manager::COLOR,
				'default'   => '#cc2929',
				'selectors' => array(
					'{{WRAPPER}} .cross-sells .add_to_cart_button:hover,
					 {{WRAPPER}} .cross-sells .button:hover' => 'background-color: {{VALUE}}; border-color: {{VALUE}};',
				),
			)
		);

		$this->add_control(
			'atc_radius',
			array(
				'label'      => esc_html__( 'Border Radius', 'storzen' ),
				'type'       => Controls_Manager::SLIDER,
				'size_units' => array( 'px', '%' ),
				'range'      => array( 'px' => array( 'min' => 0, 'max' => 50 ) ),
				'default'    => array( 'unit' => 'px', 'size' => 4 ),
				'selectors'  => array(
					'{{WRAPPER}} .cross-sells .add_to_cart_button,
					 {{WRAPPER}} .cross-sells .button' => 'border-radius: {{SIZE}}{{UNIT}};',
				),
			)
		);

		$this->end_controls_section();
	}

	// ── Render ────────────────────────────────────────────────────────────────

	protected function render() {

		// WooCommerce or cart not available.
		if ( $this->szp_cart_maybe_placeholder( esc_html__( 'Cross-Sell Products — requires WooCommerce with an active cart session.', 'storzen' ) ) ) {
			return;
		}

		$s = $this->get_settings_for_display();

		// ── Widget-local filters ───────────────────────────────────────────
		// We use closures stored in variables so we can remove them precisely.

		$limit   = max( 1, (int) ( $s['posts_per_page'] ?? 4 ) );
		$columns = max( 1, (int) ( $s['columns'] ?? 4 ) );
		$orderby = in_array( $s['orderby'] ?? 'rand', array( 'rand', 'title', 'date', 'price' ), true )
			? $s['orderby'] : 'rand';

		$f_limit   = static function () use ( $limit )   { return $limit; };
		$f_columns = static function () use ( $columns ) { return $columns; };
		$f_orderby = static function ( $args ) use ( $orderby ) {
			$args['orderby'] = $orderby;
			$args['order']   = 'price' === $orderby ? 'ASC' : 'DESC';
			return $args;
		};

		add_filter( 'woocommerce_cross_sells_limit',   $f_limit );
		add_filter( 'woocommerce_cross_sells_columns', $f_columns );
		add_filter( 'woocommerce_cross_sells_order',   $f_orderby ); // WC 3.x+

		// ── Section title override ─────────────────────────────────────────
		$title    = isset( $s['section_title'] ) ? trim( $s['section_title'] ) : '';
		$tag      = isset( $s['title_tag'] ) && in_array( $s['title_tag'], array( 'h2', 'h3', 'h4', 'p' ), true )
			? $s['title_tag'] : 'h2';

		$f_title  = null;
		if ( $title !== '' ) {
			$f_title = static function () use ( $title, $tag ) {
				return '<' . $tag . ' class="sz-cross-sell-title">' . esc_html( $title ) . '</' . $tag . '>';
			};
			// WC renders the heading inside the template; override it:
			add_filter( 'woocommerce_product_cross_sells_heading', $f_title );
		}

		// ── Render ─────────────────────────────────────────────────────────
		// Ensure the WOOCOMMERCE_CART constant is set so WC templates work.
		wc_maybe_define_constant( 'WOOCOMMERCE_CART', true );

		/*
		 * woocommerce_cross_sell_display() checks WC()->cart->get_cross_sells()
		 * which returns an array of product IDs linked to all items in the cart.
		 * If the cart is empty it renders nothing — that is correct behaviour.
		 *
		 * In the Elementor editor/preview we need something to show so the
		 * designer can work. We inject a dummy output in that case.
		 */
		$is_editor = $this->is_editor_or_preview();

		echo '<div class="szp-cart-widget szp-cross-sell-widget woocommerce">';

		if ( $is_editor && WC()->cart->is_empty() ) {
			$this->render_editor_preview( $s );
		} else {
			// WC's own function — respects the filters we just set.
			if ( function_exists( 'woocommerce_cross_sell_display' ) ) {
				woocommerce_cross_sell_display();
			}
		}

		echo '</div><!-- .szp-cross-sell-widget -->';

		// ── Remove our closures to keep the global filter stack clean ──────
		remove_filter( 'woocommerce_cross_sells_limit',   $f_limit );
		remove_filter( 'woocommerce_cross_sells_columns', $f_columns );
		remove_filter( 'woocommerce_cross_sells_order',   $f_orderby );
		if ( $f_title ) {
			remove_filter( 'woocommerce_product_cross_sells_heading', $f_title );
		}
	}

	// ── Helpers ───────────────────────────────────────────────────────────────

	/**
	 * True in Elementor editor or preview iframe.
	 */
	private function is_editor_or_preview() {
		$pl = \Elementor\Plugin::$instance;
		if ( ! empty( $pl->editor ) && method_exists( $pl->editor, 'is_edit_mode' ) && $pl->editor->is_edit_mode() ) {
			return true;
		}
		if ( ! empty( $pl->preview ) && method_exists( $pl->preview, 'is_preview_mode' ) && $pl->preview->is_preview_mode() ) {
			return true;
		}
		return false;
	}

	/**
	 * Editor preview when cart is empty — shows last N published products
	 * using WC's own loop template so the designer sees real product cards.
	 *
	 * @param array $s Widget settings.
	 */
	private function render_editor_preview( array $s ) {
		$limit   = max( 1, (int) ( $s['posts_per_page'] ?? 4 ) );
		$columns = max( 1, (int) ( $s['columns'] ?? 4 ) );
		$title   = isset( $s['section_title'] ) ? trim( $s['section_title'] ) : '';
		$tag     = isset( $s['title_tag'] ) && in_array( $s['title_tag'], array( 'h2', 'h3', 'h4', 'p' ), true )
			? $s['title_tag'] : 'h2';

		$products = wc_get_products(
			array(
				'limit'   => $limit,
				'orderby' => 'date',
				'order'   => 'DESC',
				'status'  => 'publish',
			)
		);

		if ( empty( $products ) ) {
			printf(
				'<p style="padding:16px;color:#6b7280;font-size:13px;">%s</p>',
				esc_html__( 'Cross-Sell Products — add cross-sells to your products to see them here. Showing real products in editor preview.', 'storzen' )
			);
			return;
		}

		if ( $title !== '' ) {
			printf( '<%1$s class="sz-cross-sell-title">%2$s</%1$s>', esc_attr( $tag ), esc_html( $title ) );
		}

		echo '<div class="cross-sells">';
		printf( '<ul class="products columns-%d">', absint( $columns ) );

		foreach ( $products as $product ) {
			$pid    = $product->get_id();
			$name   = $product->get_name();
			$href   = get_permalink( $pid );

			echo '<li class="product">';
			printf(
				'<a href="%1$s">%2$s<h2 class="woocommerce-loop-product__title">%3$s</h2></a>',
				esc_url( $href ),
				wp_kses_post( $product->get_image( 'woocommerce_thumbnail' ) ),
				esc_html( $name )
			);
			echo wp_kses_post( $product->get_price_html() );
			printf(
				'<a href="%1$s" class="button">%2$s</a>',
				esc_url( $product->add_to_cart_url() ),
				esc_html( $product->add_to_cart_text() )
			);
			echo '</li>';
		}

		echo '</ul></div>';

		printf(
			'<p style="font-size:11px;color:#9ca3af;text-align:center;margin-top:8px;">%s</p>',
			esc_html__( '↑ Editor preview only — live output shows actual cross-sell products from cart items.', 'storzen' )
		);
	}
}
