<?php
/**
 * Product Engagement Tracker
 *
 * Records views, unique visits, add to cart, and checkout initiation for products.
 *
 * @package InsightPress
 */

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

class InsightPress_Product_Tracker
{
    const TABLE_NAME = 'insightpress_product_events';

    public function __construct()
    {
        add_action('init', array($this, 'maybe_create_table'));
        
        // Track Product View
        add_action('template_redirect', array($this, 'track_product_view'));
        
        // Track Add to Cart
        add_action('woocommerce_add_to_cart', array($this, 'track_add_to_cart'), 10, 6);
        
        // Track Checkout Initiated (server-side check)
        add_action('woocommerce_before_checkout_form', array($this, 'track_checkout_initiated'));
    }

    /**
     * Create DB table.
     */
    public function maybe_create_table()
    {
        global $wpdb;
        $table = $wpdb->prefix . self::TABLE_NAME;

        $charset_collate = $wpdb->get_charset_collate();
        $sql = "CREATE TABLE $table (
            id bigint(20) unsigned NOT NULL auto_increment,
            product_id bigint(20) NOT NULL,
            event_type varchar(50) NOT NULL,
            session_id varchar(255) NOT NULL,
            source varchar(100) DEFAULT 'Direct',
            country varchar(100) DEFAULT 'Unknown',
            city varchar(100) DEFAULT 'Unknown',
            device_type varchar(50) DEFAULT 'Desktop',
            browser varchar(100) DEFAULT 'Other',
            customer_type varchar(50) DEFAULT 'New',
            created_at datetime DEFAULT CURRENT_TIMESTAMP,
            PRIMARY KEY  (id),
            KEY product_event (product_id, event_type),
            KEY session_id (session_id),
            KEY created_at (created_at),
            KEY source (source),
            KEY country (country),
            KEY device_type (device_type)
        ) $charset_collate;";

        require_once ABSPATH . 'wp-admin/includes/upgrade.php';
        dbDelta($sql);
    }

    /**
     * Get current session ID.
     */
    protected function get_session_id()
    {
        if (is_user_logged_in()) {
            return 'user_' . get_current_user_id();
        }
        if (isset(WC()->session) && WC()->session->get_customer_id()) {
            return 'session_' . WC()->session->get_customer_id();
        }
        if (!session_id()) {
            @session_start();
        }
        return 'php_' . session_id();
    }

    /**
     * Detect traffic source.
     */
    protected function detect_source()
    {
        $referrer = isset($_SERVER['HTTP_REFERER']) ? $_SERVER['HTTP_REFERER'] : '';
        $host = $referrer ? parse_url($referrer, PHP_URL_HOST) : '';
        
        // Google Ads Detection
        if (isset($_GET['gclid']) || (isset($_GET['utm_source']) && strpos($_GET['utm_source'], 'google') !== false && isset($_GET['utm_medium']) && $_GET['utm_medium'] === 'cpc')) {
            return 'Google Ads';
        }

        if (empty($referrer)) {
            return 'Direct';
        }

        // Facebook Detection
        if (strpos($host, 'facebook.com') !== false || strpos($host, 'fb.me') !== false || strpos($host, 'fb.com') !== false) {
            return 'Facebook';
        }

        // Organic Search Detection
        $search_engines = array('google.com', 'bing.com', 'yahoo.com', 'duckduckgo.com', 'baidu.com');
        foreach ($search_engines as $engine) {
            if (strpos($host, $engine) !== false) {
                return 'Organic';
            }
        }

        // Social Media Fallback
        $social_sites = array('instagram.com', 't.co', 'twitter.com', 'linkedin.com', 'pinterest.com');
        foreach ($social_sites as $site) {
            if (strpos($host, $site) !== false) {
                return 'Social';
            }
        }

        // Internal referrals (same domain)
        $site_url = parse_url(get_site_url(), PHP_URL_HOST);
        if ($host === $site_url) {
            return 'Internal';
        }

        return 'Referral';
    }

    /**
     * Detect device type and browser.
     */
    protected function detect_environment()
    {
        $user_agent = isset($_SERVER['HTTP_USER_AGENT']) ? $_SERVER['HTTP_USER_AGENT'] : '';
        $data = array(
            'device'  => 'Desktop',
            'browser' => 'Other'
        );

        if (empty($user_agent)) return $data;

        // Device
        if (preg_match('/Tablet|iPad/i', $user_agent)) {
            $data['device'] = 'Tablet';
        } elseif (preg_match('/Mobi|Android|iPhone/i', $user_agent)) {
            $data['device'] = 'Mobile';
        }

        // Browser Detection (More comprehensive)
        if (preg_match('/Opera/i', $user_agent) || preg_match('/OPR/i', $user_agent)) {
            $data['browser'] = 'Opera';
        } elseif (preg_match('/Edge/i', $user_agent) || preg_match('/Edg/i', $user_agent)) {
            $data['browser'] = 'Edge';
        } elseif (preg_match('/Chrome/i', $user_agent)) {
            $data['browser'] = 'Chrome';
        } elseif (preg_match('/Safari/i', $user_agent)) {
            $data['browser'] = 'Safari';
        } elseif (preg_match('/Firefox/i', $user_agent)) {
            $data['browser'] = 'Firefox';
        } elseif (preg_match('/MSIE/i', $user_agent) || preg_match('/Trident/i', $user_agent)) {
            $data['browser'] = 'Internet Explorer';
        }

        return $data;
    }

    /**
     * Detect location.
     */
    protected function detect_location()
    {
        $data = array('country' => 'Unknown', 'city' => 'Unknown');
        
        if (!class_exists('WC_Geolocation')) return $data;
        
        $ip = WC_Geolocation::get_ip_address();

        // Handle local testing environments
        if ($ip === '127.0.0.1' || $ip === '::1' || strpos($ip, '192.168.') === 0) {
            return array('country' => 'Local Testing', 'city' => 'Localhost');
        }

        $geo = WC_Geolocation::geolocate_ip($ip);
        
        if (!empty($geo['country'])) {
            $data['country'] = $geo['country'];
        }
        
        return $data;
    }

    /**
     * Get customer type (New vs Returning).
     */
    protected function get_customer_type()
    {
        $user_id = get_current_user_id();
        if ($user_id) {
            $order_count = wc_get_customer_order_count($user_id);
            return $order_count > 0 ? 'Returning' : 'New';
        }
        
        // For guests, we could check cookies or session, but 'New' is a safe default.
        return 'New';
    }

    /**
     * Record an event.
     */
    public function record_event($product_id, $event_type)
    {
        global $wpdb;
        $table = $wpdb->prefix . self::TABLE_NAME;
        $session_id = $this->get_session_id();
        $source = $this->detect_source();
        $env = $this->detect_environment();
        $loc = $this->detect_location();
        $customer_type = $this->get_customer_type();

        $wpdb->insert(
            $table,
            array(
                'product_id'    => $product_id,
                'event_type'    => $event_type,
                'session_id'    => $session_id,
                'source'        => $source,
                'country'       => $loc['country'],
                'city'          => $loc['city'],
                'device_type'   => $env['device'],
                'browser'       => $env['browser'],
                'customer_type' => $customer_type,
                'created_at'    => current_time('mysql'),
            ),
            array('%d', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s')
        );
    }

    /**
     * Track single product view.
     */
    public function track_product_view()
    {
        if (is_product()) {
            $product_id = get_the_ID();
            $this->record_event($product_id, 'view');
        }
    }

    /**
     * Track add to cart.
     */
    public function track_add_to_cart($cart_item_key, $product_id, $quantity, $variation_id, $variation, $cart_item_data)
    {
        $id_to_record = $variation_id > 0 ? $variation_id : $product_id;
        $this->record_event($id_to_record, 'add_to_cart');
        
        // If it's a variation, also record for parent product
        if ($variation_id > 0) {
            $this->record_event($product_id, 'add_to_cart');
        }
    }

    /**
     * Track checkout initiated for all products in cart.
     */
    public function track_checkout_initiated()
    {
        if (!WC()->cart) return;

        foreach (WC()->cart->get_cart() as $cart_item) {
            $product_id = $cart_item['product_id'];
            $variation_id = $cart_item['variation_id'];
            
            $this->record_event($product_id, 'checkout_initiated');
            if ($variation_id > 0) {
                $this->record_event($variation_id, 'checkout_initiated');
            }
        }
    }

    /**
     * Return the prefixed table name.
     */
    public static function get_table_name()
    {
        global $wpdb;
        return $wpdb->prefix . self::TABLE_NAME;
    }
}
