<?php
/**
 * Widget Name: Product Notice
 * Description: A flexible store notice / announcement block for product pages —
 *              choose a notice type (info, success, warning, error), add a title,
 *              rich message and optional icon, make it dismissible (optionally
 *              remembered), or output WooCommerce's own notices. Ships with
 *              multiple attractive styles.
 *
 * @package    captain-widgets-kit
 * @subpackage captain-widgets-kit/includes
 * @since      1.4.0
 */

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

use Elementor\Widget_Base;
use Elementor\Controls_Manager;
use Elementor\Group_Control_Typography;
use Elementor\Group_Control_Border;
use Elementor\Group_Control_Box_Shadow;
use Elementor\Icons_Manager;

/**
 * Class Captwiki_Woo_Product_Notice
 *
 * @since 1.4.0
 */
class Captwiki_Woo_Product_Notice extends Widget_Base {

	/**
	 * Get widget name.
	 *
	 * @since 1.4.0
	 * @return string
	 */
	public function get_name(): string {
		return 'captwiki-woo-product-notice';
	}

	/**
	 * Get widget title.
	 *
	 * @since 1.4.0
	 * @return string
	 */
	public function get_title(): string {
		return esc_html__( 'Product Notice', 'captain-widgets-kit' );
	}

	/**
	 * Get widget icon.
	 *
	 * @since 1.4.0
	 * @return string
	 */
	public function get_icon(): string {
		return 'eicon-alert captwiki-el-logo';
	}

	/**
	 * Get widget categories.
	 *
	 * @since 1.4.0
	 * @return array
	 */
	public function get_categories(): array {
		return array( 'captwiki-woo-commerce' );
	}

	/**
	 * Get widget keywords.
	 *
	 * @since 1.4.0
	 * @return array
	 */
	public function get_keywords(): array {
		return array( 'woocommerce', 'woo', 'product', 'notice', 'alert', 'announcement', 'message', 'banner', 'captain-widgets-kit' );
	}

	/**
	 * Disable Elementor's default inner wrapper.
	 *
	 * @since 1.4.0
	 * @return bool
	 */
	public function has_widget_inner_wrapper(): bool {
		return ! \Elementor\Plugin::$instance->experiments->is_feature_active( 'e_optimized_markup' );
	}

	/**
	 * Available visual styles.
	 *
	 * @since 1.4.0
	 * @return array
	 */
	private function captwiki_style_options(): array {
		return array(
			'style-1' => esc_html__( 'Style 1 – Solid', 'captain-widgets-kit' ),
			'style-2' => esc_html__( 'Style 2 – Soft Tint', 'captain-widgets-kit' ),
			'style-3' => esc_html__( 'Style 3 – Left Accent', 'captain-widgets-kit' ),
			'style-4' => esc_html__( 'Style 4 – Outline', 'captain-widgets-kit' ),
			'style-5' => esc_html__( 'Style 5 – Top Bar', 'captain-widgets-kit' ),
			'style-6' => esc_html__( 'Style 6 – Toast Card', 'captain-widgets-kit' ),
		);
	}

	/**
	 * Notice type options.
	 *
	 * @since 1.4.0
	 * @return array
	 */
	private function captwiki_type_options(): array {
		return array(
			'info'    => esc_html__( 'Info', 'captain-widgets-kit' ),
			'success' => esc_html__( 'Success', 'captain-widgets-kit' ),
			'warning' => esc_html__( 'Warning', 'captain-widgets-kit' ),
			'error'   => esc_html__( 'Error', 'captain-widgets-kit' ),
		);
	}

	/**
	 * Register controls.
	 *
	 * @since 1.4.0
	 */
	protected function register_controls(): void {
		$this->register_content_controls();
		$this->register_icon_style_controls();
		$this->register_title_style_controls();
		$this->register_box_style_controls();
	}

	/**
	 * Content tab controls.
	 *
	 * @since 1.4.0
	 */
	private function register_content_controls(): void {

		$this->start_controls_section(
			'section_content',
			array(
				'label' => esc_html__( 'Notice', 'captain-widgets-kit' ),
				'tab'   => Controls_Manager::TAB_CONTENT,
			)
		);

		$this->add_control(
			'widget_style',
			array(
				'label'   => esc_html__( 'Style', 'captain-widgets-kit' ),
				'type'    => Controls_Manager::SELECT,
				'default' => 'style-1',
				'options' => $this->captwiki_style_options(),
			)
		);

		$this->add_control(
			'source',
			array(
				'label'   => esc_html__( 'Source', 'captain-widgets-kit' ),
				'type'    => Controls_Manager::SELECT,
				'default' => 'custom',
				'options' => array(
					'custom'      => esc_html__( 'Custom Message', 'captain-widgets-kit' ),
					'woocommerce' => esc_html__( 'WooCommerce Notices', 'captain-widgets-kit' ),
				),
				'description' => esc_html__( 'WooCommerce Notices outputs the dynamic cart/checkout messages for this page.', 'captain-widgets-kit' ),
			)
		);

		$this->add_control(
			'notice_type',
			array(
				'label'     => esc_html__( 'Type', 'captain-widgets-kit' ),
				'type'      => Controls_Manager::SELECT,
				'default'   => 'info',
				'options'   => $this->captwiki_type_options(),
				'condition' => array( 'source' => 'custom' ),
			)
		);

		$this->add_control(
			'title_text',
			array(
				'label'       => esc_html__( 'Title', 'captain-widgets-kit' ),
				'type'        => Controls_Manager::TEXT,
				'default'     => esc_html__( 'Heads up!', 'captain-widgets-kit' ),
				'label_block' => true,
				'condition'   => array( 'source' => 'custom' ),
			)
		);

		$this->add_control(
			'message',
			array(
				'label'     => esc_html__( 'Message', 'captain-widgets-kit' ),
				'type'      => Controls_Manager::WYSIWYG,
				'default'   => esc_html__( 'Order before 2 PM for same-day dispatch.', 'captain-widgets-kit' ),
				'condition' => array( 'source' => 'custom' ),
			)
		);

		$this->add_control(
			'show_icon',
			array(
				'label'        => esc_html__( 'Show Icon', 'captain-widgets-kit' ),
				'type'         => Controls_Manager::SWITCHER,
				'label_on'     => esc_html__( 'Show', 'captain-widgets-kit' ),
				'label_off'    => esc_html__( 'Hide', 'captain-widgets-kit' ),
				'return_value' => 'yes',
				'default'      => 'yes',
				'condition'    => array( 'source' => 'custom' ),
			)
		);

		$this->add_control(
			'icon_mode',
			array(
				'label'     => esc_html__( 'Icon', 'captain-widgets-kit' ),
				'type'      => Controls_Manager::SELECT,
				'default'   => 'auto',
				'options'   => array(
					'auto'   => esc_html__( 'Default (by type)', 'captain-widgets-kit' ),
					'custom' => esc_html__( 'Custom Icon', 'captain-widgets-kit' ),
				),
				'condition' => array(
					'source'    => 'custom',
					'show_icon' => 'yes',
				),
			)
		);

		$this->add_control(
			'custom_icon',
			array(
				'label'     => esc_html__( 'Choose Icon', 'captain-widgets-kit' ),
				'type'      => Controls_Manager::ICONS,
				'condition' => array(
					'source'    => 'custom',
					'show_icon' => 'yes',
					'icon_mode' => 'custom',
				),
			)
		);

		$this->add_control(
			'dismissible',
			array(
				'label'        => esc_html__( 'Dismissible', 'captain-widgets-kit' ),
				'type'         => Controls_Manager::SWITCHER,
				'label_on'     => esc_html__( 'Yes', 'captain-widgets-kit' ),
				'label_off'    => esc_html__( 'No', 'captain-widgets-kit' ),
				'return_value' => 'yes',
				'default'      => 'no',
				'separator'    => 'before',
				'condition'    => array( 'source' => 'custom' ),
			)
		);

		$this->add_control(
			'persist_dismiss',
			array(
				'label'        => esc_html__( 'Remember Dismissal', 'captain-widgets-kit' ),
				'type'         => Controls_Manager::SWITCHER,
				'label_on'     => esc_html__( 'Yes', 'captain-widgets-kit' ),
				'label_off'    => esc_html__( 'No', 'captain-widgets-kit' ),
				'return_value' => 'yes',
				'default'      => 'no',
				'description'  => esc_html__( 'Keeps the notice hidden for the visitor after they close it (stored in the browser).', 'captain-widgets-kit' ),
				'condition'    => array(
					'source'      => 'custom',
					'dismissible' => 'yes',
				),
			)
		);

		$this->add_control(
			'wc_notice_hint',
			array(
				'type'      => Controls_Manager::RAW_HTML,
				'raw'       => esc_html__( 'WooCommerce notices appear here when there are cart/checkout messages on this page.', 'captain-widgets-kit' ),
				'content_classes' => 'elementor-descriptor',
				'condition' => array( 'source' => 'woocommerce' ),
			)
		);

		$this->add_responsive_control(
			'content_align',
			array(
				'label'     => esc_html__( 'Text Alignment', 'captain-widgets-kit' ),
				'type'      => Controls_Manager::CHOOSE,
				'options'   => array(
					'left'   => array(
						'title' => esc_html__( 'Left', 'captain-widgets-kit' ),
						'icon'  => 'eicon-text-align-left',
					),
					'center' => array(
						'title' => esc_html__( 'Center', 'captain-widgets-kit' ),
						'icon'  => 'eicon-text-align-center',
					),
					'right'  => array(
						'title' => esc_html__( 'Right', 'captain-widgets-kit' ),
						'icon'  => 'eicon-text-align-right',
					),
				),
				'default'   => 'left',
				'separator' => 'before',
				'selectors' => array(
					'{{WRAPPER}} .captwiki-pnotice__body' => 'text-align: {{VALUE}};',
				),
			)
		);

		$this->end_controls_section();
	}

	/**
	 * Icon style controls.
	 *
	 * @since 1.4.0
	 */
	private function register_icon_style_controls(): void {

		$selector = '{{WRAPPER}} .captwiki-pnotice__icon';

		$this->start_controls_section(
			'section_icon_style',
			array(
				'label'     => esc_html__( 'Icon', 'captain-widgets-kit' ),
				'tab'       => Controls_Manager::TAB_STYLE,
				'condition' => array(
					'source'    => 'custom',
					'show_icon' => 'yes',
				),
			)
		);

		$this->add_control(
			'icon_color',
			array(
				'label'     => esc_html__( 'Color', 'captain-widgets-kit' ),
				'type'      => Controls_Manager::COLOR,
				'selectors' => array(
					$selector => 'color: {{VALUE}};',
				),
			)
		);

		$this->add_responsive_control(
			'icon_size',
			array(
				'label'      => esc_html__( 'Size', 'captain-widgets-kit' ),
				'type'       => Controls_Manager::SLIDER,
				'size_units' => array( 'px' ),
				'range'      => array( 'px' => array( 'min' => 12, 'max' => 64 ) ),
				'selectors'  => array(
					$selector             => 'width: {{SIZE}}{{UNIT}}; height: {{SIZE}}{{UNIT}};',
					$selector . ' svg'    => 'width: {{SIZE}}{{UNIT}}; height: {{SIZE}}{{UNIT}};',
					$selector . ' i'      => 'font-size: {{SIZE}}{{UNIT}};',
				),
			)
		);

		$this->end_controls_section();
	}

	/**
	 * Title & message style controls.
	 *
	 * @since 1.4.0
	 */
	private function register_title_style_controls(): void {

		$title_selector   = '{{WRAPPER}} .captwiki-pnotice__title';
		$message_selector = '{{WRAPPER}} .captwiki-pnotice__message';

		$this->start_controls_section(
			'section_text_style',
			array(
				'label'     => esc_html__( 'Title & Message', 'captain-widgets-kit' ),
				'tab'       => Controls_Manager::TAB_STYLE,
				'condition' => array( 'source' => 'custom' ),
			)
		);

		$this->add_control(
			'title_color',
			array(
				'label'     => esc_html__( 'Title Color', 'captain-widgets-kit' ),
				'type'      => Controls_Manager::COLOR,
				'selectors' => array(
					$title_selector => 'color: {{VALUE}};',
				),
			)
		);

		$this->add_group_control(
			Group_Control_Typography::get_type(),
			array(
				'name'     => 'title_typography',
				'selector' => $title_selector,
			)
		);

		$this->add_control(
			'message_color',
			array(
				'label'     => esc_html__( 'Message Color', 'captain-widgets-kit' ),
				'type'      => Controls_Manager::COLOR,
				'separator' => 'before',
				'selectors' => array(
					$message_selector            => 'color: {{VALUE}};',
					$message_selector . ' p'     => 'color: {{VALUE}};',
				),
			)
		);

		$this->add_group_control(
			Group_Control_Typography::get_type(),
			array(
				'name'     => 'message_typography',
				'selector' => $message_selector . ', ' . $message_selector . ' p',
			)
		);

		$this->add_responsive_control(
			'title_spacing',
			array(
				'label'      => esc_html__( 'Title Spacing', 'captain-widgets-kit' ),
				'type'       => Controls_Manager::SLIDER,
				'size_units' => array( 'px' ),
				'range'      => array( 'px' => array( 'min' => 0, 'max' => 30 ) ),
				'selectors'  => array(
					$title_selector => 'margin-bottom: {{SIZE}}{{UNIT}};',
				),
			)
		);

		$this->end_controls_section();
	}

	/**
	 * Box style controls.
	 *
	 * @since 1.4.0
	 */
	private function register_box_style_controls(): void {

		$wrap_selector = '{{WRAPPER}} .captwiki-pnotice';

		$this->start_controls_section(
			'section_box_style',
			array(
				'label' => esc_html__( 'Box', 'captain-widgets-kit' ),
				'tab'   => Controls_Manager::TAB_STYLE,
			)
		);

		$this->add_control(
			'box_bg',
			array(
				'label'     => esc_html__( 'Background', 'captain-widgets-kit' ),
				'type'      => Controls_Manager::COLOR,
				'selectors' => array(
					$wrap_selector => 'background-color: {{VALUE}};',
				),
			)
		);

		$this->add_control(
			'accent_color',
			array(
				'label'       => esc_html__( 'Accent / Border Color', 'captain-widgets-kit' ),
				'type'        => Controls_Manager::COLOR,
				'description' => esc_html__( 'Overrides the left bar / top bar / outline color of the selected style.', 'captain-widgets-kit' ),
				'selectors'   => array(
					$wrap_selector                                  => 'border-color: {{VALUE}};',
					'{{WRAPPER}} .captwiki-pnotice.captwiki-style-3' => 'border-left-color: {{VALUE}};',
					'{{WRAPPER}} .captwiki-pnotice.captwiki-style-5' => 'border-top-color: {{VALUE}};',
				),
			)
		);

		$this->add_responsive_control(
			'box_padding',
			array(
				'label'      => esc_html__( 'Padding', 'captain-widgets-kit' ),
				'type'       => Controls_Manager::DIMENSIONS,
				'size_units' => array( 'px', 'em' ),
				'separator'  => 'before',
				'selectors'  => array(
					$wrap_selector => 'padding: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};',
				),
			)
		);

		$this->add_responsive_control(
			'icon_gap',
			array(
				'label'      => esc_html__( 'Icon Gap', 'captain-widgets-kit' ),
				'type'       => Controls_Manager::SLIDER,
				'size_units' => array( 'px' ),
				'range'      => array( 'px' => array( 'min' => 0, 'max' => 40 ) ),
				'selectors'  => array(
					'{{WRAPPER}} .captwiki-pnotice__inner' => 'gap: {{SIZE}}{{UNIT}};',
				),
			)
		);

		$this->add_group_control(
			Group_Control_Border::get_type(),
			array(
				'name'      => 'box_border',
				'selector'  => $wrap_selector,
				'separator' => 'before',
			)
		);

		$this->add_responsive_control(
			'box_radius',
			array(
				'label'      => esc_html__( 'Border Radius', 'captain-widgets-kit' ),
				'type'       => Controls_Manager::DIMENSIONS,
				'size_units' => array( 'px', '%' ),
				'selectors'  => array(
					$wrap_selector => 'border-radius: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};',
				),
			)
		);

		$this->add_group_control(
			Group_Control_Box_Shadow::get_type(),
			array(
				'name'     => 'box_shadow',
				'selector' => $wrap_selector,
			)
		);

		$this->end_controls_section();
	}

	/**
	 * Built-in SVG icon for a notice type.
	 *
	 * @since 1.4.0
	 * @param string $type Notice type.
	 * @return string
	 */
	private function captwiki_type_icon( string $type ): string {

		$icons = array(
			'info'    => '<svg viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"><circle cx="12" cy="12" r="10" stroke="currentColor" stroke-width="2"/><path d="M12 11v5" stroke="currentColor" stroke-width="2" stroke-linecap="round"/><circle cx="12" cy="7.6" r="1.3" fill="currentColor"/></svg>',
			'success' => '<svg viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"><circle cx="12" cy="12" r="10" stroke="currentColor" stroke-width="2"/><path d="M8 12.5l2.5 2.5L16 9.5" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/></svg>',
			'warning' => '<svg viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M12 3l9.5 16.5H2.5L12 3z" stroke="currentColor" stroke-width="2" stroke-linejoin="round"/><path d="M12 9.5v4" stroke="currentColor" stroke-width="2" stroke-linecap="round"/><circle cx="12" cy="16.6" r="1.2" fill="currentColor"/></svg>',
			'error'   => '<svg viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"><circle cx="12" cy="12" r="10" stroke="currentColor" stroke-width="2"/><path d="M9 9l6 6M15 9l-6 6" stroke="currentColor" stroke-width="2" stroke-linecap="round"/></svg>',
		);

		return isset( $icons[ $type ] ) ? $icons[ $type ] : $icons['info'];
	}

	/**
	 * Output an editor-only notice.
	 *
	 * @since 1.4.0
	 * @param string $message Notice text.
	 */
	private function captwiki_render_editor_notice( string $message ): void {

		if ( ! \Elementor\Plugin::$instance->editor->is_edit_mode() ) {
			return;
		}

		echo '<div class="captwiki-pnotice captwiki-pnotice--placeholder"><p>' . esc_html( $message ) . '</p></div>';
	}

	/**
	 * Render widget output on the frontend.
	 *
	 * @since 1.4.0
	 */
	protected function render(): void {

		$settings = $this->get_settings_for_display();
		$source   = ! empty( $settings['source'] ) ? $settings['source'] : 'custom';

		$allowed_styles = array_keys( $this->captwiki_style_options() );
		$style          = ! empty( $settings['widget_style'] ) && in_array( $settings['widget_style'], $allowed_styles, true ) ? $settings['widget_style'] : 'style-1';

		wp_enqueue_style(
			'captwiki-woo-product-notice-' . $style,
			CAPTWIKI_URL . 'assets/css/widgets/woo-product-notice/captwiki-woo-product-notice-' . $style . '.css',
			array( 'captwiki-woo-product-notice' ),
			CAPTWIKI_VERSION
		);

		// WooCommerce notices source.
		if ( 'woocommerce' === $source ) {

			if ( ! function_exists( 'wc_print_notices' ) || ! function_exists( 'wc_notice_count' ) ) {
				$this->captwiki_render_editor_notice( esc_html__( 'WooCommerce is required for the WooCommerce Notices source.', 'captain-widgets-kit' ) );
				return;
			}

			if ( \Elementor\Plugin::$instance->editor->is_edit_mode() ) {
				$this->captwiki_render_editor_notice( esc_html__( 'WooCommerce notices will be shown here on the live site when present.', 'captain-widgets-kit' ) );
				return;
			}

			if ( wc_notice_count() > 0 ) {
				echo '<div class="captwiki-pnotice captwiki-' . esc_attr( $style ) . ' captwiki-pnotice--wc captwiki-widget-' . esc_attr( $this->get_id() ) . '">';
				wc_print_notices();
				echo '</div>';
			}

			return;
		}

		// Custom message source.
		$type         = ! empty( $settings['notice_type'] ) ? $settings['notice_type'] : 'info';
		$allowed_type = array_keys( $this->captwiki_type_options() );
		$type         = in_array( $type, $allowed_type, true ) ? $type : 'info';

		$title   = isset( $settings['title_text'] ) ? $settings['title_text'] : '';
		$message = isset( $settings['message'] ) ? $settings['message'] : '';

		if ( '' === trim( wp_strip_all_tags( (string) $title ) ) && '' === trim( wp_strip_all_tags( (string) $message ) ) ) {
			$this->captwiki_render_editor_notice( esc_html__( 'Add a title or message for the Product Notice.', 'captain-widgets-kit' ) );
			return;
		}

		$show_icon   = ! empty( $settings['show_icon'] ) && 'yes' === $settings['show_icon'];
		$dismissible = ! empty( $settings['dismissible'] ) && 'yes' === $settings['dismissible'];
		$persist     = $dismissible && ! empty( $settings['persist_dismiss'] ) && 'yes' === $settings['persist_dismiss'];

		if ( $dismissible ) {
			wp_enqueue_script( 'captwiki-woo-product-notice' );
		}

		$wrapper_classes = array(
			'captwiki-pnotice',
			'captwiki-' . $style,
			'captwiki-pnotice--' . $type,
			'captwiki-widget-' . $this->get_id(),
		);

		if ( $dismissible ) {
			$wrapper_classes[] = 'captwiki-pnotice--dismissible';
		}

		$attrs = '';
		if ( $dismissible ) {
			$attrs .= ' data-dismissible="1"';
			$attrs .= ' data-persist="' . esc_attr( $persist ? '1' : '0' ) . '"';
			$attrs .= ' data-key="captwiki-pnotice-' . esc_attr( $this->get_id() ) . '"';
		}

		echo '<div class="' . esc_attr( implode( ' ', $wrapper_classes ) ) . '"' . $attrs . '>'; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
		echo '<div class="captwiki-pnotice__inner">';

		if ( $show_icon ) {
			echo '<span class="captwiki-pnotice__icon">';

			if ( ! empty( $settings['icon_mode'] ) && 'custom' === $settings['icon_mode'] && ! empty( $settings['custom_icon']['value'] ) ) {
				Icons_Manager::render_icon( $settings['custom_icon'], array( 'aria-hidden' => 'true' ) );
			} else {
				echo $this->captwiki_type_icon( $type ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
			}

			echo '</span>';
		}

		echo '<div class="captwiki-pnotice__body">';

		if ( '' !== trim( wp_strip_all_tags( (string) $title ) ) ) {
			echo '<div class="captwiki-pnotice__title">' . esc_html( $title ) . '</div>';
		}

		if ( '' !== trim( wp_strip_all_tags( (string) $message ) ) ) {
			echo '<div class="captwiki-pnotice__message">' . wp_kses_post( $message ) . '</div>';
		}

		echo '</div>'; // body.

		if ( $dismissible ) {
			echo '<button type="button" class="captwiki-pnotice__close" aria-label="' . esc_attr__( 'Dismiss', 'captain-widgets-kit' ) . '">';
			echo '<svg viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg" aria-hidden="true"><path d="M6 6l12 12M18 6L6 18" stroke="currentColor" stroke-width="2" stroke-linecap="round"/></svg>';
			echo '</button>';
		}

		echo '</div>'; // inner.
		echo '</div>'; // wrapper.
	}
}
