<?php

namespace PixelioCartAbandonRecoveryMore\Frontend\Controllers;

use PixelioCartAbandonRecoveryMore\Admin\Services\Tracking\Pixelio_Cart_Abandon_Recovery_More_Event_Dto;
use PixelioCartAbandonRecoveryMore\Admin\Services\Tracking\Pixelio_Cart_Abandon_Recovery_More_Tracking_Context;
use PixelioCartAbandonRecoveryMore\Admin\Services\Tracking\Pixelio_Cart_Abandon_Recovery_More_Consent_Tracking_Strategy;
use PixelioCartAbandonRecoveryMore\Admin\Services\Tracking\Pixelio_Cart_Abandon_Recovery_More_Anonymous_Aggregate_Tracking_Strategy;
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_Session_Repository;
use PixelioCartAbandonRecoveryMore\Includes\Utils\Pixelio_Cart_Abandon_Recovery_More_Util;

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

class Pixelio_Cart_Abandon_Recovery_More_Ajax_Event_Data_Tracking_Controller
{
    private Pixelio_Cart_Abandon_Recovery_More_Wordpress_Wrapper $wordpress_wrapper;
    private Pixelio_Cart_Abandon_Recovery_More_Session_Repository $session_model;
	private Pixelio_Cart_Abandon_Recovery_More_Woocommerce_Wrapper $woocommerce_wrapper;
	private Pixelio_Cart_Abandon_Recovery_More_Util $pixelio_util;

	public function __construct($wordpress_wrapper, $woocommerce_wrapper, $pixelio_util, $session_model)
    {
        $this->wordpress_wrapper = $wordpress_wrapper;
        $this->woocommerce_wrapper = $woocommerce_wrapper;
        $this->session_model = $session_model;
        $this->pixelio_util = $pixelio_util;
    }

    public function register_hooks(): void
    {
        $this->wordpress_wrapper->pixelio_add_action('wp_ajax_pixelio_track_event_data', [$this, 'track_event_data']);
		$this->wordpress_wrapper->pixelio_add_action('wp_ajax_nopriv_pixelio_track_event_data', [$this, 'track_event_data']);
    }

    public function track_event_data(): void
    {

        if (!$this->is_valid_request()) {


			$this->wordpress_wrapper->pixelio_wp_send_json_error([
                'message' => 'Invalid tracking request.',
            ], 403);
        }

        $has_consent = $this->has_tracking_consent();

        $event = new Pixelio_Cart_Abandon_Recovery_More_Event_Dto([
            'event_type' => $this->get_event_type(),
            'uuid' => $has_consent ? $this->get_uuid() : null,
            'product_id' => $this->get_product_id(),
            'parent_product_id' => $this->get_parent_product_id(),
            'page_url' => $has_consent ? $this->get_page_url() : null,
            'page_type' => $this->get_page_type(),
            'visit_duration' => $this->get_visit_duration(),
            'scroll_percent' => $this->get_scroll_percent(),
			'tracking_mode' => $this->get_tracking_mode()
        ]);

        $context = new Pixelio_Cart_Abandon_Recovery_More_Tracking_Context(
            $has_consent
                ? new Pixelio_Cart_Abandon_Recovery_More_Consent_Tracking_Strategy($this->session_model)
                : new Pixelio_Cart_Abandon_Recovery_More_Anonymous_Aggregate_Tracking_Strategy($this->session_model)
        );
        $context->track($event);

		$this->wordpress_wrapper->pixelio_wp_send_json_success([
            'tracked' => true,
            'mode' => $has_consent ? 'consent' : 'anonymous',
        ]);
    }

    private function is_valid_request(): bool
    {

        return $this->wordpress_wrapper->pixelio_check_ajax_referer(
            'pixelio_ajax_nonce'
        );
    }
	private function has_tracking_consent(): bool
	{
		/*
		 * GDPR disabled in Rivio settings.
		 * Merchant is responsible for compliance.
		 * Rivio allows full tracking.
		 */
		if (
			!$this->pixelio_util->pixelio_cart_abandon_recovery_more_dependency_is_checked(
				'pixelio-cart-abandon-recovery-more-gdpr-consent-checkbox'
			)
		) {
			return true;
		}

		/*
		 * GDPR enabled.
		 * Explicit consent required.
		 */
		return isset($_COOKIE['pixelio_marketing_consent'])
			&& $_COOKIE['pixelio_marketing_consent'] === '1';
	}

	private function get_tracking_mode(): string
	{
		$gdprEnabled = $this->pixelio_util->pixelio_cart_abandon_recovery_more_dependency_is_checked('pixelio-cart-abandon-recovery-more-gdpr-consent-checkbox');
		if ($gdprEnabled === false) {
			return 'gdpr_disabled';
		}

		if (
			isset($_COOKIE['pixelio_marketing_consent'])
			&& $_COOKIE['pixelio_marketing_consent'] === '1'
		) {
			return 'consent_granted';
		}
		return 'anonymous';
	}

	private function get_uuid(): ?string
	{
		$uuid = $this->wordpress_wrapper->pixelio_wc_get_session('uuid');

		if (empty($uuid)) {
			return null;
		}

		return $this->wordpress_wrapper->pixelio_sanitize_text_field($uuid);
	}

    private function get_event_type(): string
    {
        $event_type = $_POST['event_type'] ?? 'page_engagement';

        $event_type = $this->wordpress_wrapper->pixelio_sanitize_key($this->wordpress_wrapper->pixelio_wp_unslash($event_type));

        $allowed_events = [
            'page_view',
            'product_view',
            'page_engagement',
            'add_to_cart',
            'cart_view',
            'checkout_view',
            'wishlist_click',
            'popup_view',
            'popup_submit',
        ];

        return in_array($event_type, $allowed_events, true)
            ? $event_type
            : 'page_engagement';
    }

    private function get_product_id(): int
    {
        return isset($_POST['product_id'])
            ? absint($_POST['product_id'])
            : 0;
    }

    private function get_parent_product_id(): int
    {
        return isset($_POST['parent_product_id'])
            ? absint($_POST['parent_product_id'])
            : 0;
    }

    private function get_page_url(): ?string
    {
        if (empty($_POST['page_url'])) {
            return null;
        }

        return $this->wordpress_wrapper->pixelio_esc_url_raw($this->wordpress_wrapper->pixelio_wp_unslash($_POST['page_url']));
    }

    private function get_page_type(): string
    {
        $page_type = $_POST['page_type'] ?? 'page';

        $page_type = $this->wordpress_wrapper->pixelio_sanitize_key($this->wordpress_wrapper->pixelio_wp_unslash($page_type));

        $allowed_page_types = [
            'page',
            'product',
            'cart',
            'checkout',
            'home',
            'shop',
        ];

        return in_array($page_type, $allowed_page_types, true)
            ? $page_type
            : 'page';
    }

    private function get_visit_duration(): int
    {
        $duration = isset($_POST['visit_duration'])
            ? absint($_POST['visit_duration'])
            : 0;

        return min($duration, 3600);
    }

    private function get_scroll_percent(): int
    {
        $scroll = isset($_POST['scroll_percent'])
            ? absint($_POST['scroll_percent'])
            : 0;

        return min($scroll, 100);
    }
}
