<?php
/**
 * AuctionForge User Tracking
 * Tracks user IP addresses and device fingerprints on registration and login.
 * Cloudflare-aware: uses CF-Connecting-IP header when available.
 * Deduplicates: same user + same IP + same device = update last_seen + increment count.
 */

if (!defined('ABSPATH')) {
    die('You shouldnt be here');
}

function auctionforge_create_ip_log_table() {
    global $wpdb;
    $table_name = $wpdb->prefix . 'auctionforge_user_tracking';
    $charset_collate = $wpdb->get_charset_collate();

    $sql = "CREATE TABLE IF NOT EXISTS $table_name (
        id bigint(20) unsigned NOT NULL AUTO_INCREMENT,
        email varchar(255) NOT NULL DEFAULT '',
        first_name varchar(255) DEFAULT '',
        last_name varchar(255) DEFAULT '',
        ip_address varchar(45) NOT NULL DEFAULT '',
        device_id varchar(64) NOT NULL DEFAULT '',
        device_fingerprint varchar(64) NOT NULL DEFAULT '',
        gpu_vendor varchar(100) DEFAULT '',
        gpu_renderer varchar(255) DEFAULT '',
        canvas_hash varchar(64) DEFAULT '',
        audio_hash varchar(64) DEFAULT '',
        screen_res varchar(50) DEFAULT '',
        hardware_cores int unsigned DEFAULT 0,
        math_hash varchar(64) DEFAULT '',
        webrtc_ips varchar(255) DEFAULT '',
        media_devices varchar(100) DEFAULT '',
        voices_hash varchar(64) DEFAULT '',
        battery_info varchar(50) DEFAULT '',
        connection_type varchar(50) DEFAULT '',
        color_profile varchar(50) DEFAULT '',
        accessibility varchar(100) DEFAULT '',
        form_fill_ms int unsigned DEFAULT 0,
        user_agent text DEFAULT '',
        first_seen datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
        last_seen datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
        event_count int unsigned NOT NULL DEFAULT 1,
        last_event_type varchar(20) NOT NULL DEFAULT 'register',
        PRIMARY KEY (id),
        UNIQUE KEY idx_email_ip_device (email, ip_address, device_id),
        KEY idx_email (email),
        KEY idx_ip_address (ip_address),
        KEY idx_device_id (device_id),
        KEY idx_device_fingerprint (device_fingerprint),
        KEY idx_last_seen (last_seen)
    ) $charset_collate;";

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

function auctionforge_get_client_ip() {
    if (!empty($_SERVER['HTTP_CF_CONNECTING_IP'])) {
        return sanitize_text_field($_SERVER['HTTP_CF_CONNECTING_IP']);
    }
    if (!empty($_SERVER['HTTP_X_FORWARDED_FOR'])) {
        $ips = explode(',', $_SERVER['HTTP_X_FORWARDED_FOR']);
        return sanitize_text_field(trim($ips[0]));
    }
    if (!empty($_SERVER['HTTP_X_REAL_IP'])) {
        return sanitize_text_field($_SERVER['HTTP_X_REAL_IP']);
    }
    return sanitize_text_field(isset($_SERVER['REMOTE_ADDR']) ? $_SERVER['REMOTE_ADDR'] : '0.0.0.0');
}

/**
 * AJAX handler: log a tracking event (registration or login)
 * Deduplicates by (email, ip_address, device_id)
 */
function auctionforge_ajax_log_ip() {
    check_ajax_referer('auctionforge_ip_log', 'nonce');

    global $wpdb;
    $table_name = $wpdb->prefix . 'auctionforge_user_tracking';

    $ip = auctionforge_get_client_ip();
    $first_name = sanitize_text_field(isset($_POST['first_name']) ? $_POST['first_name'] : '');
    $last_name = sanitize_text_field(isset($_POST['last_name']) ? $_POST['last_name'] : '');
    $email = sanitize_email(isset($_POST['email']) ? $_POST['email'] : '');
    $event_type = sanitize_text_field(isset($_POST['event_type']) ? $_POST['event_type'] : 'register');
    $device_id = sanitize_text_field(isset($_POST['device_id']) ? $_POST['device_id'] : '');
    $device_fingerprint = sanitize_text_field(isset($_POST['device_fingerprint']) ? $_POST['device_fingerprint'] : '');
    
    // Advanced Fingerprint Metrics — Tier 1
    $gpu_vendor = sanitize_text_field(isset($_POST['gpu_vendor']) ? $_POST['gpu_vendor'] : '');
    $gpu_renderer = sanitize_text_field(isset($_POST['gpu_renderer']) ? $_POST['gpu_renderer'] : '');
    $canvas_hash = sanitize_text_field(isset($_POST['canvas_hash']) ? $_POST['canvas_hash'] : '');
    $audio_hash = sanitize_text_field(isset($_POST['audio_hash']) ? $_POST['audio_hash'] : '');
    $screen_res = sanitize_text_field(isset($_POST['screen_res']) ? $_POST['screen_res'] : '');
    $hardware_cores = intval(isset($_POST['hardware_cores']) ? $_POST['hardware_cores'] : 0);
    
    // Advanced Fingerprint Metrics — Tier 2
    $math_hash = sanitize_text_field(isset($_POST['math_hash']) ? $_POST['math_hash'] : '');
    $webrtc_ips = sanitize_text_field(isset($_POST['webrtc_ips']) ? $_POST['webrtc_ips'] : '');
    $media_devices = sanitize_text_field(isset($_POST['media_devices']) ? $_POST['media_devices'] : '');
    $voices_hash = sanitize_text_field(isset($_POST['voices_hash']) ? $_POST['voices_hash'] : '');
    $battery_info = sanitize_text_field(isset($_POST['battery_info']) ? $_POST['battery_info'] : '');
    $connection_type = sanitize_text_field(isset($_POST['connection_type']) ? $_POST['connection_type'] : '');
    $color_profile = sanitize_text_field(isset($_POST['color_profile']) ? $_POST['color_profile'] : '');
    $accessibility = sanitize_text_field(isset($_POST['accessibility']) ? $_POST['accessibility'] : '');
    $form_fill_ms = intval(isset($_POST['form_fill_ms']) ? $_POST['form_fill_ms'] : 0);
    
    $user_agent = sanitize_text_field(isset($_SERVER['HTTP_USER_AGENT']) ? $_SERVER['HTTP_USER_AGENT'] : '');

    if (!in_array($event_type, array('register', 'login'))) {
        $event_type = 'register';
    }

    if (empty($email)) {
        wp_send_json_error('No email provided');
        return;
    }

    $now = current_time('mysql');

    // INSERT or UPDATE on duplicate (same email + ip + device)
    $sql = $wpdb->prepare(
        "INSERT INTO $table_name (email, first_name, last_name, ip_address, device_id, device_fingerprint, gpu_vendor, gpu_renderer, canvas_hash, audio_hash, screen_res, hardware_cores, math_hash, webrtc_ips, media_devices, voices_hash, battery_info, connection_type, color_profile, accessibility, form_fill_ms, user_agent, first_seen, last_seen, event_count, last_event_type)
         VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %d, %s, %s, %s, %s, %s, %s, %s, %s, %d, %s, %s, %s, 1, %s)
         ON DUPLICATE KEY UPDATE
            first_name = VALUES(first_name),
            last_name = VALUES(last_name),
            device_fingerprint = VALUES(device_fingerprint),
            gpu_vendor = VALUES(gpu_vendor),
            gpu_renderer = VALUES(gpu_renderer),
            canvas_hash = VALUES(canvas_hash),
            audio_hash = VALUES(audio_hash),
            screen_res = VALUES(screen_res),
            hardware_cores = VALUES(hardware_cores),
            math_hash = VALUES(math_hash),
            webrtc_ips = VALUES(webrtc_ips),
            media_devices = VALUES(media_devices),
            voices_hash = VALUES(voices_hash),
            battery_info = VALUES(battery_info),
            connection_type = VALUES(connection_type),
            color_profile = VALUES(color_profile),
            accessibility = VALUES(accessibility),
            form_fill_ms = VALUES(form_fill_ms),
            user_agent = VALUES(user_agent),
            last_seen = VALUES(last_seen),
            event_count = event_count + 1,
            last_event_type = VALUES(last_event_type)",
        $email, $first_name, $last_name, $ip, $device_id, $device_fingerprint, $gpu_vendor, $gpu_renderer, $canvas_hash, $audio_hash, $screen_res, $hardware_cores, $math_hash, $webrtc_ips, $media_devices, $voices_hash, $battery_info, $connection_type, $color_profile, $accessibility, $form_fill_ms, $user_agent, $now, $now, $event_type
    );

    $wpdb->query($sql);

    wp_send_json_success(array('logged' => true));
}

/**
 * AJAX handler: search tracking logs (admin only)
 */
function auctionforge_ajax_search_ip_logs() {
    check_ajax_referer('auctionforge_admin', 'nonce');
    if (!current_user_can('manage_options')) {
        wp_send_json_error('Unauthorized');
        return;
    }

    global $wpdb;
    $table_name = $wpdb->prefix . 'auctionforge_user_tracking';

    $search = sanitize_text_field(isset($_POST['search']) ? $_POST['search'] : '');
    $per_page = intval(isset($_POST['per_page']) ? $_POST['per_page'] : 50);
    $page = intval(isset($_POST['page']) ? $_POST['page'] : 1);
    $offset = ($page - 1) * $per_page;

    $where = array();
    $params = array();

    if (!empty($search)) {
        $like = '%' . $wpdb->esc_like($search) . '%';
        $where[] = "(ip_address LIKE %s OR first_name LIKE %s OR last_name LIKE %s OR email LIKE %s OR device_id LIKE %s OR device_fingerprint LIKE %s)";
        $params[] = $like;
        $params[] = $like;
        $params[] = $like;
        $params[] = $like;
        $params[] = $like;
        $params[] = $like;
    }

    $where_sql = !empty($where) ? 'WHERE ' . implode(' AND ', $where) : '';

    $count_sql = "SELECT COUNT(*) FROM $table_name $where_sql";
    if (!empty($params)) {
        $total = $wpdb->get_var($wpdb->prepare($count_sql, $params));
    } else {
        $total = $wpdb->get_var($count_sql);
    }

    $query = "SELECT * FROM $table_name $where_sql ORDER BY last_seen DESC LIMIT %d OFFSET %d";
    $all_params = array_merge($params, array($per_page, $offset));
    $results = $wpdb->get_results($wpdb->prepare($query, $all_params), ARRAY_A);

    // Find shared devices/IPs — flag entries where device_id or device_fingerprint matches other emails
    $flagged = array();
    foreach ($results as $row) {
        if (!empty($row['device_id'])) {
            $shared_device = $wpdb->get_var($wpdb->prepare(
                "SELECT COUNT(DISTINCT email) FROM $table_name WHERE device_id = %s",
                $row['device_id']
            ));
            if ($shared_device > 1) {
                $flagged[$row['id']]['shared_device'] = intval($shared_device);
            }
        }
        if (!empty($row['device_fingerprint'])) {
            $shared_fp = $wpdb->get_var($wpdb->prepare(
                "SELECT COUNT(DISTINCT email) FROM $table_name WHERE device_fingerprint = %s",
                $row['device_fingerprint']
            ));
            if ($shared_fp > 1) {
                $flagged[$row['id']]['shared_fingerprint'] = intval($shared_fp);
            }
        }
    }

    wp_send_json_success(array(
        'results'  => $results,
        'flagged'  => $flagged,
        'total'    => intval($total),
        'page'     => $page,
        'per_page' => $per_page,
        'pages'    => ceil(intval($total) / max($per_page, 1)),
    ));
}

/**
 * AJAX handler: look up all accounts linked to a device or IP
 */
function auctionforge_ajax_lookup_linked() {
    check_ajax_referer('auctionforge_admin', 'nonce');
    if (!current_user_can('manage_options')) {
        wp_send_json_error('Unauthorized');
        return;
    }

    global $wpdb;
    $table_name = $wpdb->prefix . 'auctionforge_user_tracking';

    $type = sanitize_text_field(isset($_POST['type']) ? $_POST['type'] : '');
    $value = sanitize_text_field(isset($_POST['value']) ? $_POST['value'] : '');

    if (empty($value)) {
        wp_send_json_error('No value provided');
        return;
    }

    $allowed = array('device_id', 'device_fingerprint', 'ip_address');
    if (!in_array($type, $allowed)) {
        wp_send_json_error('Invalid lookup type');
        return;
    }

    $results = $wpdb->get_results($wpdb->prepare(
        "SELECT * FROM $table_name WHERE $type = %s ORDER BY last_seen DESC",
        $value
    ), ARRAY_A);

    wp_send_json_success(array('results' => $results));
}

/**
 * AJAX handler: export as CSV (admin only)
 */
function auctionforge_ajax_export_ip_logs() {
    check_ajax_referer('auctionforge_admin', 'nonce');
    if (!current_user_can('manage_options')) {
        wp_die('Unauthorized');
    }

    global $wpdb;
    $table_name = $wpdb->prefix . 'auctionforge_user_tracking';

    $search = sanitize_text_field(isset($_GET['search']) ? $_GET['search'] : '');

    $where = array();
    $params = array();

    if (!empty($search)) {
        $like = '%' . $wpdb->esc_like($search) . '%';
        $where[] = "(ip_address LIKE %s OR first_name LIKE %s OR last_name LIKE %s OR email LIKE %s OR device_id LIKE %s OR device_fingerprint LIKE %s)";
        $params = array($like, $like, $like, $like, $like, $like);
    }

    $where_sql = !empty($where) ? 'WHERE ' . implode(' AND ', $where) : '';
    $query = "SELECT * FROM $table_name $where_sql ORDER BY last_seen DESC";

    if (!empty($params)) {
        $results = $wpdb->get_results($wpdb->prepare($query, $params), ARRAY_A);
    } else {
        $results = $wpdb->get_results($query, ARRAY_A);
    }

    header('Content-Type: text/csv');
    header('Content-Disposition: attachment; filename="user-tracking-' . date('Y-m-d') . '.csv"');

    $output = fopen('php://output', 'w');
    fputcsv($output, array('ID', 'Email', 'First Name', 'Last Name', 'IP Address', 'Device ID', 'Fingerprint', 'GPU Vendor', 'GPU Renderer', 'Canvas Hash', 'Audio Hash', 'Screen Res', 'Cores', 'Math Hash', 'WebRTC IPs', 'Media Devices', 'Voices Hash', 'Battery', 'Connection', 'Color Profile', 'Accessibility', 'Form Fill (ms)', 'User Agent', 'First Seen', 'Last Seen', 'Event Count', 'Last Event'));

    foreach ($results as $row) {
        fputcsv($output, array(
            $row['id'], $row['email'], $row['first_name'], $row['last_name'],
            $row['ip_address'], $row['device_id'], $row['device_fingerprint'],
            $row['gpu_vendor'], $row['gpu_renderer'], $row['canvas_hash'], 
            $row['audio_hash'], $row['screen_res'], $row['hardware_cores'],
            isset($row['math_hash']) ? $row['math_hash'] : '',
            isset($row['webrtc_ips']) ? $row['webrtc_ips'] : '',
            isset($row['media_devices']) ? $row['media_devices'] : '',
            isset($row['voices_hash']) ? $row['voices_hash'] : '',
            isset($row['battery_info']) ? $row['battery_info'] : '',
            isset($row['connection_type']) ? $row['connection_type'] : '',
            isset($row['color_profile']) ? $row['color_profile'] : '',
            isset($row['accessibility']) ? $row['accessibility'] : '',
            isset($row['form_fill_ms']) ? $row['form_fill_ms'] : 0,
            $row['user_agent'], $row['first_seen'], $row['last_seen'],
            $row['event_count'], $row['last_event_type'],
        ));
    }

    fclose($output);
    exit;
}

function auctionforge_register_ip_log_page() {
    add_submenu_page(
        'edit.php?post_type=lot',
        __('User Tracking', 'auctionforge'),
        __('User Tracking', 'auctionforge'),
        'manage_options',
        'auctionforge-ip-log',
        'auctionforge_render_ip_log_page'
    );
}

function auctionforge_render_ip_log_page() {
    require_once plugin_dir_path(dirname(__FILE__)) . 'admin/view/ip-log.php';
}
