<?php
declare(strict_types=1);
// ==================================================
// Nuclear Fancy Pants Edition™
// File: /home/ploi/automarketer-ai.com/public/wp-content/plugins/automarketer-ai/includes/class-product-view-tracker.php
// Description: Re-engagement product view tracking, cookie management, followup email dispatch - NUCLEAR+++
// Last Edited: 2026-05-16
// ==================================================

namespace AutoMarketerAI;

defined('ABSPATH') || exit;

class ProductViewTracker
{
    private const COOKIE_NAME    = 'amai_visitor';
    private const COOKIE_TTL     = 2592000; // 30 days
    private const CRON_HOOK      = 'amai_product_followup';
    private const FOLLOWUP_DELAY = 172800; // 48 hours in seconds

    // -------------------------------------------------------------------------
    // Cron interval -- registered unconditionally at plugin boot
    // -------------------------------------------------------------------------

    public static function registerInterval(): void
    {
        add_filter('cron_schedules', [self::class, 'addCronInterval']);
    }

    public static function addCronInterval(array $schedules): array
    {
        if (!isset($schedules['amai_hourly'])) {
            $schedules['amai_hourly'] = [
                'interval' => 3600,
                'display'  => 'Every hour',
            ];
        }
        return $schedules;
    }

    // -------------------------------------------------------------------------
    // Bootstrap -- only wires hooks when module is active and WC is present
    // -------------------------------------------------------------------------

    public static function init(): void
    {
        if (!self::isActive()) {
            return;
        }

        if (!self::wooCommercePresent()) {
            return;
        }

        add_action('init',               [self::class, 'maybeSetCookie']);
        add_action('wp_enqueue_scripts', [self::class, 'enqueueTracker']);

        add_action('wp_ajax_amai_track_product_view',        [self::class, 'handleTrackView']);
        add_action('wp_ajax_nopriv_amai_track_product_view', [self::class, 'handleTrackView']);

        add_action('woocommerce_checkout_order_created', [self::class, 'handleOrderCreated']);
        add_action(self::CRON_HOOK,                      [self::class, 'processFollowups']);
    }

    // -------------------------------------------------------------------------
    // Cookie
    // -------------------------------------------------------------------------

    public static function maybeSetCookie(): void
    {
        if (isset($_COOKIE[self::COOKIE_NAME]) && strlen($_COOKIE[self::COOKIE_NAME]) === 64) {
            return;
        }

        if (headers_sent()) {
            return;
        }

        $key = bin2hex(random_bytes(32));

        setcookie(
            self::COOKIE_NAME,
            $key,
            [
                'expires'  => time() + self::COOKIE_TTL,
                'path'     => '/',
                'secure'   => is_ssl(),
                'httponly' => false,
                'samesite' => 'Lax',
            ]
        );

        $_COOKIE[self::COOKIE_NAME] = $key;
    }

    private static function getSessionKey(): string
    {
        if (!isset($_COOKIE[self::COOKIE_NAME])) {
            return '';
        }

        $raw = (string) $_COOKIE[self::COOKIE_NAME];

        if (!preg_match('/^[0-9a-f]{64}$/', $raw)) {
            return '';
        }

        return $raw;
    }

    // -------------------------------------------------------------------------
    // JS tracker enqueue
    // -------------------------------------------------------------------------

    public static function enqueueTracker(): void
    {
        if (!is_product()) {
            return;
        }

        $product_id = get_the_ID();

        if (!$product_id) {
            return;
        }

        wp_enqueue_script(
            'amai-product-tracker',
            plugin_dir_url(AMAI_PLUGIN_DIR . 'automarketer-ai.php') . 'assets/js/amai-product-tracker.js',
            ['jquery'],
            AMAI_VERSION,
            true
        );

        wp_localize_script('amai-product-tracker', 'amaiTracker', [
            'ajaxurl'   => admin_url('admin-ajax.php'),
            'nonce'     => wp_create_nonce('amai_track_product_view'),
            'productId' => (string) $product_id,
        ]);
    }

    // -------------------------------------------------------------------------
    // AJAX handler -- track a product view
    // -------------------------------------------------------------------------

    public static function handleTrackView(): void
    {
        check_ajax_referer('amai_track_product_view', 'nonce');

        $product_id = isset($_POST['product_id']) ? (int) $_POST['product_id'] : 0;

        if ($product_id <= 0) {
            wp_send_json_error('invalid_product');
        }

        $session_key = self::getSessionKey();

        if ($session_key === '') {
            wp_send_json_error('no_session');
        }

        $email      = null;
        $first_name = null;

        if (is_user_logged_in()) {
            $user       = wp_get_current_user();
            $email      = $user->user_email !== '' ? $user->user_email : null;
            $first_name = $user->first_name !== '' ? $user->first_name : null;
        } elseif (function_exists('WC') && WC()->session) {
            $customer   = WC()->session->get('customer');
            $email      = !empty($customer['email']) ? sanitize_email((string) $customer['email']) : null;
            $first_name = !empty($customer['first_name']) ? sanitize_text_field((string) $customer['first_name']) : null;
        }

        global $wpdb;

        $table = $wpdb->prefix . 'amai_product_views';

        $existing = $wpdb->get_var(
            $wpdb->prepare(
                "SELECT id FROM `{$table}` WHERE session_key = %s AND product_id = %d AND purchased = 0 LIMIT 1",
                $session_key,
                $product_id
            )
        );

        if ($existing) {
            wp_send_json_success('already_tracked');
        }

        $result = $wpdb->insert(
            $table,
            [
                'session_key' => $session_key,
                'product_id'  => $product_id,
                'email'       => $email,
                'first_name'  => $first_name,
                'viewed_at'   => gmdate('Y-m-d H:i:s'),
                'purchased'   => 0,
            ],
            ['%s', '%d', '%s', '%s', '%s', '%d']
        );

        if ($result === false) {
            wp_send_json_error('db_error');
        }

        wp_send_json_success('tracked');
    }

    // -------------------------------------------------------------------------
    // Order created -- mark purchased, backfill email
    // -------------------------------------------------------------------------

    public static function handleOrderCreated(\WC_Order $order): void
    {
        $session_key = self::getSessionKey();

        if ($session_key === '') {
            return;
        }

        $product_ids = [];

        foreach ($order->get_items() as $item) {
            if ($item instanceof \WC_Order_Item_Product) {
                $pid = (int) $item->get_product_id();
                if ($pid > 0) {
                    $product_ids[] = $pid;
                }
            }
        }

        if (empty($product_ids)) {
            return;
        }

        global $wpdb;

        $table        = $wpdb->prefix . 'amai_product_views';
        $email        = sanitize_email((string) $order->get_billing_email());
        $first_name   = sanitize_text_field((string) $order->get_billing_first_name());
        $placeholders = implode(',', array_fill(0, count($product_ids), '%d'));

        $args   = array_merge([$session_key], $product_ids);
        $in_sql = $wpdb->prepare(
            "UPDATE `{$table}` SET purchased = 1 WHERE session_key = %s AND product_id IN ({$placeholders})",
            ...$args
        );

        $wpdb->query($in_sql);

        if ($email !== '') {
            $wpdb->query(
                $wpdb->prepare(
                    "UPDATE `{$table}` SET email = %s, first_name = %s WHERE session_key = %s AND email IS NULL",
                    $email,
                    $first_name !== '' ? $first_name : null,
                    $session_key
                )
            );
        }
    }

    // -------------------------------------------------------------------------
    // Cron -- send followup emails
    // -------------------------------------------------------------------------

    public static function processFollowups(): void
    {
        global $wpdb;

        $table  = $wpdb->prefix . 'amai_product_views';
        $cutoff = gmdate('Y-m-d H:i:s', time() - self::FOLLOWUP_DELAY);

        $rows = $wpdb->get_results(
            $wpdb->prepare(
                "SELECT session_key, email, first_name, GROUP_CONCAT(product_id ORDER BY viewed_at ASC) AS product_ids
                 FROM `{$table}`
                 WHERE purchased = 0
                   AND email IS NOT NULL
                   AND viewed_at < %s
                   AND followup_sent_at IS NULL
                 GROUP BY session_key, email, first_name
                 LIMIT 50",
                $cutoff
            ),
            ARRAY_A
        );

        if (empty($rows)) {
            return;
        }

        foreach ($rows as $row) {
            $email      = sanitize_email((string) $row['email']);
            $first_name = sanitize_text_field((string) ($row['first_name'] ?? ''));
            $session    = (string) $row['session_key'];

            if ($email === '') {
                continue;
            }

            $product_ids = array_filter(array_map('intval', explode(',', (string) $row['product_ids'])));

            if (empty($product_ids)) {
                continue;
            }

            $sent = self::sendFollowupEmail($email, $first_name, $product_ids);

            if (!$sent) {
                continue;
            }

            $now_sql         = gmdate('Y-m-d H:i:s');
            $id_placeholders = implode(',', array_fill(0, count($product_ids), '%d'));
            $args            = array_merge([$now_sql, $session], $product_ids);

            $wpdb->query(
                $wpdb->prepare(
                    "UPDATE `{$table}` SET followup_sent_at = %s WHERE session_key = %s AND product_id IN ({$id_placeholders}) AND followup_sent_at IS NULL",
                    ...$args
                )
            );
        }
    }

    // -------------------------------------------------------------------------
    // Email builder
    // -------------------------------------------------------------------------

    private static function sendFollowupEmail(string $email, string $first_name, array $product_ids): bool
    {
        $store_name = get_bloginfo('name');
        $greeting   = $first_name !== '' ? "Hi {$first_name}," : 'Hi there,';

        $product_rows_html = '';

        foreach ($product_ids as $pid) {
            $product = wc_get_product($pid);

            if (!$product || !$product->is_visible()) {
                continue;
            }

            $name  = esc_html($product->get_name());
            $price = wp_strip_all_tags(wc_price($product->get_price()));
            $url   = esc_url($product->get_permalink());

            $product_rows_html .= "<tr>
                <td style='padding:12px 0;border-bottom:1px solid #f0ece8;'>
                    <a href='{$url}' style='font-weight:600;color:#D97757;text-decoration:none;'>{$name}</a>
                    <span style='color:#888;margin-left:8px;'>{$price}</span>
                </td>
            </tr>";
        }

        if ($product_rows_html === '') {
            return false;
        }

        $store_url = esc_url(get_home_url());

        $html = "<!DOCTYPE html>
<html>
<head><meta charset='UTF-8'></head>
<body style='margin:0;padding:0;background:#f9fafb;font-family:DM Sans,sans-serif;'>
<table width='100%' cellpadding='0' cellspacing='0' style='background:#f9fafb;padding:40px 0;'>
<tr><td align='center'>
<table width='560' cellpadding='0' cellspacing='0' style='background:#fff;border-radius:16px;border:1.5px solid #E7DDD5;padding:40px;'>
<tr><td>
    <p style='margin:0 0 24px;font-size:16px;color:#3d3830;'>{$greeting}</p>
    <p style='margin:0 0 24px;font-size:16px;color:#3d3830;'>
        You left a few things behind. Still thinking it over? Here is what you were browsing:
    </p>
    <table width='100%' cellpadding='0' cellspacing='0'>
        {$product_rows_html}
    </table>
    <p style='margin:24px 0 0;font-size:16px;color:#3d3830;'>
        Whenever you are ready, they are waiting for you at <a href='{$store_url}' style='color:#D97757;'>{$store_name}</a>.
    </p>
    <p style='margin:40px 0 0;font-size:14px;color:#888;'>The team at {$store_name}</p>
</td></tr>
</table>
</td></tr>
</table>
</body>
</html>";

        $subject = 'Still thinking it over?';
        $headers = ['Content-Type: text/html; charset=UTF-8'];

        return wp_mail($email, $subject, $html, $headers);
    }

    // -------------------------------------------------------------------------
    // Cron management
    // -------------------------------------------------------------------------

    public static function maybeSchedule(): void
    {
        if (!self::isActive()) {
            return;
        }

        if (!wp_next_scheduled(self::CRON_HOOK)) {
            // Register interval inline -- filter may not have fired yet at activation time
            add_filter('cron_schedules', [self::class, 'addCronInterval']);
            wp_schedule_event(time(), 'amai_hourly', self::CRON_HOOK);
        }
    }

    public static function clearSchedule(): void
    {
        $timestamp = wp_next_scheduled(self::CRON_HOOK);

        if ($timestamp) {
            wp_unschedule_event($timestamp, self::CRON_HOOK);
        }
    }

    // -------------------------------------------------------------------------
    // Helpers
    // -------------------------------------------------------------------------

    public static function isActive(): bool
    {
        $active = (array) get_option('amai_active_modules', []);
        return in_array('re-engagement', $active, true);
    }

    private static function wooCommercePresent(): bool
    {
        return class_exists('WooCommerce');
    }

    // --------------------------------------------------
    // Public test entry point for SettingsPage.
    // Sends a sample re-engagement followup email to the admin.
    // --------------------------------------------------
    public static function sendTestFollowupEmail(string $to, string $firstName): void
    {
        $store_name = get_bloginfo('name');
        $store_url  = home_url('/shop');
        $html    = MarketingSite::buildReEngagementEmailHtml($firstName, $store_name, $store_url);
        $subject = 'Still thinking it over?';
        $headers = ['Content-Type: text/html; charset=UTF-8'];
        wp_mail($to, $subject, $html, $headers);
    }
}