<?php
session_start();
header('Content-Type: application/json; charset=UTF-8');
include __DIR__ . '/../config.php';

// Use the correct database variable name from config.php
$pdo = $db; // config.php uses $db, but our code expects $pdo
$VERITRAL_API_KEY = isset($VERITRAL_API_KEY) ? $VERITRAL_API_KEY : getenv('VERITRAL_API_KEY');
$VERITRAL_API_SECRET = isset($VERITRAL_API_SECRET) ? $VERITRAL_API_SECRET : getenv('VERITRAL_API_SECRET');
try { $pdo->exec("ALTER TABLE bonus_types ADD COLUMN wagering_requirement DECIMAL(10,2) NOT NULL DEFAULT 0"); } catch (PDOException $e) {}
try { $pdo->exec("ALTER TABLE personalized_bonuses ADD COLUMN wagering_requirement DECIMAL(10,2) NOT NULL DEFAULT 0"); } catch (PDOException $e) {}
try { $pdo->exec("ALTER TABLE bonus_talepleri ADD COLUMN wagering_requirement DECIMAL(10,2) NOT NULL DEFAULT 0"); } catch (PDOException $e) {}
try { $pdo->exec("ALTER TABLE bonus_types ADD COLUMN no_wagering TINYINT(1) NOT NULL DEFAULT 0"); } catch (PDOException $e) {}
try { $pdo->exec("ALTER TABLE personalized_bonuses ADD COLUMN no_wagering TINYINT(1) NOT NULL DEFAULT 0"); } catch (PDOException $e) {}
try { $pdo->exec("ALTER TABLE bonus_talepleri ADD COLUMN no_wagering TINYINT(1) NOT NULL DEFAULT 0"); } catch (PDOException $e) {}

// Debug için: PDO değişkeninin varlığını kontrol et
if (!isset($pdo)) {
    error_log("PDO not set after config include");
    echo json_encode(['success' => false, 'message' => 'Database connection error: PDO not initialized']);
    exit;
}

// CORS headers
header("Access-Control-Allow-Origin: *");
header("Access-Control-Allow-Methods: GET, POST, PUT, DELETE, OPTIONS");
header("Access-Control-Allow-Headers: Content-Type, Authorization");

if ($_SERVER['REQUEST_METHOD'] === 'OPTIONS') {
    exit(0);
}

// Oturum anahtar adları için uyumluluk ve admin/user fallback
if (!isset($_SESSION['user_id']) && isset($_SESSION['users_id'])) {
    $_SESSION['user_id'] = $_SESSION['users_id'];
}
if (!isset($_SESSION['admin_id']) && isset($_SESSION['user_id'])) {
    $_SESSION['admin_id'] = $_SESSION['user_id'];
}

$action = $_GET['action'] ?? '';
// Admin dışı işlemler için kullanıcı oturumu gerekli
if (strpos($action, 'admin_') !== 0 && !isset($_SESSION['user_id'])) {
    echo json_encode(['success' => false, 'message' => 'Oturum bulunamadı']);
    exit;
}

$user_id = $_SESSION['user_id'] ?? null;
if (!$user_id && isset($_SESSION['username'])) {
    try {
        $stmt = $pdo->prepare("SELECT id FROM kullanicilar WHERE username = ? LIMIT 1");
        $stmt->execute([$_SESSION['username']]);
        $row = $stmt->fetch(PDO::FETCH_ASSOC);
        if ($row && isset($row['id'])) { $_SESSION['user_id'] = intval($row['id']); $user_id = $_SESSION['user_id']; }
    } catch (PDOException $e) {}
}

    try {
        switch ($action) {
        case 'get_available_bonuses':
            getAvailableBonuses($pdo, $user_id);
            break;
        case 'calculate_personalized_bonus':
            calculatePersonalizedBonus($pdo, $user_id);
            break;
        case 'claim_bonus':
            claimBonus($pdo, $user_id);
            break;
        case 'get_bonus_history':
            getBonusHistory($pdo, $user_id);
            break;
        case 'get_bonus_requests':
            $stmt = $pdo->prepare("SELECT id, uye_id AS user_id, bonus_turu AS bonus_name, miktar AS amount, tarih AS created_at, durum FROM bonus_talepleri WHERE uye_id = ? ORDER BY tarih DESC LIMIT 100");
            $stmt->execute([$user_id]);
            $requests = $stmt->fetchAll(PDO::FETCH_ASSOC);
            echo json_encode(['success' => true, 'requests' => $requests]);
            break;
        case 'update_user_behavior':
            updateUserBehavior($pdo, $user_id);
            break;
        case 'admin_get_bonuses':
        if (!isset($_SESSION['admin_id'])) {
            echo json_encode(['success' => false, 'message' => 'Yetkisiz erişim']);
            exit;
        }
        
        $status = $_GET['status'] ?? '';
        
        // Debug için log - hem error_log hem de response'a ekle
        error_log("admin_get_bonuses called with status: " . $status);
        
        // Session debug bilgisi
        $debug_info = [
            'session_admin_id' => $_SESSION['admin_id'] ?? 'not_set',
            'status_param' => $status,
            'request_time' => date('Y-m-d H:i:s'),
            'pdo_exists' => isset($pdo) ? 'yes' : 'no'
        ];
        
        // Check if database connection exists
        if (!isset($pdo)) {
            echo json_encode(['success' => false, 'message' => 'Database connection not found', 'debug' => $debug_info]);
            exit;
        }
        
        // Birleşik bonus sistemi - hem personalized_bonuses hem de bonus_talepleri tablolarını birleştir
        // Önce her iki tablodan da veri çekelim, sonra birleştirelim
        $sql = "(SELECT 
                    pb.id, 
                    pb.user_id, 
                    k.username, 
                    bt.name as bonus_name, 
                    pb.amount, 
                    pb.status, 
                    pb.created_at,
                    'personalized' as source_type,
                    pb.bonus_type_id,
                    NULL as request_status
                FROM personalized_bonuses pb 
                LEFT JOIN kullanicilar k ON pb.user_id = k.id 
                LEFT JOIN bonus_types bt ON pb.bonus_type_id = bt.id";
        
        if ($status && !in_array($status, ['pending', 'approved', 'rejected'])) {
            $sql .= " WHERE pb.status = ?";
        }
        
        $sql .= ")
                UNION ALL
                (SELECT 
                    btalep.id, 
                    btalep.uye_id as user_id, 
                    k.username, 
                    btalep.bonus_turu as bonus_name, 
                    btalep.miktar as amount, 
                    CASE btalep.durum 
                        WHEN 0 THEN 'pending' 
                        WHEN 1 THEN 'approved' 
                        WHEN 2 THEN 'rejected' 
                    END as status, 
                    btalep.tarih as created_at,
                    'request' as source_type,
                    NULL as bonus_type_id,
                    btalep.durum as request_status
                FROM bonus_talepleri btalep
                LEFT JOIN kullanicilar k ON btalep.uye_id = k.id";
        
        if ($status && in_array($status, ['pending', 'approved', 'rejected'])) {
            $statusMap = [
                'pending' => 0,
                'approved' => 1, 
                'rejected' => 2
            ];
            $sql .= " WHERE btalep.durum = " . $statusMap[$status];
        } else if ($status && !in_array($status, ['pending', 'approved', 'rejected'])) {
            $sql .= " WHERE 1=0"; // Sadece personalized_bonuses için filtre
        }
        
        $sql .= ") ORDER BY created_at DESC LIMIT 100";
        
        // Parametreleri hazırla
        $params = [];
        
        // Orijinal UNION sorgusunu başlangıçta oluştur
        $fullUnionSql = "(SELECT 
                    pb.id, 
                    pb.user_id, 
                    k.username, 
                    bt.name as bonus_name, 
                    pb.amount, 
                    pb.status, 
                    pb.created_at,
                    'personalized' as source_type,
                    pb.bonus_type_id,
                    NULL as request_status
                FROM personalized_bonuses pb 
                LEFT JOIN kullanicilar k ON pb.user_id = k.id 
                LEFT JOIN bonus_types bt ON pb.bonus_type_id = bt.id";
        
        if ($status && !in_array($status, ['pending', 'approved', 'rejected'])) {
            $fullUnionSql .= " WHERE pb.status = ?";
            $params[] = $status;
        }
        
        $fullUnionSql .= ")
                UNION ALL
                (SELECT 
                    btalep.id, 
                    btalep.uye_id as user_id, 
                    k.username, 
                    btalep.bonus_turu as bonus_name, 
                    btalep.miktar as amount, 
                    CASE btalep.durum 
                        WHEN 0 THEN 'pending' 
                        WHEN 1 THEN 'approved' 
                        WHEN 2 THEN 'rejected' 
                    END as status, 
                    btalep.tarih as created_at,
                    'request' as source_type,
                    NULL as bonus_type_id,
                    btalep.durum as request_status
                FROM bonus_talepleri btalep
                LEFT JOIN kullanicilar k ON btalep.uye_id = k.id";
        
        if ($status && in_array($status, ['pending', 'approved', 'rejected'])) {
            $statusMap = [
                'pending' => 0,
                'approved' => 1, 
                'rejected' => 2
            ];
            $fullUnionSql .= " WHERE btalep.durum = " . $statusMap[$status];
        } else if ($status && !in_array($status, ['pending', 'approved', 'rejected'])) {
            // Sadece personalized için zaten WHERE eklendi, şimdi bonus_talepleri için de filtre
            $fullUnionSql .= " WHERE 1=0"; // Bu durumda bonus_talepleri'ni hariç tut
        }
        
        $fullUnionSql .= ") ORDER BY created_at DESC LIMIT 100";
        
        if ($status) {
            if (in_array($status, ['pending', 'approved', 'rejected'])) {
                // Sadece talep bonusları için filtreleme
                $statusMap = [
                    'pending' => 0,
                    'approved' => 1, 
                    'rejected' => 2
                ];
                $durumValue = $statusMap[$status];
                
                $sql = "(SELECT 
                    btalep.id, 
                    btalep.uye_id as user_id, 
                    k.username, 
                    btalep.bonus_turu as bonus_name, 
                    btalep.miktar as amount, 
                    CASE btalep.durum 
                        WHEN 0 THEN 'pending' 
                        WHEN 1 THEN 'approved' 
                        WHEN 2 THEN 'rejected' 
                    END as status, 
                    btalep.tarih as created_at,
                    'request' as source_type,
                    NULL as bonus_type_id,
                    btalep.durum as request_status
                FROM bonus_talepleri btalep
                LEFT JOIN kullanicilar k ON btalep.uye_id = k.id
                WHERE btalep.durum = ?)
                ORDER BY created_at DESC LIMIT 100";
                
                $params[] = $durumValue;
            } else {
                // Sadece personalized_bonuses için filtreleme
                $sql = "(SELECT 
                    pb.id, 
                    pb.user_id, 
                    k.username, 
                    bt.name as bonus_name, 
                    pb.amount, 
                    pb.status, 
                    pb.created_at,
                    'personalized' as source_type,
                    pb.bonus_type_id,
                    NULL as request_status
                FROM personalized_bonuses pb 
                LEFT JOIN kullanicilar k ON pb.user_id = k.id 
                LEFT JOIN bonus_types bt ON pb.bonus_type_id = bt.id";
                
                if ($status) {
                    $sql .= " WHERE pb.status = ?";
                    $params[] = $status;
                }
                
                $sql .= " ORDER BY created_at DESC LIMIT 100";
            }
        } else {
            // Tüm bonusları göster
            $sql = $fullUnionSql;
        }
        
        try {
            $stmt = $pdo->prepare($sql);
            $stmt->execute($params);
            $bonuses = $stmt->fetchAll(PDO::FETCH_ASSOC);
            
            // Debug için log
            error_log("SQL Query executed successfully. Row count: " . count($bonuses));
            if (count($bonuses) > 0) {
                error_log("First bonus: " . json_encode($bonuses[0]));
            }
            
            $debug_info['sql_executed'] = true;
            $debug_info['row_count'] = count($bonuses);
            
            echo json_encode(['success' => true, 'bonuses' => $bonuses, 'debug' => $debug_info]);
        } catch (PDOException $e) {
            error_log("SQL Error: " . $e->getMessage());
            $debug_info['sql_error'] = $e->getMessage();
            echo json_encode(['success' => false, 'message' => 'Database error: ' . $e->getMessage(), 'debug' => $debug_info]);
        }
        break;

        case 'get_bonus_details':
        if (!isset($_SESSION['admin_id'])) {
            echo json_encode(['success' => false, 'message' => 'Yetkisiz erişim']);
            exit;
        }
        
        $bonusId = intval($_GET['id'] ?? 0);
        $sourceType = $_GET['source_type'] ?? '';
        
        if ($bonusId <= 0) {
            echo json_encode(['success' => false, 'message' => 'Geçerli bonus ID gerekli']);
            exit;
        }
        
        try {
            if ($sourceType === 'personalized') {
                $stmt = $pdo->prepare("SELECT pb.*, k.username, bt.name as bonus_name, bt.wagering_requirement 
                                      FROM personalized_bonuses pb 
                                      LEFT JOIN kullanicilar k ON pb.user_id = k.id 
                                      LEFT JOIN bonus_types bt ON pb.bonus_type_id = bt.id 
                                      WHERE pb.id = ?");
                $stmt->execute([$bonusId]);
            } else if ($sourceType === 'request') {
                $stmt = $pdo->prepare("SELECT btalep.id, btalep.uye_id as user_id, k.username, 
                                      btalep.bonus_turu as bonus_name, btalep.miktar as amount, 
                                      btalep.tarih as created_at, btalep.durum, btalep.wagering_requirement,
                                      CASE btalep.durum 
                                          WHEN 0 THEN 'pending' 
                                          WHEN 1 THEN 'approved' 
                                          WHEN 2 THEN 'rejected' 
                                      END as status,
                                      'request' as source_type
                                      FROM bonus_talepleri btalep
                                      LEFT JOIN kullanicilar k ON btalep.uye_id = k.id 
                                      WHERE btalep.id = ?");
                $stmt->execute([$bonusId]);
            } else {
                echo json_encode(['success' => false, 'message' => 'Geçerli kaynak türü gerekli']);
                exit;
            }
            
            $bonus = $stmt->fetch(PDO::FETCH_ASSOC);
            
            if ($bonus) {
                // Wagering compute
                $required = 0; $done = 0; $met = false; $startAt = null;
                if ($sourceType === 'personalized') {
                    $startAt = $bonus['used_at'] ?? $bonus['created_at'] ?? null;
                    $wr = floatval($bonus['wagering_requirement'] ?? 0);
                    $required = round(floatval($bonus['amount']) * $wr, 2);
                } else {
                    $wr = floatval($bonus['wagering_requirement'] ?? 0);
                    $required = round(floatval($bonus['amount']) * $wr, 2);
                    $startAt = $bonus['created_at'] ?? null;
                }
                if ($startAt) {
                    try {
                        $stmt3 = $pdo->prepare("SELECT COALESCE(SUM(amount),0) AS total FROM transactions WHERE user_id = ? AND type = 'bet' AND created_at >= ?");
                        $stmt3->execute([intval($bonus['user_id']), $startAt]);
                        $row3 = $stmt3->fetch(PDO::FETCH_ASSOC);
                        $done = round(floatval($row3['total'] ?? 0), 2);
                    } catch (PDOException $e) {}
                }
                $met = $required > 0 ? ($done >= $required) : true;
                $bonus['wagering_required'] = $required;
                $bonus['wagering_done'] = $done;
                $bonus['wagering_met'] = $met;
                echo json_encode(['success' => true, 'bonus' => $bonus]);
            } else {
                echo json_encode(['success' => false, 'message' => 'Bonus bulunamadı']);
            }
        } catch (Exception $e) {
            echo json_encode(['success' => false, 'message' => $e->getMessage()]);
        }
        break;

        case 'admin_get_bonus_requests':
        if (!isset($_SESSION['admin_id'])) {
            echo json_encode(['success' => false, 'message' => 'Yetkisiz erişim']);
            exit;
        }

        $status = $_GET['status'] ?? '';
        $baseSql = "SELECT btalep.id, btalep.uye_id AS user_id, k.username, btalep.bonus_turu AS bonus_name, btalep.miktar AS amount, btalep.tarih AS created_at, btalep.durum
                    FROM bonus_talepleri btalep
                    LEFT JOIN kullanicilar k ON btalep.uye_id = k.id";

        $params = [];
        if ($status !== '') {
            $baseSql .= " WHERE btalep.durum = ?";
            $params[] = $status;
        }
        $baseSql .= " ORDER BY btalep.tarih DESC LIMIT 100";

        $stmt = $pdo->prepare($baseSql);
        $stmt->execute($params);
        $requests = $stmt->fetchAll(PDO::FETCH_ASSOC);

        echo json_encode(['success' => true, 'requests' => $requests]);
        break;

        case 'admin_approve_bonus_request':
        if (!isset($_SESSION['admin_id'])) {
            echo json_encode(['success' => false, 'message' => 'Yetkisiz erişim']);
            exit;
        }

        $requestId = intval($_POST['request_id'] ?? 0);
        if ($requestId <= 0) {
            echo json_encode(['success' => false, 'message' => 'Geçerli talep ID gerekli']);
            exit;
        }

        $pdo->beginTransaction();
        try {
            $stmt = $pdo->prepare("SELECT * FROM bonus_talepleri WHERE id = ? AND durum = 0 FOR UPDATE");
            $stmt->execute([$requestId]);
            $req = $stmt->fetch(PDO::FETCH_ASSOC);

            if (!$req) {
                throw new Exception('Talep bulunamadı veya beklemede değil');
            }

            $stmt = $pdo->prepare("UPDATE kullanicilar SET ana_bakiye = ana_bakiye + ? WHERE id = ?");
            $stmt->execute([floatval($req['miktar']), intval($req['uye_id'])]);

            $stmt = $pdo->prepare("UPDATE bonus_talepleri SET durum = 1 WHERE id = ?");
            $stmt->execute([$requestId]);

            $pdo->commit();
            echo json_encode(['success' => true, 'message' => 'Talep onaylandı ve bakiye güncellendi']);
        } catch (Exception $e) {
            $pdo->rollBack();
            echo json_encode(['success' => false, 'message' => $e->getMessage()]);
        }
        break;

        case 'admin_reject_bonus_request':
        if (!isset($_SESSION['admin_id'])) {
            echo json_encode(['success' => false, 'message' => 'Yetkisiz erişim']);
            exit;
        }

        $requestId = intval($_POST['request_id'] ?? 0);
        if ($requestId <= 0) {
            echo json_encode(['success' => false, 'message' => 'Geçerli talep ID gerekli']);
            exit;
        }

        try {
            $stmt = $pdo->prepare("UPDATE bonus_talepleri SET durum = 2 WHERE id = ? AND durum = 0");
            $stmt->execute([$requestId]);

            if ($stmt->rowCount() > 0) {
                echo json_encode(['success' => true, 'message' => 'Talep reddedildi']);
            } else {
                echo json_encode(['success' => false, 'message' => 'Talep bulunamadı veya beklemede değil']);
            }
        } catch (PDOException $e) {
            echo json_encode(['success' => false, 'message' => 'Veritabanı hatası: ' . $e->getMessage()]);
        }
        break;
        
    case 'admin_get_bonus_types':
        if (!isset($_SESSION['admin_id'])) {
            echo json_encode(['success' => false, 'message' => 'Yetkisiz erişim']);
            exit;
        }
        
        $stmt = $pdo->query("SELECT * FROM bonus_types ORDER BY created_at DESC");
        $types = $stmt->fetchAll(PDO::FETCH_ASSOC);
        echo json_encode(['success' => true, 'types' => $types], JSON_UNESCAPED_UNICODE);
        break;
        
    case 'admin_add_bonus_type':
        if (!isset($_SESSION['admin_id'])) {
            echo json_encode(['success' => false, 'message' => 'Yetkisiz erişim']);
            exit;
        }
        
        $name = $_POST['name'] ?? '';
        $description = $_POST['description'] ?? '';
        $min_amount = $_POST['min_amount'] ?? null;
        $max_amount = $_POST['max_amount'] ?? null;
        $percentage = $_POST['percentage'] ?? null;
        $conditions = $_POST['conditions'] ?? '{}';
        $wagering_requirement = isset($_POST['wagering_requirement']) ? floatval($_POST['wagering_requirement']) : 0;
        $no_wagering = isset($_POST['no_wagering']) ? (intval($_POST['no_wagering']) ? 1 : 0) : 0;
        
        if (empty($name)) {
            echo json_encode(['success' => false, 'message' => 'Bonus adı gerekli']);
            exit;
        }
        
        // JSON geçerliliğini kontrol et
        if (!empty($conditions) && json_decode($conditions) === null) {
            echo json_encode(['success' => false, 'message' => 'Geçersiz JSON formatı']);
            exit;
        }
        
        try {
            $stmt = $pdo->prepare("INSERT INTO bonus_types (name, description, min_amount, max_amount, percentage, conditions, wagering_requirement, no_wagering) VALUES (?, ?, ?, ?, ?, ?, ?, ?)");
            $stmt->execute([$name, $description, $min_amount, $max_amount, $percentage, $conditions, $wagering_requirement, $no_wagering]);
            echo json_encode(['success' => true, 'message' => 'Bonus türü eklendi'], JSON_UNESCAPED_UNICODE);
        } catch (PDOException $e) {
            echo json_encode(['success' => false, 'message' => 'Veritabanı hatası: ' . $e->getMessage()], JSON_UNESCAPED_UNICODE);
        }
        break;

    case 'admin_update_bonus_type':
        if (!isset($_SESSION['admin_id'])) {
            echo json_encode(['success' => false, 'message' => 'Yetkisiz erişim'], JSON_UNESCAPED_UNICODE);
            exit;
        }
        $id = intval($_POST['id'] ?? 0);
        $name = $_POST['name'] ?? '';
        $description = $_POST['description'] ?? '';
        $min_amount = $_POST['min_amount'] ?? null;
        $max_amount = $_POST['max_amount'] ?? null;
        $percentage = $_POST['percentage'] ?? null;
        $conditions = $_POST['conditions'] ?? '{}';
        $wagering_requirement = isset($_POST['wagering_requirement']) ? floatval($_POST['wagering_requirement']) : 0;
        $no_wagering = isset($_POST['no_wagering']) ? (intval($_POST['no_wagering']) ? 1 : 0) : 0;
        if (!$id || empty($name)) {
            echo json_encode(['success' => false, 'message' => 'Gerekli alanlar eksik'], JSON_UNESCAPED_UNICODE);
            exit;
        }
        if (!empty($conditions) && json_decode($conditions) === null) {
            echo json_encode(['success' => false, 'message' => 'Geçersiz JSON formatı'], JSON_UNESCAPED_UNICODE);
            exit;
        }
        try {
            $stmt = $pdo->prepare("UPDATE bonus_types SET name = ?, description = ?, min_amount = ?, max_amount = ?, percentage = ?, conditions = ?, wagering_requirement = ?, no_wagering = ? WHERE id = ?");
            $stmt->execute([$name, $description, $min_amount, $max_amount, $percentage, $conditions, $wagering_requirement, $no_wagering, $id]);
            echo json_encode(['success' => true, 'message' => 'Bonus türü güncellendi'], JSON_UNESCAPED_UNICODE);
        } catch (PDOException $e) {
            echo json_encode(['success' => false, 'message' => 'Veritabanı hatası: ' . $e->getMessage()], JSON_UNESCAPED_UNICODE);
        }
        break;

    case 'admin_toggle_bonus_type':
        if (!isset($_SESSION['admin_id'])) {
            echo json_encode(['success' => false, 'message' => 'Yetkisiz erişim'], JSON_UNESCAPED_UNICODE);
            exit;
        }
        $id = intval($_POST['id'] ?? 0);
        $current = intval($_POST['is_active'] ?? 0);
        if (!$id) {
            echo json_encode(['success' => false, 'message' => 'Bonus türü ID gerekli'], JSON_UNESCAPED_UNICODE);
            exit;
        }
        $new = $current ? 0 : 1;
        try {
            $stmt = $pdo->prepare("UPDATE bonus_types SET is_active = ? WHERE id = ?");
            $stmt->execute([$new, $id]);
            echo json_encode(['success' => true, 'message' => ($new ? 'Aktif edildi' : 'Pasif edildi'), 'new_status' => $new], JSON_UNESCAPED_UNICODE);
        } catch (PDOException $e) {
            echo json_encode(['success' => false, 'message' => 'Veritabanı hatası: ' . $e->getMessage()], JSON_UNESCAPED_UNICODE);
        }
        break;
        
    case 'admin_assign_bonus':
        if (!isset($_SESSION['admin_id'])) {
            echo json_encode(['success' => false, 'message' => 'Yetkisiz erişim']);
            exit;
        }
        
        $user_id = $_POST['user_id'] ?? 0;
        $bonus_type_id = $_POST['bonus_type_id'] ?? 0;
        $amount = $_POST['amount'] ?? 0;
        $valid_until = $_POST['valid_until'] ?? null;
        $description = $_POST['description'] ?? '';
        
        if (!$user_id || !$bonus_type_id || !$amount) {
            echo json_encode(['success' => false, 'message' => 'Eksik bilgiler']);
            exit;
        }
        
        // Kullanıcı kontrolü
        $stmt = $pdo->prepare("SELECT id FROM kullanicilar WHERE id = ?");
        $stmt->execute([$user_id]);
        if (!$stmt->fetch()) {
            echo json_encode(['success' => false, 'message' => 'Kullanıcı bulunamadı']);
            exit;
        }
        
        // Bonus türü kontrolü
        $stmt = $pdo->prepare("SELECT * FROM bonus_types WHERE id = ? AND is_active = 1");
        $stmt->execute([$bonus_type_id]);
        $bonus_type = $stmt->fetch(PDO::FETCH_ASSOC);
        if (!$bonus_type) {
            echo json_encode(['success' => false, 'message' => 'Bonus türü bulunamadı veya aktif değil']);
            exit;
        }
        
        try {
            $pdo->beginTransaction();
            $wr = floatval($bonus_type['wagering_requirement'] ?? 0);
            $no_wr = intval($bonus_type['no_wagering'] ?? 0) ? 1 : 0;
            $stmt = $pdo->prepare("INSERT INTO personalized_bonuses (user_id, bonus_type_id, amount, description, valid_until, status, used_at, wagering_requirement, no_wagering) VALUES (?, ?, ?, ?, ?, 'active', NOW(), ?, ?)");
            $stmt->execute([$user_id, $bonus_type_id, $amount, $description, $valid_until, $wr, $no_wr]);
            $stmt = $pdo->prepare("UPDATE kullanicilar SET ana_bakiye = ana_bakiye + ? WHERE id = ?");
            $stmt->execute([$amount, $user_id]);
            $stmt = $pdo->prepare("INSERT INTO bonus_usage_history (user_id, bonus_id, action, amount_used, remaining_amount, wagering_required) VALUES (?, LAST_INSERT_ID(), 'activated', ?, ?, ?)");
            $remaining = $amount;
            $wagerReq = $no_wr ? 0 : ($amount * $wr);
            $stmt->execute([$user_id, $amount, $remaining, $wagerReq]);
            $pdo->commit();
            echo json_encode(['success' => true, 'message' => 'Bonus başarıyla eklendi']);
        } catch (PDOException $e) {
            $pdo->rollBack();
            echo json_encode(['success' => false, 'message' => 'Veritabanı hatası: ' . $e->getMessage()]);
        }
        break;

    case 'admin_assign_free_spins':
        if (!isset($_SESSION['admin_id'])) {
            echo json_encode(['success' => false, 'message' => 'Yetkisiz erişim'], JSON_UNESCAPED_UNICODE);
            exit;
        }
        $user_id = intval($_POST['user_id'] ?? 0);
        $spins = intval($_POST['spins'] ?? 0);
        $provider = trim($_POST['provider'] ?? '');
        $game_code = trim($_POST['game_code'] ?? '');
        $expires_at = $_POST['expires_at'] ?? null;
        if (!$user_id || $spins <= 0) {
            echo json_encode(['success' => false, 'message' => 'Kullanıcı ve spin sayısı gerekli'], JSON_UNESCAPED_UNICODE);
            exit;
        }
        // Kullanıcı kontrolü
        $stmt = $pdo->prepare("SELECT id FROM kullanicilar WHERE id = ?");
        $stmt->execute([$user_id]);
        if (!$stmt->fetch()) {
            echo json_encode(['success' => false, 'message' => 'Kullanıcı bulunamadı'], JSON_UNESCAPED_UNICODE);
            exit;
        }
        // Tabloyu oluştur
        $pdo->exec("CREATE TABLE IF NOT EXISTS user_free_spins (
            id INT AUTO_INCREMENT PRIMARY KEY,
            user_id INT NOT NULL,
            provider VARCHAR(64) NULL,
            game_code VARCHAR(128) NULL,
            spins INT NOT NULL,
            status VARCHAR(16) NOT NULL DEFAULT 'pending',
            expires_at DATETIME NULL,
            assigned_by INT NULL,
            created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
            INDEX idx_user (user_id)
        ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci");
        try {
            $stmt = $pdo->prepare("INSERT INTO user_free_spins (user_id, provider, game_code, spins, status, expires_at, assigned_by) VALUES (?, ?, ?, ?, 'pending', ?, ?)");
            $stmt->execute([$user_id, $provider, $game_code, $spins, $expires_at, $_SESSION['admin_id']]);
            echo json_encode(['success' => true, 'message' => 'Free spin atandı'], JSON_UNESCAPED_UNICODE);
        } catch (PDOException $e) {
            echo json_encode(['success' => false, 'message' => 'Veritabanı hatası: ' . $e->getMessage()], JSON_UNESCAPED_UNICODE);
        }
        break;

    case 'admin_fs_campaign_create':
        if (!isset($_SESSION['admin_id'])) {
            echo json_encode(['success' => false, 'message' => 'Yetkisiz erişim'], JSON_UNESCAPED_UNICODE);
            exit;
        }
        $api_key = $VERITRAL_API_KEY;
        $secret_key = $VERITRAL_API_SECRET;
        if (!$api_key || !$secret_key) {
            echo json_encode(['success' => false, 'message' => 'API kimlik bilgileri eksik'], JSON_UNESCAPED_UNICODE);
            exit;
        }
        $vendor = $_POST['vendor'] ?? '';
        $campaign_code = $_POST['campaign_code'] ?? '';
        $freespins_per_player = intval($_POST['freespins_per_player'] ?? 0);
        $begins_at = intval($_POST['begins_at'] ?? 0);
        $expires_at = intval($_POST['expires_at'] ?? 0);
        $currency_code = $_POST['currency_code'] ?? 'TRY';
        $game_id = intval($_POST['game_id'] ?? 0);
        $total_bet = intval($_POST['total_bet'] ?? 0);
        $players = $_POST['players'] ?? '';
        if (!$vendor || !$campaign_code || $freespins_per_player <= 0 || !$begins_at || !$expires_at || !$game_id || !$total_bet) {
            echo json_encode(['success' => false, 'message' => 'Zorunlu alanlar eksik'], JSON_UNESCAPED_UNICODE);
            exit;
        }
        // Tablo: freespin_campaigns
        $pdo->exec("CREATE TABLE IF NOT EXISTS freespin_campaigns (
            id INT AUTO_INCREMENT PRIMARY KEY,
            vendor VARCHAR(64) NOT NULL,
            campaign_code VARCHAR(128) NOT NULL,
            freespins_per_player INT NOT NULL,
            begins_at INT NOT NULL,
            expires_at INT NOT NULL,
            currency_code VARCHAR(8) NOT NULL,
            game_id INT NOT NULL,
            total_bet INT NOT NULL,
            players TEXT NULL,
            status VARCHAR(24) NOT NULL DEFAULT 'created',
            created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
            UNIQUE KEY uniq_campaign (campaign_code)
        ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci");
        // Harici API isteği
        $payload = [
            'api_key' => $api_key,
            'secret_key' => $secret_key,
            'vendor' => $vendor,
            'campaign_code' => $campaign_code,
            'freespins_per_player' => $freespins_per_player,
            'begins_at' => $begins_at,
            'expires_at' => $expires_at,
            'currency_code' => $currency_code,
            'games' => [['game_id' => $game_id, 'total_bet' => $total_bet]],
            'players' => $players
        ];
        $resp = callExternalApi('https://api.veritral.com/api/campaigns/create', 'POST', $payload);
        // Kaydı yerel DB'ye ekle
        try {
            $stmt = $pdo->prepare("INSERT INTO freespin_campaigns (vendor, campaign_code, freespins_per_player, begins_at, expires_at, currency_code, game_id, total_bet, players, status) VALUES (?,?,?,?,?,?,?,?,?,?) ON DUPLICATE KEY UPDATE vendor=VALUES(vendor), freespins_per_player=VALUES(freespins_per_player), begins_at=VALUES(begins_at), expires_at=VALUES(expires_at), currency_code=VALUES(currency_code), game_id=VALUES(game_id), total_bet=VALUES(total_bet), players=VALUES(players), status=VALUES(status)");
            $stmt->execute([$vendor, $campaign_code, $freespins_per_player, $begins_at, $expires_at, $currency_code, $game_id, $total_bet, $players, ($resp['success'] ?? false) ? 'active' : 'error']);
        } catch (PDOException $e) {}
        echo json_encode(['success' => !!($resp['success'] ?? false), 'response' => $resp], JSON_UNESCAPED_UNICODE);
        break;

    case 'admin_fs_campaign_list':
        $api_key = $VERITRAL_API_KEY;
        $secret_key = $VERITRAL_API_SECRET;
        if (!$api_key || !$secret_key) {
            echo json_encode(['success' => false, 'message' => 'API kimlik bilgileri eksik'], JSON_UNESCAPED_UNICODE);
            exit;
        }
        $payload = ['api_key' => $api_key, 'secret_key' => $secret_key];
        $resp = callExternalApi('https://api.veritral.com/api/campaigns/agent/list', 'GET', $payload);
        echo json_encode(['success' => !!($resp['success'] ?? true), 'campaigns' => $resp['campaigns'] ?? $resp, 'raw' => $resp], JSON_UNESCAPED_UNICODE);
        break;

    case 'admin_fs_campaign_cancel':
        $api_key = $VERITRAL_API_KEY;
        $secret_key = $VERITRAL_API_SECRET;
        $campaign_code = $_POST['campaign_code'] ?? '';
        if (!$api_key || !$secret_key || !$campaign_code) {
            echo json_encode(['success' => false, 'message' => 'Gerekli alanlar eksik'], JSON_UNESCAPED_UNICODE);
            exit;
        }
        $payload = ['api_key' => $api_key, 'secret_key' => $secret_key, 'campaign_code' => $campaign_code];
        $resp = callExternalApi('https://api.veritral.com/api/campaigns/cancel', 'POST', $payload);
        // Yerel durumu güncelle
        try { $stmt = $pdo->prepare("UPDATE freespin_campaigns SET status='cancelled' WHERE campaign_code=?"); $stmt->execute([$campaign_code]); } catch (PDOException $e) {}
        echo json_encode(['success' => !!($resp['success'] ?? true), 'response' => $resp], JSON_UNESCAPED_UNICODE);
        break;

    case 'admin_fs_campaign_players_add':
        $api_key = $VERITRAL_API_KEY;
        $secret_key = $VERITRAL_API_SECRET;
        $campaign_code = $_POST['campaign_code'] ?? '';
        $players = $_POST['players'] ?? '';
        if (!$api_key || !$secret_key || !$campaign_code || !$players) {
            echo json_encode(['success' => false, 'message' => 'Gerekli alanlar eksik'], JSON_UNESCAPED_UNICODE);
            exit;
        }
        $list = is_array($players) ? $players : array_filter(array_map('trim', explode(',', $players)));
        $payload = ['api_key' => $api_key, 'secret_key' => $secret_key, 'campaign_code' => $campaign_code, 'players' => $list];
        $resp = callExternalApi('https://api.veritral.com/api/campaigns/players/add', 'POST', $payload);
        // Yerel kayıt
        $pdo->exec("CREATE TABLE IF NOT EXISTS freespin_campaign_players (
            id INT AUTO_INCREMENT PRIMARY KEY,
            campaign_code VARCHAR(128) NOT NULL,
            user_id VARCHAR(64) NOT NULL,
            status VARCHAR(24) NOT NULL DEFAULT 'added',
            created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
            INDEX idx_campaign (campaign_code)
        ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci");
        try {
            if (!empty($list)) {
                $stmt = $pdo->prepare("INSERT INTO freespin_campaign_players (campaign_code, user_id, status) VALUES (?,?, 'added')");
                foreach ($list as $uid) { $stmt->execute([$campaign_code, $uid]); }
            }
        } catch (PDOException $e) {}
        echo json_encode(['success' => !!($resp['success'] ?? true), 'response' => $resp], JSON_UNESCAPED_UNICODE);
        break;

    case 'admin_fs_campaign_players_remove':
        $api_key = $VERITRAL_API_KEY;
        $secret_key = $VERITRAL_API_SECRET;
        $campaign_code = $_POST['campaign_code'] ?? '';
        $players = $_POST['players'] ?? '';
        if (!$api_key || !$secret_key || !$campaign_code || !$players) {
            echo json_encode(['success' => false, 'message' => 'Gerekli alanlar eksik'], JSON_UNESCAPED_UNICODE);
            exit;
        }
        $list = is_array($players) ? $players : array_filter(array_map('trim', explode(',', $players)));
        $payload = ['api_key' => $api_key, 'secret_key' => $secret_key, 'campaign_code' => $campaign_code, 'players' => $list];
        $resp = callExternalApi('https://api.veritral.com/api/campaigns/players/remove', 'POST', $payload);
        try { $stmt = $pdo->prepare("UPDATE freespin_campaign_players SET status='removed' WHERE campaign_code=? AND user_id=?"); foreach ($list as $uid) { $stmt->execute([$campaign_code, $uid]); } } catch (PDOException $e) {}
        echo json_encode(['success' => !!($resp['success'] ?? true), 'response' => $resp], JSON_UNESCAPED_UNICODE);
        break;
        
    case 'admin_cancel_bonus':
        if (!isset($_SESSION['admin_id'])) {
            echo json_encode(['success' => false, 'message' => 'Yetkisiz erişim']);
            exit;
        }
        
        $bonus_id = $_POST['bonus_id'] ?? 0;
        
        if (!$bonus_id) {
            echo json_encode(['success' => false, 'message' => 'Bonus ID gerekli']);
            exit;
        }
        
        try {
            $stmt = $pdo->prepare("UPDATE personalized_bonuses SET status = 'expired' WHERE id = ? AND status = 'pending'");
            $stmt->execute([$bonus_id]);
            
            if ($stmt->rowCount() > 0) {
                echo json_encode(['success' => true, 'message' => 'Bonus iptal edildi']);
            } else {
                echo json_encode(['success' => false, 'message' => 'Bonus bulunamadı veya iptal edilemez']);
            }
        } catch (PDOException $e) {
            echo json_encode(['success' => false, 'message' => 'Veritabanı hatası: ' . $e->getMessage()]);
        }
        break;
        
    case 'admin_get_user_behaviors':
        if (!isset($_SESSION['admin_id'])) {
            echo json_encode(['success' => false, 'message' => 'Yetkisiz erişim']);
            exit;
        }
        
        $search = $_GET['search'] ?? '';
        $risk_level = $_GET['risk_level'] ?? '';
        
        $sql = "SELECT uba.*, k.username 
                FROM user_behavior_analytics uba 
                LEFT JOIN kullanicilar k ON uba.user_id = k.id 
                WHERE 1=1";
        $params = [];
        
        if ($search) {
            $sql .= " AND (k.username LIKE ? OR uba.user_id = ?)";
            $params[] = "%$search%";
            $params[] = $search;
        }
        
        if ($risk_level) {
            $sql .= " AND uba.risk_level = ?";
            $params[] = $risk_level;
        }
        
        $sql .= " ORDER BY uba.last_updated DESC LIMIT 50";
        
        $stmt = $pdo->prepare($sql);
        $stmt->execute($params);
        $behaviors = $stmt->fetchAll(PDO::FETCH_ASSOC);
        
        echo json_encode(['success' => true, 'behaviors' => $behaviors]);
        break;
        
    default:
        echo json_encode(['success' => false, 'message' => 'Geçersiz işlem']);
        break;}
} catch (Exception $e) {
    echo json_encode(['success' => false, 'message' => 'Hata: ' . $e->getMessage()]);
}

// Kullanıcının mevcut bonuslarını getir
function getAvailableBonuses($pdo, $user_id) {
    $stmt = $pdo->prepare("
        SELECT pb.*, bt.name as bonus_name, bt.description as bonus_description
        FROM personalized_bonuses pb
        JOIN bonus_types bt ON pb.bonus_type_id = bt.id
        WHERE pb.user_id = ? AND pb.status IN ('pending', 'active')
        ORDER BY pb.created_at DESC
    ");
    $stmt->execute([$user_id]);
    $bonuses = $stmt->fetchAll(PDO::FETCH_ASSOC);
    
    echo json_encode(['success' => true, 'bonuses' => $bonuses]);
}

// Kişiselleştirilmiş bonus hesapla
function calculatePersonalizedBonus($pdo, $user_id) {
    // Kullanıcı davranış verilerini al
    $behavior = getUserBehavior($pdo, $user_id);
    
    // Bonus önerilerini hesapla
    $suggestions = [];
    
    // Yatırım davranışına göre bonus
    if ($behavior['total_deposits'] > 1000) {
        $suggestions[] = [
            'type' => 'loyalty',
            'title' => 'Sadık Müşteri Bonusu',
            'description' => 'Yüksek yatırım geçmişiniz için özel %30 bonus',
            'percentage' => 30,
            'max_amount' => 1500
        ];
    }
    
    // Aktivite skoruna göre bonus
    if ($behavior['activity_score'] > 80) {
        $suggestions[] = [
            'type' => 'activity',
            'title' => 'Süper Aktif Oyuncu Bonusu',
            'description' => 'Yüksek aktiviteniz için 200 TL sabit bonus',
            'amount' => 200
        ];
    }
    
    // Kayıp durumuna göre geri kazanım bonusu
    $loss_ratio = $behavior['total_bets'] > 0 ? ($behavior['total_bets'] - $behavior['total_wins']) / $behavior['total_bets'] : 0;
    if ($loss_ratio > 0.6) {
        $suggestions[] = [
            'type' => 'deposit',
            'title' => 'Geri Kazanım Bonusu',
            'description' => 'Şansınızı artırmak için %40 geri kazanım bonusu',
            'percentage' => 40,
            'max_amount' => 800
        ];
    }
    
    echo json_encode(['success' => true, 'suggestions' => $suggestions, 'behavior' => $behavior]);
}

// Bonus talep et
function claimBonus($pdo, $user_id) {
    $bonus_id = $_POST['bonus_id'] ?? 0;
    
    if (!$bonus_id) {
        echo json_encode(['success' => false, 'message' => 'Bonus ID gerekli']);
        return;
    }
    
    $pdo->beginTransaction();
    
    try {
        // Bonus kontrolü
        $stmt = $pdo->prepare("
            SELECT * FROM personalized_bonuses 
            WHERE id = ? AND user_id = ? AND status = 'pending'
        ");
        $stmt->execute([$bonus_id, $user_id]);
        $bonus = $stmt->fetch(PDO::FETCH_ASSOC);
        
        if (!$bonus) {
            throw new Exception('Bonus bulunamadı veya zaten kullanılmış');
        }
        
        // Bonusu aktif et
        $stmt = $pdo->prepare("
            UPDATE personalized_bonuses 
            SET status = 'active', used_at = NOW() 
            WHERE id = ?
        ");
        $stmt->execute([$bonus_id]);
        
        // Kullanıcı bakiyesine ekle (ana_bakiye)
        $stmt = $pdo->prepare("
            UPDATE kullanicilar 
            SET ana_bakiye = ana_bakiye + ? 
            WHERE id = ?
        ");
        $stmt->execute([$bonus['amount'], $user_id]);
        
        // Bonus geçmişine kaydet
        $stmt = $pdo->prepare("
            INSERT INTO bonus_usage_history 
            (user_id, bonus_id, action, amount_used, remaining_amount, wagering_required) 
            VALUES (?, ?, 'activated', ?, ?, ?)
        ");
        $stmt->execute([
            $user_id, 
            $bonus_id, 
            $bonus['amount'], 
            $bonus['amount'], 
            $bonus['amount'] * $bonus['wagering_requirement']
        ]);
        
        $pdo->commit();
        echo json_encode(['success' => true, 'message' => 'Bonus başarıyla alındı']);
        
    } catch (Exception $e) {
        $pdo->rollBack();
        echo json_encode(['success' => false, 'message' => $e->getMessage()]);
    }
}

// Bonus geçmişini getir
function getBonusHistory($pdo, $user_id) {
    $stmt = $pdo->prepare("
        SELECT pb.*, bt.name as bonus_name, buh.action, buh.created_at as action_date
        FROM personalized_bonuses pb
        JOIN bonus_types bt ON pb.bonus_type_id = bt.id
        LEFT JOIN bonus_usage_history buh ON pb.id = buh.bonus_id
        WHERE pb.user_id = ?
        ORDER BY pb.created_at DESC
        LIMIT 50
    ");
    $stmt->execute([$user_id]);
    $history = $stmt->fetchAll(PDO::FETCH_ASSOC);
    
    echo json_encode(['success' => true, 'history' => $history]);
}

// Kullanıcı davranışını güncelle
function updateUserBehavior($pdo, $user_id) {
    // Kullanıcının işlem verilerini topla
    $stmt = $pdo->prepare("
        SELECT 
            COALESCE(SUM(CASE WHEN type = 'deposit' THEN amount ELSE 0 END), 0) as total_deposits,
            COALESCE(SUM(CASE WHEN type = 'withdrawal' THEN amount ELSE 0 END), 0) as total_withdrawals,
            COALESCE(SUM(CASE WHEN type = 'bet' THEN amount ELSE 0 END), 0) as total_bets,
            COALESCE(SUM(CASE WHEN type = 'win' THEN amount ELSE 0 END), 0) as total_wins,
            COUNT(DISTINCT DATE(created_at)) as active_days
        FROM transactions 
        WHERE user_id = ? AND created_at >= DATE_SUB(NOW(), INTERVAL 30 DAY)
    ");
    $stmt->execute([$user_id]);
    $stats = $stmt->fetch(PDO::FETCH_ASSOC);
    
    // Aktivite skoru hesapla (0-100 arası)
    $activity_score = min(100, (
        ($stats['active_days'] * 3) + 
        (min($stats['total_deposits'] / 100, 20)) + 
        (min($stats['total_bets'] / 500, 30))
    ));
    
    // Risk seviyesi hesapla
    $risk_level = 'low';
    if ($stats['total_bets'] > $stats['total_deposits'] * 10) {
        $risk_level = 'high';
    } elseif ($stats['total_bets'] > $stats['total_deposits'] * 5) {
        $risk_level = 'medium';
    }
    
    // Davranış verilerini güncelle veya ekle
    $stmt = $pdo->prepare("
        INSERT INTO user_behavior_analytics 
        (user_id, total_deposits, total_withdrawals, total_bets, total_wins, activity_score, risk_level, last_activity)
        VALUES (?, ?, ?, ?, ?, ?, ?, NOW())
        ON DUPLICATE KEY UPDATE
        total_deposits = VALUES(total_deposits),
        total_withdrawals = VALUES(total_withdrawals),
        total_bets = VALUES(total_bets),
        total_wins = VALUES(total_wins),
        activity_score = VALUES(activity_score),
        risk_level = VALUES(risk_level),
        last_activity = NOW()
    ");
    $stmt->execute([
        $user_id,
        $stats['total_deposits'],
        $stats['total_withdrawals'],
        $stats['total_bets'],
        $stats['total_wins'],
        $activity_score,
        $risk_level
    ]);
    
    echo json_encode(['success' => true, 'behavior_updated' => true]);
}

// Kullanıcı davranış verilerini getir
function getUserBehavior($pdo, $user_id) {
    $stmt = $pdo->prepare("
        SELECT * FROM user_behavior_analytics WHERE user_id = ?
    ");
    $stmt->execute([$user_id]);
    $behavior = $stmt->fetch(PDO::FETCH_ASSOC);
    
    if (!$behavior) {
        // İlk kez davranış verisi oluştur
        updateUserBehavior($pdo, $user_id);
        $stmt->execute([$user_id]);
        $behavior = $stmt->fetch(PDO::FETCH_ASSOC);
    }
    
    return $behavior ?: [];
}
function callExternalApi($url, $method, $payload) {
    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, $url);
    curl_setopt($ch, CURLOPT_CUSTOMREQUEST, $method);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_HTTPHEADER, ['Content-Type: application/json']);
    if (strtoupper($method) !== 'GET') {
        curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($payload, JSON_UNESCAPED_UNICODE));
    } else {
        // GET isteklerinde query-string kullan
        $qs = http_build_query($payload);
        curl_setopt($ch, CURLOPT_URL, $url . '?' . $qs);
    }
    $res = curl_exec($ch);
    if ($res === false) {
        $err = curl_error($ch);
        curl_close($ch);
        return ['success' => false, 'error' => $err];
    }
    $status = curl_getinfo($ch, CURLINFO_HTTP_CODE);
    curl_close($ch);
    $json = json_decode($res, true);
    if ($json === null) {
        return ['success' => ($status >= 200 && $status < 300), 'raw' => $res, 'status' => $status];
    }
    return $json;
}