<?php
/**
 * ZUTALW AJAX handlers
 * Handles all background requests for the game logic, configuration, and data submission.
 * UPDATED: Added 2-Tier Anti-Fraud Logic (Device OR Phone OR Email limit check)
 */

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

class ZUTALW_Ajax {

    public function __construct() {
        add_action( 'wp_ajax_zutalw_getdataConfig', array( $this, 'ajax_getdataConfig' ) );
        add_action( 'wp_ajax_nopriv_zutalw_getdataConfig', array( $this, 'ajax_getdataConfig' ) );

        add_action( 'wp_ajax_zutalw_InsCustomer', array( $this, 'ajax_insertCustomer' ) );
        add_action( 'wp_ajax_nopriv_zutalw_InsCustomer', array( $this, 'ajax_insertCustomer' ) );

        add_action( 'wp_ajax_zutalw_popup', array( $this, 'ajax_popup' ) );
        add_action( 'wp_ajax_nopriv_zutalw_popup', array( $this, 'ajax_popup' ) );

        add_action( 'wp_ajax_zutalw_UpdateConfig', array( $this, 'ajax_updateConfig' ) );

        add_action( 'wp_ajax_zutalw_get_spin_result', array( $this, 'ajax_get_spin_result' ) );
        add_action( 'wp_ajax_nopriv_zutalw_get_spin_result', array( $this, 'ajax_get_spin_result' ) );

        add_action( 'wp_ajax_zutalw_search_posts', array( $this, 'ajax_search_posts_handler' ) );

        add_action( 'wp_ajax_zutalw_reload_admin_leads', array( $this, 'ajax_reload_leads' ) );
        add_action( 'wp_ajax_nopriv_zutalw_reload_admin_leads', array( $this, 'ajax_reload_leads' ) );

        add_action( 'wp_ajax_zutalw_reload_admin_fraud', array( $this, 'ajax_reload_fraud' ) );
        add_action( 'wp_ajax_nopriv_zutalw_reload_admin_fraud', array( $this, 'ajax_reload_fraud' ) ); 
        
        add_action( 'admin_init', array( $this, 'handle_campaign_csv_export' ) );

        add_action( 'wp_ajax_zutalw_reload_unique_leads', array( $this, 'ajax_reload_unique_leads' ) );
        add_action( 'admin_init', array( $this, 'handle_unique_csv_export' ) );
    }

    public function ajax_reload_unique_leads() {
        check_ajax_referer( 'zutalw_campaign_nonce', 'security' );
        
        global $wpdb;
        $id = isset($_POST['campaign_id']) ? intval($_POST['campaign_id']) : 0;
        
        $page = isset($_POST['page']) ? intval($_POST['page']) : 1;
        if ( $page < 1 ) $page = 1;
        $per_page = 20;
        $offset = ( $page - 1 ) * $per_page;

        $table_leads = $wpdb->prefix . 'zutalw_prize_logs';
        
        // CÂU LỆNH SQL THÔNG MINH: Lấy ID lớn nhất (mới nhất) group by Phone -> Email -> Device
        $subquery = "
            SELECT MAX(id) as max_id 
            FROM $table_leads 
            WHERE campaign_id = %d 
            GROUP BY COALESCE(NULLIF(phone, ''), NULLIF(email, ''), device_id)
        ";

        $total_items = $wpdb->get_var( $wpdb->prepare( "SELECT COUNT(DISTINCT COALESCE(NULLIF(phone, ''), NULLIF(email, ''), device_id)) FROM $table_leads WHERE campaign_id = %d", $id ) );
        $total_pages = ceil( $total_items / $per_page );

        // Join để lấy ra toàn bộ thông tin của dòng dữ liệu mới nhất
        $unique_leads = $wpdb->get_results( $wpdb->prepare( "
            SELECT t1.* FROM $table_leads t1
            INNER JOIN ($subquery) t2 ON t1.id = t2.max_id
            ORDER BY t1.id DESC LIMIT %d OFFSET %d
        ", $id, $per_page, $offset ) );

        if ( ! empty( $unique_leads ) ) {
            foreach ( $unique_leads as $lead ) {
                ?>
                <tr>
                    <td><?php echo esc_html( $lead->id ); ?></td>
                    <td><strong><?php echo esc_html( $lead->fullname ?: 'Guest' ); ?></strong></td>
                    <td><code style="font-size:11px;"><?php echo esc_html( $lead->device_id ); ?></code></td>
                    <td><?php echo esc_html( $lead->phone ); ?></td>
                    <td><?php echo esc_html( $lead->email ); ?></td>
                    <td>
                        <span class="dashicons dashicons-saved" style="color: #00a32a;"></span> 
                        <strong><?php echo esc_html( $lead->prize_name ); ?></strong>
                    </td>
                    <td style="text-wrap;">
                        <?php if ( ! empty( $lead->page_url ) ) : ?>
                            <a href="<?php echo esc_url( $lead->page_url ); ?>" target="_blank" title="<?php echo esc_attr( $lead->page_url ); ?>">
                                <span class="dashicons dashicons-admin-links"></span> View Page
                            </a>
                        <?php else : ?>
                            -
                        <?php endif; ?>
                    </td>
                    <td><?php echo esc_html( $lead->created_at ); ?></td>
                </tr>
                <?php
            }

            // Phân trang
            if ( $total_pages > 1 ) {
                echo '<tr class="zutalw-pagination-row" style="background: #f9f9f9;"><td colspan="7" style="text-align: right; padding: 10px;">';
                if ( $page > 1 ) {
                    echo '<button type="button" class="button zutalw-page-btn" data-page="1" data-target="#tab-unique-leads">&laquo; First</button> ';
                    echo '<button type="button" class="button zutalw-page-btn" data-page="'.($page - 1).'" data-target="#tab-unique-leads">&lsaquo; Prev</button> ';
                }
                echo '<span style="margin: 0 10px;">Page <strong>' . $page . '</strong> of <strong>' . $total_pages . '</strong></span>';
                if ( $page < $total_pages ) {
                    echo '<button type="button" class="button zutalw-page-btn" data-page="'.($page + 1).'" data-target="#tab-unique-leads">Next &rsaquo;</button> ';
                    echo '<button type="button" class="button zutalw-page-btn" data-page="'.$total_pages.'" data-target="#tab-unique-leads">Last &raquo;</button>';
                }
                echo '</td></tr>';
            }
        } else {
            echo '<tr><td colspan="7">No unique leads found.</td></tr>';
        }
        wp_die();
    }

    public function handle_unique_csv_export() {
        if ( ! isset( $_GET['action'] ) || $_GET['action'] !== 'zutalw_export_unique_leads' ) {
            return;
        }

        if ( ! current_user_can( 'manage_options' ) ) {
            wp_die( esc_html__( 'You do not have permission to export this data.', 'zuta-lucky-wheel' ) );
        }

        if ( ! isset( $_GET['_wpnonce'] ) || ! wp_verify_nonce( sanitize_key( wp_unslash( $_GET['_wpnonce'] ) ), 'zutalw_export_campaign_nonce' ) ) {
            wp_die( esc_html__( 'Security check failed. Please try again.', 'zuta-lucky-wheel' ) );
        }

        $campaign_id = isset( $_GET['campaign_id'] ) ? intval( $_GET['campaign_id'] ) : 0;
        if ( ! $campaign_id ) {
            wp_die( esc_html__( 'Invalid Campaign ID.', 'zuta-lucky-wheel' ) );
        }

        global $wpdb;
        $table_prize_logs = $wpdb->prefix . 'zutalw_prize_logs';

        // Lấy tất cả dữ liệu đã được lọc trùng (không LIMIT) để xuất ra Excel
        $subquery = "
            SELECT MAX(id) as max_id 
            FROM $table_prize_logs 
            WHERE campaign_id = %d 
            GROUP BY COALESCE(NULLIF(phone, ''), NULLIF(email, ''), device_id)
        ";

        $unique_leads = $wpdb->get_results( $wpdb->prepare( "
            SELECT t1.* FROM $table_prize_logs t1
            INNER JOIN ($subquery) t2 ON t1.id = t2.max_id
            ORDER BY t1.id DESC
        ", $campaign_id ) );

        if ( ob_get_length() ) { ob_end_clean(); }

        $filename = 'campaign-' . $campaign_id . '-UNIQUE-leads-' . gmdate( 'Y-m-d_H-i' ) . '.csv';

        header( 'Content-Type: text/csv; charset=utf-8' );
        header( 'Content-Disposition: attachment; filename="' . esc_attr( $filename ) . '"' );
        header( 'Pragma: no-cache' );
        header( 'Expires: 0' );
        echo "\xEF\xBB\xBF"; 

        $output = fopen( 'php://output', 'w' );
        if ( $output ) {
            fputcsv( $output, array( 'ID', 'Player Name', 'Device ID', 'Phone', 'Email', 'Latest Prize Won', 'Source URL', 'Date' ) );
            if ( ! empty( $unique_leads ) ) {
                foreach ( $unique_leads as $lead ) {
                    fputcsv( $output, array(
                        $lead->id,
                        $lead->fullname ? $lead->fullname : 'Guest',
                        $lead->device_id,
                        $lead->phone,
                        $lead->email,
                        $lead->prize_name ? $lead->prize_name : 'Unknown',
                        $lead->page_url,
                        $lead->created_at
                    ) );
                }
            }
            fclose( $output );
        }
        exit;
    }

    public function handle_campaign_csv_export() {
        if ( ! isset( $_GET['action'] ) || $_GET['action'] !== 'zutalw_export_campaign_leads' ) {
            return;
        }

        if ( ! current_user_can( 'manage_options' ) ) {
            wp_die( esc_html__( 'You do not have permission to export this data.', 'zuta-lucky-wheel' ) );
        }

        if ( ! isset( $_GET['_wpnonce'] ) || ! wp_verify_nonce( sanitize_key( wp_unslash( $_GET['_wpnonce'] ) ), 'zutalw_export_campaign_nonce' ) ) {
            wp_die( esc_html__( 'Security check failed. Please try again.', 'zuta-lucky-wheel' ) );
        }

        $campaign_id = isset( $_GET['campaign_id'] ) ? intval( $_GET['campaign_id'] ) : 0;
        if ( ! $campaign_id ) {
            wp_die( esc_html__( 'Invalid Campaign ID.', 'zuta-lucky-wheel' ) );
        }

        global $wpdb;
        
        // --- KHAI BÁO TRỰC TIẾP TÊN BẢNG TẠI ĐÂY ---
        $table_prize_logs = $wpdb->prefix . 'zutalw_prize_logs';

        $leads = $wpdb->get_results( $wpdb->prepare( "
            SELECT * FROM {$table_prize_logs} 
            WHERE campaign_id = %d 
            ORDER BY id DESC
        ", $campaign_id ) );

        if ( ob_get_length() ) {
            ob_end_clean();
        }

        $filename = 'campaign-' . $campaign_id . '-leads-' . gmdate( 'Y-m-d_H-i' ) . '.csv';

        header( 'Content-Type: text/csv; charset=utf-8' );
        header( 'Content-Disposition: attachment; filename="' . esc_attr( $filename ) . '"' );
        header( 'Pragma: no-cache' );
        header( 'Expires: 0' );

        // Thêm BOM để Excel đọc đúng tiếng Việt (English is fine too)
        echo "\xEF\xBB\xBF"; 
        
        // phpcs:ignore WordPress.WP.AlternativeFunctions.file_system_operations_fopen
        $output = fopen( 'php://output', 'w' );
        
        if ( $output ) {
            fputcsv( $output, array( 'ID', 'Player Name', 'Device ID (Fingerprint)', 'Phone', 'Email', 'Prize Won', 'Source URL', 'Date' ) );

            if ( ! empty( $leads ) ) {
                foreach ( $leads as $lead ) {
                    $player_name = $lead->fullname ? $lead->fullname : 'Guest';
                    $prize       = $lead->prize_name ? $lead->prize_name : 'Unknown';
                    
                    fputcsv( $output, array(
                        $lead->id,
                        $player_name,
                        $lead->device_id,
                        $lead->phone,
                        $lead->email,
                        $prize,
                        $lead->page_url,
                        $lead->created_at
                    ) );
                }
            }
            // phpcs:ignore WordPress.WP.AlternativeFunctions.file_system_operations_fclose
            fclose( $output );
        }
        exit;
    }

    public function ajax_reload_leads() {
        check_ajax_referer( 'zutalw_campaign_nonce', 'security' );
        
        global $wpdb;
        $id = isset($_POST['campaign_id']) ? intval($_POST['campaign_id']) : 0;
        
        // Nhận tham số page từ AJAX, mặc định là trang 1
        $page = isset($_POST['page']) ? intval($_POST['page']) : 1;
        if ( $page < 1 ) $page = 1;
        $per_page = 20;
        $offset = ( $page - 1 ) * $per_page;

        $table_leads = $wpdb->prefix . 'zutalw_prize_logs';
        
        // Đếm tổng số bản ghi để chia trang
        $total_items = $wpdb->get_var( $wpdb->prepare( "SELECT COUNT(id) FROM $table_leads WHERE campaign_id = %d", $id ) );
        $total_pages = ceil( $total_items / $per_page );

        // Query với LIMIT và OFFSET giúp cực nhẹ VPS
        $leads = $wpdb->get_results( $wpdb->prepare( 
            "SELECT * FROM $table_leads WHERE campaign_id = %d ORDER BY id DESC LIMIT %d OFFSET %d", 
            $id, $per_page, $offset 
        ) );

        if ( ! empty( $leads ) ) {
            foreach ( $leads as $lead ) {
                ?>
                <tr>
                    <td><?php echo esc_html( $lead->id ); ?></td>
                    <td><strong><?php echo esc_html( $lead->fullname ?: 'Guest' ); ?></strong></td>
                    <td><code style="font-size:11px;"><?php echo esc_html( $lead->device_id ); ?></code></td>
                    <td><?php echo esc_html( $lead->phone ); ?></td>
                    <td><?php echo esc_html( $lead->email ); ?></td>
                    <td><strong><?php echo esc_html( $lead->prize_name ); ?></strong></td>
                    <td>
                        <?php if ( ! empty( $lead->page_url ) ) : ?>
                            <a href="<?php echo esc_url( $lead->page_url ); ?>" target="_blank" title="<?php echo esc_attr( $lead->page_url ); ?>">
                                <span class="dashicons dashicons-admin-links"></span> View Page
                            </a>
                        <?php else : ?>
                            -
                        <?php endif; ?>
                    </td>
                    <td><?php echo esc_html( $lead->created_at ); ?></td>
                </tr>
                <?php
            }

            // Render thanh phân trang
            if ( $total_pages > 1 ) {
                echo '<tr class="zutalw-pagination-row" style="background: #f9f9f9;"><td colspan="8" style="text-align: right; padding: 10px;">';
                if ( $page > 1 ) {
                    echo '<button type="button" class="button zutalw-page-btn" data-page="1" data-target="#tab-leads">&laquo; First</button> ';
                    echo '<button type="button" class="button zutalw-page-btn" data-page="'.($page - 1).'" data-target="#tab-leads">&lsaquo; Prev</button> ';
                }
                echo '<span style="margin: 0 10px;">Page <strong>' . $page . '</strong> of <strong>' . $total_pages . '</strong></span>';
                if ( $page < $total_pages ) {
                    echo '<button type="button" class="button zutalw-page-btn" data-page="'.($page + 1).'" data-target="#tab-leads">Next &rsaquo;</button> ';
                    echo '<button type="button" class="button zutalw-page-btn" data-page="'.$total_pages.'" data-target="#tab-leads">Last &raquo;</button>';
                }
                echo '</td></tr>';
            }

        } else {
            echo '<tr><td colspan="7">No leads found.</td></tr>';
        }
        wp_die();
    }

    public function ajax_reload_fraud() {
        check_ajax_referer( 'zutalw_campaign_nonce', 'security' );
        
        global $wpdb;
        $id = isset($_POST['campaign_id']) ? intval($_POST['campaign_id']) : 0;
        
        $page = isset($_POST['page']) ? intval($_POST['page']) : 1;
        if ( $page < 1 ) $page = 1;
        $per_page = 20;
        $offset = ( $page - 1 ) * $per_page;

        $table_fraud = $wpdb->prefix . 'zutalw_spin_limits';

        $total_items = $wpdb->get_var( $wpdb->prepare( "SELECT COUNT(id) FROM $table_fraud WHERE campaign_id = %d", $id ) );
        $total_pages = ceil( $total_items / $per_page );

        $logs = $wpdb->get_results( $wpdb->prepare( 
            "SELECT * FROM $table_fraud WHERE campaign_id = %d ORDER BY updated_at DESC LIMIT %d OFFSET %d", 
            $id, $per_page, $offset 
        ) );

        if ( ! empty( $logs ) ) {
            foreach ( $logs as $log ) {
                $suspicious = ($log->spins_used > $log->spins_total) ? 'style="background:#fcf0f1"' : '';
                ?>
                <tr <?php echo $suspicious; ?>>
                    <td><code><?php echo esc_html( $log->device_id ); ?></code></td>
                    <td align="center"><strong><?php echo esc_html( $log->spins_total ); ?></strong></td>
                    <td align="center" style="color:red"><strong><?php echo esc_html( $log->spins_used ); ?></strong></td>
                    <td align="center" style="color:green"><strong><?php echo esc_html( $log->spins_left ); ?></strong></td>
                    <td><?php echo esc_html( $log->updated_at ); ?></td>
                </tr>
                <?php
            }

            // Render thanh phân trang
            if ( $total_pages > 1 ) {
                echo '<tr class="zutalw-pagination-row" style="background: #f9f9f9;"><td colspan="5" style="text-align: right; padding: 10px;">';
                if ( $page > 1 ) {
                    echo '<button type="button" class="button zutalw-page-btn" data-page="1" data-target="#tab-fraud">&laquo; First</button> ';
                    echo '<button type="button" class="button zutalw-page-btn" data-page="'.($page - 1).'" data-target="#tab-fraud">&lsaquo; Prev</button> ';
                }
                echo '<span style="margin: 0 10px;">Page <strong>' . $page . '</strong> of <strong>' . $total_pages . '</strong></span>';
                if ( $page < $total_pages ) {
                    echo '<button type="button" class="button zutalw-page-btn" data-page="'.($page + 1).'" data-target="#tab-fraud">Next &rsaquo;</button> ';
                    echo '<button type="button" class="button zutalw-page-btn" data-page="'.$total_pages.'" data-target="#tab-fraud">Last &raquo;</button>';
                }
                echo '</td></tr>';
            }

        } else {
            echo '<tr><td colspan="5">No fraud logs found.</td></tr>';
        }
        wp_die();
    }

    private function sanitize_recursive( $data ) {
        if ( is_array( $data ) ) {
            foreach ( $data as $key => $value ) {
                $data[ $key ] = $this->sanitize_recursive( $value );
            }
            return $data;
        } elseif ( is_string( $data ) ) {
            return sanitize_text_field( $data ); 
        } elseif ( is_int( $data ) ) {
            return intval( $data );
        } elseif ( is_float( $data ) ) {
            return floatval( $data );
        } elseif ( is_bool( $data ) ) {
            return (bool) $data;
        }
        return $data;
    }

    public function ajax_getdataConfig() {
        global $wpdb;

        $campaign_id = isset($_POST['idcampain']) ? intval($_POST['idcampain']) : 0;
        $pool_level  = isset($_POST['pool_level']) ? intval($_POST['pool_level']) : 1;
        
        $table_campaigns = $wpdb->prefix . 'zutalw_campaigns';
        $table_segments  = $wpdb->prefix . 'zutalw_segments';

        // phpcs:ignore WordPress.DB.DirectDatabaseQuery, WordPress.DB.PreparedSQL.InterpolatedNotPrepared
        $campaign = $wpdb->get_row( $wpdb->prepare( "SELECT * FROM {$table_campaigns} WHERE id = %d", $campaign_id ) );

        if ( ! $campaign ) {
            wp_send_json( array() );
        }

        // phpcs:ignore WordPress.DB.DirectDatabaseQuery
        $has_pool_col = $wpdb->get_results( "SHOW COLUMNS FROM `{$table_segments}` LIKE 'pool_level'" );
        
        if ( !empty($has_pool_col) ) {
            $segments = $wpdb->get_results( $wpdb->prepare( "SELECT * FROM {$table_segments} WHERE campaign_id = %d AND pool_level = %d ORDER BY sort_order ASC", $campaign->id, $pool_level ), ARRAY_A );
            
            // 🔥 FALLBACK: Nếu yêu cầu Pool 2 nhưng lại không có giải nào, TỰ ĐỘNG lấy Pool 1
            if ( empty($segments) && $pool_level == 2 ) {
                $pool_level = 1;
                $segments = $wpdb->get_results( $wpdb->prepare( "SELECT * FROM {$table_segments} WHERE campaign_id = %d AND pool_level = %d ORDER BY sort_order ASC", $campaign->id, $pool_level ), ARRAY_A );
            }
        } else {
            $segments = $wpdb->get_results( $wpdb->prepare( "SELECT * FROM {$table_segments} WHERE campaign_id = %d ORDER BY sort_order ASC", $campaign->id ), ARRAY_A );
        }

        $settings = json_decode( $campaign->settings, true );
        if ( ! is_array( $settings ) ) {
            $settings = array();
        }
        $design = isset( $settings['design'] ) ? $settings['design'] : array();

        $dataconfig_array = array();

        $dataconfig_array[] = array(
            'game_mode'      => 'weighted',
            'colwin'         => isset( $design['border_color'] ) ? $design['border_color'] : '#333333',
            'backgroundodd'  => '#ffffff',
            'backgroundeven' => '#cccccc',
            'colorodd'       => '#000000',
            'coloreven'      => '#000000',
            'fontsize'       => '16',
        );

       if ( $segments ) {
            foreach ( $segments as $seg ) {
                $dataconfig_array[] = array(
                    'label'       => $seg['label'],
                    'bg_color'    => $seg['bg_color'],
                    'text_color'  => $seg['text_color'],
                    'probability' => $seg['weight'],
                    'image_url'   => isset($seg['image_url']) ? $seg['image_url'] : '', // Đã bổ sung dòng này
                );
            }
        }

        $response = array(
            array(
                'idconfiggame'    => $campaign->id, 
                'nameconfig'      => $campaign->name,
                'tradein_enabled' => isset($campaign->tradein_enabled) ? intval($campaign->tradein_enabled) : 0, // Bổ sung dòng này
                'dataconfig'      => wp_json_encode( $dataconfig_array )
            )
        );

        wp_send_json( $response );
    }

    public function ajax_get_spin_result() {
        check_ajax_referer( 'zutalw-nonce', 'security' );

        $device_id   = isset($_POST['device_id']) ? sanitize_text_field( wp_unslash( $_POST['device_id'] ) ) : '';
        $campaign_id = isset($_POST['idcampain']) ? intval($_POST['idcampain']) : 0;
        $pool_level  = isset($_POST['pool_level']) ? intval($_POST['pool_level']) : 1;
        
        if ( $device_id === 'admin_preview' && current_user_can('manage_options') ) {
            wp_send_json_success( array( 'segment_id' => wp_rand(0, 7), 'label' => 'Admin Test', 'spins_left' => 9999 ) );
            return;
        }

        if ( empty( $device_id ) || $device_id === 'unknown' ) {
            wp_send_json_error( array( 'message' => esc_html__( 'Identity missing or invalid.', 'zuta-lucky-wheel' ) ) );
        }

        global $wpdb;
        $table_limits    = $wpdb->prefix . 'zutalw_spin_limits';
        $table_segments  = $wpdb->prefix . 'zutalw_segments';
        $table_campaigns = $wpdb->prefix . 'zutalw_campaigns';

        if ( $campaign_id <= 0 ) {
            wp_send_json_error( array( 'message' => esc_html__( 'Campaign not found.', 'zuta-lucky-wheel' ) ) );
        }

        // Validate Campaign Status
        $campaign = $wpdb->get_row( $wpdb->prepare( "SELECT status, end_date, settings FROM {$table_campaigns} WHERE id = %d", $campaign_id ) );
        if ( ! $campaign || (isset($campaign->status) && $campaign->status !== 'active') ) {
            wp_send_json_error( array( 'message' => esc_html__( 'This campaign is currently paused.', 'zuta-lucky-wheel' ) ) );
        }

        // CHECK SPIN LIMIT STRICTLY FROM DEVICE TABLE
        $limit_record = $wpdb->get_row( $wpdb->prepare( "SELECT id, spins_left FROM $table_limits WHERE device_id = %s AND campaign_id = %d", $device_id, $campaign_id ) );

        if ( ! $limit_record || $limit_record->spins_left <= 0 ) {
            wp_send_json_error( array( 'message' => esc_html__( 'You are out of spins!', 'zuta-lucky-wheel' ) ) );
        }

        // Prepare pool data
        $has_pool_col = $wpdb->get_results( "SHOW COLUMNS FROM `{$table_segments}` LIKE 'pool_level'" );
        if ( !empty($has_pool_col) ) {
            $segments = $wpdb->get_results( $wpdb->prepare( "SELECT * FROM {$table_segments} WHERE campaign_id = %d AND pool_level = %d ORDER BY sort_order ASC", $campaign_id, $pool_level ), ARRAY_A );
            
            // 🔥 FALLBACK: Đảm bảo vòng quay cũng tự động dùng dữ liệu Pool 1 nếu Pool 2 trống
            if ( empty($segments) && $pool_level == 2 ) {
                $pool_level = 1;
                $segments = $wpdb->get_results( $wpdb->prepare( "SELECT * FROM {$table_segments} WHERE campaign_id = %d AND pool_level = %d ORDER BY sort_order ASC", $campaign_id, $pool_level ), ARRAY_A );
            }
        } else {
            $segments = $wpdb->get_results( $wpdb->prepare( "SELECT * FROM {$table_segments} WHERE campaign_id = %d ORDER BY sort_order ASC", $campaign_id ), ARRAY_A );
        }
        
        if ( empty($segments) ) {
            wp_send_json_error( array( 'message' => esc_html__( 'No prizes found in this pool.', 'zuta-lucky-wheel' ) ) );
        }

        $config_for_calc = array();
        $config_for_calc[] = array( 'game_mode' => 'weighted' ); 
        foreach ( $segments as $seg ) {
            $config_for_calc[] = array( 'label' => $seg['label'], 'probability' => $seg['weight'] );
        }

        // Get Winning Prize
        $winner = ZUTALW_Core::get_winning_result( $config_for_calc );
        if ( ! $winner ) {
            wp_send_json_error( array( 'message' => esc_html__( 'Prize calculation error.', 'zuta-lucky-wheel' ) ) );
        }

        $segment_index_js = isset($winner['original_index']) ? intval($winner['original_index']) - 1 : 0;
        if ($segment_index_js < 0) $segment_index_js = 0;

        // DEDUCT SPIN IMMEDIATELY BASED ON DEVICE
        $wpdb->query( $wpdb->prepare( 
            "UPDATE $table_limits SET spins_left = spins_left - 1, spins_used = spins_used + 1 WHERE id = %d AND spins_left > 0", 
            $limit_record->id 
        ));

        wp_send_json_success( array(
            'segment_id' => $segment_index_js, 
            'label'      => $winner['label'],
            'spins_left' => $limit_record->spins_left - 1
        ));
    }

    public function ajax_insertCustomer() {
        check_ajax_referer( 'zutalw-nonce', 'security' );
        global $wpdb;
        
        $table_prize_logs = $wpdb->prefix . 'zutalw_prize_logs';
        $table_limits     = $wpdb->prefix . 'zutalw_spin_limits';
        $table_campaigns  = $wpdb->prefix . 'zutalw_campaigns';

        $fullname    = isset( $_POST['fullname'] ) ? sanitize_text_field( wp_unslash( $_POST['fullname'] ) ) : '';
        $phone       = isset( $_POST['phone'] ) ? sanitize_text_field( wp_unslash( $_POST['phone'] ) ) : '';
        $email       = isset( $_POST['email'] ) ? sanitize_email( wp_unslash( $_POST['email'] ) ) : '';
        $getgift     = isset( $_POST['getgift'] ) ? sanitize_text_field( wp_unslash( $_POST['getgift'] ) ) : '';
        $device_id   = isset( $_POST['device_id'] ) ? sanitize_text_field( wp_unslash( $_POST['device_id'] ) ) : '';
        $campaign_id = isset( $_POST['campaign_id'] ) ? intval( $_POST['campaign_id'] ) : 1;
        $is_trade_in = isset( $_POST['is_trade_in'] ) ? intval( $_POST['is_trade_in'] ) : 0;
        $page_url = isset($_POST['page_url']) ? esc_url_raw($_POST['page_url']) : '';

        if ( empty( $fullname ) || empty( $phone ) ) {
            wp_send_json_error( array( 'message' => esc_html__( 'Please provide your Fullname and Phone number.', 'zuta-lucky-wheel' ) ) );
        }

        if ( empty( $device_id ) || $device_id === 'unknown' ) {
            wp_send_json_error( array( 'message' => esc_html__( 'Device Identity Error.', 'zuta-lucky-wheel' ) ) );
        }

        // --- 1. GET MAX SPINS FROM CAMPAIGN ---
        $max_spins = 1;
        $campaign = $wpdb->get_row( $wpdb->prepare( "SELECT settings FROM {$table_campaigns} WHERE id = %d", $campaign_id ) );
        if ( $campaign && !empty( $campaign->settings ) ) {
            $settings = json_decode( $campaign->settings, true );
            $max_spins = isset( $settings['display']['max_spins'] ) ? intval( $settings['display']['max_spins'] ) : 1;
        }

        // --- 2. ANTI-FRAUD TIER 2 (DEVICE OR PHONE OR EMAIL) ---
        // Only enforce this limit for actual prize claims (not trade-ins)
        if ( $is_trade_in === 0 ) {
            $where_clauses = array();
            $query_args    = array( $campaign_id );

            if ( !empty( $phone ) ) {
                $where_clauses[] = "phone = %s";
                $query_args[]    = $phone;
            }
            if ( !empty( $email ) ) {
                $where_clauses[] = "email = %s";
                $query_args[]    = $email;
            }
            if ( !empty( $device_id ) ) {
                $where_clauses[] = "device_id = %s";
                $query_args[]    = $device_id;
            }

            if ( count( $where_clauses ) > 0 ) {
                $where_sql = implode( ' OR ', $where_clauses );
                
                // Count how many times this identity has CLAIMED a prize
                $check_sql = $wpdb->prepare( "
                    SELECT COUNT(id) FROM {$table_prize_logs} 
                    WHERE campaign_id = %d AND is_trade_in = 0 AND ($where_sql)
                ", $query_args );

                $used_count = $wpdb->get_var( $check_sql );

                if ( $used_count >= $max_spins ) {
                    wp_send_json_error( array(
                        'message' => esc_html__( 'This Device, Phone, or Email has reached the prize limit for this campaign!', 'zuta-lucky-wheel' )
                    ) );
                    exit;
                }
            }
        }

        // --- 3. SAVE RECORD ---
        if ( $is_trade_in === 1 ) {
            // Trade-in: INSERT LOG AND ADD +1 SPIN TO DEVICE LIMIT
            $wpdb->insert( $table_prize_logs, array(
                'campaign_id' => $campaign_id,
                'device_id'   => $device_id,
                'prize_id'    => 0, 
                'prize_name'  => 'Trade-in: ' . $getgift,
                'fullname'    => $fullname,
                'phone'       => $phone,
                'email'       => $email,
                'page_url'    => $page_url,
                'is_trade_in' => 1,
                'created_at'  => current_time('mysql')
            ));

            $wpdb->query( $wpdb->prepare(
                "UPDATE $table_limits SET spins_left = spins_left + 1 WHERE device_id = %s AND campaign_id = %d",
                $device_id, $campaign_id
            ));
            
            wp_send_json_success( array( 'message' => esc_html__( 'Trade-in granted! You have 1 extra spin.', 'zuta-lucky-wheel' ), 'is_trade_in' => 1 ) );
        } else {
            // CLAIM GIFT: INSERT INTO LOG TABLE
            $inserted = $wpdb->insert( $table_prize_logs, array(
                'campaign_id' => $campaign_id,
                'device_id'   => $device_id,
                'prize_id'    => 0,
                'prize_name'  => $getgift,
                'fullname'    => $fullname,
                'phone'       => $phone,
                'email'       => $email,
                'page_url'    => $page_url,
                'is_trade_in' => 0,
                'created_at'  => current_time('mysql')
            ));

            if ( $inserted ) {
                wp_send_json_success( array( 'message' => esc_html__( 'Information saved successfully! We will contact you soon.', 'zuta-lucky-wheel' ), 'is_trade_in' => 0 ) );
            } else {
                wp_send_json_error( array( 'message' => esc_html__( 'System error. Please try again later.', 'zuta-lucky-wheel' ) ) );
            }
        }
    }

    public function ajax_popup() {
        check_ajax_referer( 'zutalw-nonce', 'security' );
        global $wpdb;

        $gif         = isset( $_POST['name_gif'] ) ? sanitize_text_field( wp_unslash( $_POST['name_gif'] ) ) : '';
        $is_trade_in = isset( $_POST['is_trade_in'] ) ? intval( $_POST['is_trade_in'] ) : 0;
        $campaign_id = isset( $_POST['campaign_id'] ) ? intval( $_POST['campaign_id'] ) : 0;
        
        // Mặc định tiêu đề nếu chưa cấu hình
        $popup_title = esc_html__( 'Congratulations!', 'zuta-lucky-wheel' );

        // Kéo cấu hình "Game Popup Title" từ Database dựa vào ID Chiến dịch
        if ( $campaign_id > 0 ) {
            $table_campaigns = $wpdb->prefix . 'zutalw_campaigns';
            $campaign = $wpdb->get_row( $wpdb->prepare( "SELECT settings FROM {$table_campaigns} WHERE id = %d", $campaign_id ) );
            if ( $campaign && !empty( $campaign->settings ) ) {
                $settings = json_decode( $campaign->settings, true );
                if ( !empty( $settings['display']['game_title'] ) ) {
                    $popup_title = sanitize_text_field( $settings['display']['game_title'] );
                }
            }
        }
        
        ob_start();
        ?>
        <div class="zutalw-popup-form">
            <div class="zutalw-form">
                <form class="form-input">
                    <input type="hidden" name="getgift_hidden" value="<?php echo esc_attr($gif); ?>">
                    <input type="hidden" name="is_trade_in_hidden" value="<?php echo esc_attr($is_trade_in); ?>">
                    
                    <button type="button" class="btn-close" onclick="jQuery('#zutalw-popup-notify').fadeOut();">×</button>
                    <div class="form-group head-congrate">
                        <?php if ( $is_trade_in === 1 ) : ?>
                            <h4><?php echo esc_html__( 'Trade-in Offer!', 'zuta-lucky-wheel' ); ?></h4>
                            <p><?php echo esc_html__( 'Trade your current prize for 1 Extra Spin in Pool 2!', 'zuta-lucky-wheel' ); ?></p>
                        <?php else : ?>
                            <h4><?php echo esc_html( $popup_title ); ?></h4>
                            <p class="namegif"><?php echo esc_html__( 'You won:', 'zuta-lucky-wheel' ) . ' ' . esc_html( $gif ); ?></p>
                        <?php endif; ?>
                    </div>
                    <div class="form-group"><input class="fullname" placeholder="<?php echo esc_attr__( 'Your Name', 'zuta-lucky-wheel' ); ?>" required></div>
                    <div class="form-group"><input class="phone" placeholder="<?php echo esc_attr__( 'Phone Number', 'zuta-lucky-wheel' ); ?>" required></div>
                    <div class="form-group"><input class="email" placeholder="<?php echo esc_attr__( 'Email Address', 'zuta-lucky-wheel' ); ?>"></div>
                    <div class="form-group but">
                        <button type="button" id="zutalw-submit-winner-btn" class="btn btn-primary"><?php echo esc_html__( 'Submit Information', 'zuta-lucky-wheel' ); ?></button>
                    </div>
                </form>
            </div>
        </div>
        <?php
        echo ob_get_clean();
        wp_die();
    }

    public function ajax_updateConfig() {
        check_ajax_referer( 'zutalw-nonce', 'security' );

        if ( ! current_user_can( 'manage_options' ) ) {
            wp_send_json_error( esc_html__( 'You do not have permission to do this.', 'zuta-lucky-wheel' ) );
        }

        // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
        $raw_input = isset($_POST['dataconfig']) ? wp_unslash( $_POST['dataconfig'] ) : '';
        
        $raw_config = [];
        if ( is_string( $raw_input ) && !empty($raw_input) ) {
            $raw_config = json_decode( $raw_input, true );
        } elseif ( is_array( $raw_input ) ) {
            $raw_config = $raw_input;
        }

        if ( empty( $raw_config ) ) {
            wp_send_json_error( 'invalid_input' );
        }

        $sanitized_config = $this->sanitize_recursive( $raw_config );
        $license = isset( $_POST['license'] ) ? intval( $_POST['license'] ) : 0;

        if ( class_exists( 'ZUTALW_Model_ConfigGame' ) ) {
            $model = new ZUTALW_Model_ConfigGame();
            $res = $model->save_config( $sanitized_config, $license );
            
            if ( is_wp_error( $res ) ) {
                wp_send_json_error( $res->get_error_message() );
            }
            wp_send_json_success( 'ok' );
        }
        
        wp_send_json_error( 'Config Model missing.' );
    }

    public function ajax_search_posts_handler() {
        if ( ! current_user_can( 'manage_options' ) ) {
            wp_send_json_error( array( 'message' => 'Permission denied' ) );
        }

        $keyword = isset( $_POST['keyword'] ) ? sanitize_text_field( wp_unslash( $_POST['keyword'] ) ) : '';
        
        if ( empty( $keyword ) ) {
            wp_send_json_error( array( 'message' => 'Empty keyword' ) );
        }

        $args = array(
            's'              => $keyword,
            'post_type'      => array( 'page', 'post' ),
            'post_status'    => 'publish',
            'posts_per_page' => 20, 
        );

        $posts = get_posts( $args );
        $data = array();

        foreach ( $posts as $p ) {
            $type_label = ( $p->post_type === 'page' ) ? 'Page' : 'Post';
            $data[] = array(
                'id'   => $p->ID,
                'text' => '[' . $type_label . '] ' . esc_html( $p->post_title ) . ' (ID: ' . $p->ID . ')',
            );
        }

        wp_send_json_success( $data );
    }
}