<?php
/**
 * Cart controller file.
 *
 * This file contains the main cart controller responsible for handling
 * WooCommerce cart events, updating stored abandoned cart data,
 * displaying recovery forms, adding stock urgency messages, and
 * processing GDPR-related fields.
 *
 * @package PixelioCartAbandonRecoveryMore
 * @since 0.1
 */

namespace PixelioCartAbandonRecoveryMore\Frontend\Controllers;

use PixelioCartAbandonRecoveryMore\Admin\Services\Pixelio_Cart_Abandon_Recovery_More_After_Purchase_Service;
use PixelioCartAbandonRecoveryMore\Admin\Views\Pixelio_Cart_Abandon_Recovery_More_Form_Builder;
use PixelioCartAbandonRecoveryMore\Admin\Wrapper\Pixelio_Cart_Abandon_Recovery_More_Woocommerce_Wrapper;
use PixelioCartAbandonRecoveryMore\Admin\Wrapper\Pixelio_Cart_Abandon_Recovery_More_Wordpress_Wrapper;
use PixelioCartAbandonRecoveryMore\Frontend\Repositories\Pixelio_Cart_Abandon_Recovery_More_Cart_Item_Repository;
use PixelioCartAbandonRecoveryMore\Frontend\Repositories\Pixelio_Cart_Abandon_Recovery_More_Cart_Repository;
use PixelioCartAbandonRecoveryMore\Frontend\Repositories\Pixelio_Cart_Abandon_Recovery_More_User_Consent_Repository;
use PixelioCartAbandonRecoveryMore\Frontend\Repositories\Pixelio_Cart_Abandon_Recovery_More_Uuid_Repository;
use PixelioCartAbandonRecoveryMore\Includes\Utils\Pixelio_Cart_Abandon_Recovery_More_Util;

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

/**
 * Main cart controller.
 *
 * Hooks into WooCommerce actions to track cart interactions,
 * update stored cart items, capture emails, handle GDPR fields,
 * add UX improvements (stock urgency), and trigger admin notifications.
 *
 * @since 0.1
 */
class Pixelio_Cart_Abandon_Recovery_More_Cart_Controller extends Pixelio_Cart_Abandon_Recovery_More_General_Controller
{

	private Pixelio_Cart_Abandon_Recovery_More_Wordpress_Wrapper $wordpress_wrapper;
	private Pixelio_Cart_Abandon_Recovery_More_Woocommerce_Wrapper $woocommerce_wrapper;
	private $cart_item_model;
	private Pixelio_Cart_Abandon_Recovery_More_User_Consent_Repository $user_consent_repo;
	private Pixelio_Cart_Abandon_Recovery_More_Uuid_Repository $uuid_repo;

	/**
	 * Constructor.
	 *
	 * Registers all WooCommerce hooks.
	 */
	public function __construct(Pixelio_Cart_Abandon_Recovery_More_Util                 $pixelio_util,
								Pixelio_Cart_Abandon_Recovery_More_Wordpress_Wrapper    $wordpress_wrapper,
								Pixelio_Cart_Abandon_Recovery_More_Woocommerce_Wrapper  $woocommerce_wrapper,
								Pixelio_Cart_Abandon_Recovery_More_Cart_Repository      $cart_model,
								Pixelio_Cart_Abandon_Recovery_More_Cart_Item_Repository $cart_item_model,
	Pixelio_Cart_Abandon_Recovery_More_User_Consent_Repository $user_consent_repo,
	Pixelio_Cart_Abandon_Recovery_More_UUID_Repository $uuid_repo)
	{
		$this->pixelio_util = $pixelio_util;
		$this->wordpress_wrapper = $wordpress_wrapper;
		$this->cart_model = $cart_model;
		$this->woocommerce_wrapper = $woocommerce_wrapper;
		$this->cart_item_model = $cart_item_model;
		$this->uuid_repo = $uuid_repo;
		$this->user_consent_repo = $user_consent_repo;
		parent::__construct($wordpress_wrapper, $pixelio_util);

		$this->wordpress_wrapper->pixelio_add_action('woocommerce_add_to_cart', array($this, 'pixelio_cart_abandon_recovery_more_add_to_cart'), 10, 6);
		$this->wordpress_wrapper->pixelio_add_filter('woocommerce_loop_add_to_cart_link', array($this, 'pixelio_cart_abandon_recovery_more_add_to_cart_button_class'), 10, 2);
		$this->wordpress_wrapper->pixelio_add_action('woocommerce_after_shop_loop_item', array($this, 'pixelio_cart_abandon_recovery_more_add_stock_message_before_add_to_cart'), 5);
		$this->wordpress_wrapper->pixelio_add_action('woocommerce_thankyou', array($this, 'pixelio_cart_abandon_recovery_more_after_purchase_action'), 10, 1);
		$this->wordpress_wrapper->pixelio_add_action('woocommerce_cart_emptied', array($this, 'pixelio_cart_abandon_recovery_more_cart_cleared'));
		$this->wordpress_wrapper->pixelio_add_action('woocommerce_remove_cart_item', array($this, 'pixelio_cart_abandon_recovery_more_cart_item_removed'), 10, 2);
		$this->wordpress_wrapper->pixelio_add_action('woocommerce_order_status_changed', array($this, 'pixelio_cart_abandon_recovery_more_cart_status_changed'), 10, 4);
		$this->wordpress_wrapper->pixelio_add_action('woocommerce_after_cart_item_quantity_update', array($this, 'pixelio_cart_abandon_recovery_more_on_quantity_update'), 10, 2);
		$this->wordpress_wrapper->pixelio_add_action('woocommerce_cart_contents', array($this, 'pixelio_cart_abandon_recovery_more_cart_email_capture_form'), 10, 2);
		$this->wordpress_wrapper->pixelio_add_action('render_block', array($this, 'pixelio_cart_abandon_recovery_more_add_form_in_cart_block'), 10, 2);
		$this->wordpress_wrapper->pixelio_add_action('woocommerce_after_checkout_billing_form', array($this, 'pixelio_cart_abandon_recovery_more_add_rgpd_checkbox_checkout'), 10, 2);
		$this->wordpress_wrapper->pixelio_add_action('woocommerce_single_product_summary', array($this, 'pixelio_cart_abandon_recovery_more_show_stock_hurry_up'), 25);
		$this->wordpress_wrapper->pixelio_add_action('woocommerce_checkout_create_order_line_item', array($this, 'pixelio_cart_abandon_recovery_more_transfer_metadata_to_order'), 10, 4);

	}


	function pixelio_cart_abandon_recovery_more_transfer_metadata_to_order($item, $cart_item_key, $values, $order): void
	{
		if (isset($values['pixelio_uuid'])) {
			$item->add_meta_data('pixelio_uuid', $values['pixelio_uuid'], true);
		}
		if (isset($values['pixelio_email_template'])) {
			$item->add_meta_data('pixelio_email_template', $values['pixelio_email_template'], true);
		}
	}

	/**
	 * Change the status of a cart in the Database
	 *
	 * @return void
	 */
	public function pixelio_cart_abandon_recovery_more_cart_status_changed($order_id, $old_status, $new_status, $order): void
	{
		$cart_id = $this->cart_model->pixelio_find_by_order_id($order_id);

		if (!$cart_id) {
			return;
		}

		$status_map = [
			'pending'    => 2,
			'processing' => 9,
			'on-hold'    => 10,
			'completed'  => 4,
			'cancelled'  => 7,
			'refunded'   => 11,
			'failed'     => 8,
		];

		if (!isset($status_map[$new_status])) {
			return;
		}

		$this->cart_model->update_status($cart_id, $order_id, $status_map[$new_status]);
	}

	/**
	 * Displays a stock urgency message on product pages.
	 *
	 * @return void
	 */
	public function pixelio_cart_abandon_recovery_more_show_stock_hurry_up(): void
	{
		if (!$this->pixelio_util->pixelio_cart_abandon_recovery_more_dependency_is_checked('pixelio-cart-abandon-recovery-more-show-stock-hurry-up-checkbox')) {
			return;
		}
		$product = $this->woocommerce_wrapper->pixelio_get_product();
		if (!$product) {
			return;
		}
		$this->wordpress_wrapper->pixelio_add_filter('woocommerce_get_stock_html', '__return_empty_string');
		$stock_quantity = 0;

		if ($product->is_type('variable')) {
			foreach ($product->get_children() as $variation_id) {
				$variation = $this->woocommerce_wrapper->pixelio_wc_get_product($variation_id);
				if ($variation && $variation->managing_stock()) {
					$stock_quantity += $variation->get_stock_quantity();
				}
			}
		} else {
			if (!$product->managing_stock()) {
				return;
			}
			$stock_quantity = $product->get_stock_quantity();
		}

		if ($stock_quantity <= 0) {
			return;
		}

		if ($stock_quantity <= 5) {
			/* translators: %d: number of items left in stock */
			$message = sprintf($this->wordpress_wrapper->pixelio_esc_html('Hurry up! Only %d left in stock.'), $stock_quantity);
		} elseif ($stock_quantity <= 10) {
			/* translators: %d: number of items remaining in stock */
			$message = sprintf($this->wordpress_wrapper->pixelio_esc_html('Limited stock! Only %d remaining, get it now!'), $stock_quantity);
		} else {
			/* translators: %d: number of items in stock */
			$message = sprintf($this->wordpress_wrapper->pixelio_esc_html('In stock: %d items'), $stock_quantity);
		}
		// phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- Escaped later before rendering.
		echo $this->wordpress_wrapper->pixelio_wp_kses('<p class="pixelio-stock-hurry-up" style="color:#d9534f; font-weight:600; margin-top:10px;">' . $this->wordpress_wrapper->pixelio_esc_html($message) . '</p>', Pixelio_Cart_Abandon_Recovery_More_Util::$pixelio_cart_abandon_recovery_more_allowed_html);
	}

	/**
	 * Injects the email capture form inside cart blocks.
	 *
	 * @param string $block_content Existing block content.
	 * @param array $block Block data.
	 * @return string
	 */
	public function pixelio_cart_abandon_recovery_more_add_form_in_cart_block($block_content, $block): string
	{
		if ('woocommerce/cart' === $block['blockName']) {
			$block_content = $this->pixelio_cart_abandon_recovery_more_get_cart_form_ajax() . $block_content;
		}
		return $block_content;
	}

	/**
	 * Generates the email capture form HTML.
	 *
	 * @return string HTML markup.
	 */
	private function pixelio_cart_abandon_recovery_more_get_cart_form_ajax()
	{

		$form_builder = new Pixelio_Cart_Abandon_Recovery_More_Form_Builder(
			$this->woocommerce_wrapper,
			$this->wordpress_wrapper,
			$this->pixelio_util,
			$this->user_consent_repo,$this->uuid_repo
		);
		$html = "";
		if(!$this->wordpress_wrapper->pixelio_is_user_logged_in() && !$this->pixelio_util->pixelio_cart_abandon_recovery_more_dependency_is_checked('pixelio-cart-abandon-recovery-more-gdpr-consent-checkbox')
		|| $this->pixelio_util->pixelio_cart_abandon_recovery_more_dependency_is_checked('pixelio-cart-abandon-recovery-more-gdpr-consent-checkbox')){
			$html = $form_builder->get_cart_recovery_form_html();
		}

		return $html;
	}

	/**
	 * Adds the GDPR checkbox on checkout.
	 *
	 * @param mixed $checkout Checkout object.
	 * @return void
	 */
	public function pixelio_cart_abandon_recovery_more_add_rgpd_checkbox_checkout($checkout, $ok): void
	{

		// phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- Escaped later before rendering.
		echo $this->wordpress_wrapper->pixelio_wp_kses('<div class="pixelio-checkout-rgpd" style="margin:10px 0;">', Pixelio_Cart_Abandon_Recovery_More_Util::$pixelio_cart_abandon_recovery_more_allowed_html);
		// phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- Escaped later before rendering.
		echo $this->wordpress_wrapper->pixelio_wp_kses('</div>', Pixelio_Cart_Abandon_Recovery_More_Util::$pixelio_cart_abandon_recovery_more_allowed_html);
	}

	/**
	 * Outputs the recovery form inside the cart.
	 *
	 * @return void
	 */
	public function pixelio_cart_abandon_recovery_more_cart_email_capture_form(): void
	{
		// phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- Escaped already.
		echo $this->wordpress_wrapper->pixelio_wp_kses($this->pixelio_cart_abandon_recovery_more_get_cart_form_ajax(), Pixelio_Cart_Abandon_Recovery_More_Util::$pixelio_cart_abandon_recovery_more_allowed_html);
	}

	/**
	 * Triggered when quantity changes in the cart.
	 *
	 * @param string $cart_item_key Cart item key.
	 * @param int $quantity Updated quantity.
	 * @return void
	 */
	public function pixelio_cart_abandon_recovery_more_on_quantity_update($cart_item_key, $quantity): void
	{
		$cart_item = $this->woocommerce_wrapper->pixelio_get_cart_item($cart_item_key);
		$product_id = $cart_item['product_id'];
		$variation_id = $cart_item['variation_id'] ?? 0;
		if ($variation_id) {
			$product_id = $variation_id;
		}
		if ($this->wordpress_wrapper->pixelio_wc_get_session('uuid')) {
			$uuid = $this->wordpress_wrapper->pixelio_sanitize_text_field($this->wordpress_wrapper->pixelio_wp_unslash($this->wordpress_wrapper->pixelio_wc_get_session('uuid')));
			$cart_id = $this->cart_model->pixelio_find_by_uuid($uuid);
			if (!$cart_id) {
				$cart_id = $this->cart_model->pixelio_create_new_cart(sanitize_text_field(wp_unslash($this->wordpress_wrapper->pixelio_wc_get_session('uuid'))));
			}
			$this->cart_item_model->update($cart_id, $product_id, $quantity,$quantity == 0);
		}
	}

	/**
	 * Clears the saved cart when WooCommerce cart is emptied.
	 *
	 * @return void
	 */
	public function pixelio_cart_abandon_recovery_more_cart_cleared(): void
	{
		if (isset($_POST['empty-cart'])) {
			if ($this->wordpress_wrapper->pixelio_wc_get_session('uuid')) {
				$uuid = $this->wordpress_wrapper->pixelio_sanitize_text_field($this->wordpress_wrapper->pixelio_wp_unslash($this->wordpress_wrapper->pixelio_wc_get_session('uuid')));
				$cart_id = $this->cart_model->pixelio_find_by_uuid($uuid);
				$this->cart_model->pixelio_mark_removed($cart_id);
				$this->cart_item_model->pixelio_remove_all_item_by_cart_id($cart_id);
				$this->woocommerce_wrapper->pixelio_wc_set_session('uuid', null);
			}
		}
	}

	/**
	 * Runs after checkout payment success.
	 *
	 * @param int $order_id WooCommerce order ID.
	 * @return void
	 */
	public function pixelio_cart_abandon_recovery_more_after_purchase_action($order_id): void
	{
		$service = new Pixelio_Cart_Abandon_Recovery_More_After_Purchase_Service(
			$this->woocommerce_wrapper,
			$this->pixelio_util,
			$this->cart_model,
			$this->wordpress_wrapper
		);
		$service->handle_after_purchase($order_id);
	}


	/**
	 * Displays minimal stock message before add-to-cart button.
	 *
	 * @return void
	 */
	public function pixelio_cart_abandon_recovery_more_add_stock_message_before_add_to_cart(): void
	{
		$product = $this->woocommerce_wrapper->pixelio_get_product();

		if ($product->is_in_stock() && $product->managing_stock()) {
			$stock_quantity = $product->get_stock_quantity();
			if (null !== $stock_quantity && 5 >= $stock_quantity) {
				echo $this->wordpress_wrapper->pixelio_wp_kses('<p class="pixelio-cart-abandon-recovery-more-stock-message">' . $this->wordpress_wrapper->pixelio_esc_html('Only ') . $this->wordpress_wrapper->pixelio_esc_html($stock_quantity) . $this->wordpress_wrapper->pixelio_esc_attr(' in stock left') . '</p > ', Pixelio_Cart_Abandon_Recovery_More_Util::$pixelio_cart_abandon_recovery_more_allowed_html);
			}
		}
	}

	/**
	 * Adds custom CSS class to add-to-cart buttons.
	 *
	 * @param string $link Button HTML.
	 * @param mixed $product WC product.
	 * @return string Modified HTML.
	 */
	public function pixelio_cart_abandon_recovery_more_add_to_cart_button_class($link, $product): array|string
	{
		$custom_class = 'pixelio-add-to-cart-button';
		$link = str_replace('class="button', 'class="button ' . $this->wordpress_wrapper->pixelio_esc_attr($custom_class) . '"', $link);
		return $link;
	}

	/**
	 * Triggered when cart item is removed.
	 *
	 * @param string $cart_item_key Cart item key.
	 * @param mixed $cart Cart object.
	 * @return void
	 */
	public function pixelio_cart_abandon_recovery_more_cart_item_removed($cart_item_key, $cart): void
	{
		if ($this->wordpress_wrapper->pixelio_wc_get_session('uuid')) {
			$removed_item = $cart->removed_cart_contents[$cart_item_key];
			$product_id = $removed_item['product_id'];
			$variation_id = $removed_item['variation_id'] ?? 0;
			if ($variation_id) {
				$product_id = $variation_id;
			}
			$cart_id = $this->cart_model->pixelio_find_by_uuid(sanitize_text_field(wp_unslash($this->wordpress_wrapper->pixelio_wc_get_session('uuid'))));
			if (!$cart_id) {
				$cart_id = $this->cart_model->pixelio_create_new_cart(sanitize_text_field(wp_unslash($this->wordpress_wrapper->pixelio_wc_get_session('uuid'))));
			}
			$this->cart_item_model->pixelio_mark_removed($cart_id, $product_id);
		}
	}

	/**
	 * Saves cart item when added to cart.
	 *
	 * @param string $cart_item_key Item key.
	 * @param int $product_id Product ID.
	 * @param int $quantity Quantity.
	 * @param int $variation_id Variation ID.
	 * @param array $variation Variation data.
	 * @param array $cart_item_data Extra cart item data.
	 * @return void
	 */
	public function pixelio_cart_abandon_recovery_more_add_to_cart($cart_item_key, $product_id, $quantity, $variation_id, $variation, $cart_item_data): void
	{
		if ($this->wordpress_wrapper->pixelio_wc_get_session('uuid')) {
			$cart_id = $this->cart_model->pixelio_find_by_uuid(sanitize_text_field(wp_unslash($this->wordpress_wrapper->pixelio_wc_get_session('uuid'))));
			if (!$cart_id) {
				$cart_id = $this->cart_model->pixelio_create_new_cart(sanitize_text_field(wp_unslash($this->wordpress_wrapper->pixelio_wc_get_session('uuid'))), 0);
			}
			$product = wc_get_product($variation_id ?: $product_id);
			$price = $product->get_price();          // prix actuel (promo incluse)
			$this->cart_item_model->insert($cart_id, $product_id, $quantity, $price);
		}
	}
}
