File size: 23,858 Bytes
109e05b
 
 
 
 
 
 
 
 
 
 
 
 
 
d5eef83
 
109e05b
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1c9ebba
 
 
 
109e05b
1c9ebba
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
109e05b
 
 
 
 
 
 
 
 
 
d5eef83
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
109e05b
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
56aafb6
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
109e05b
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
56aafb6
109e05b
56aafb6
 
 
 
 
 
 
 
109e05b
 
 
 
56aafb6
 
 
109e05b
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
dbcd8a8
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
109e05b
dbcd8a8
 
 
 
109e05b
1c9ebba
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
109e05b
 
dbcd8a8
1c9ebba
 
 
 
 
 
dbcd8a8
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1c9ebba
 
 
 
 
 
 
 
 
 
 
 
 
 
dbcd8a8
1c9ebba
dbcd8a8
1c9ebba
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
dbcd8a8
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
# -*- coding: utf-8 -*-
"""

Trek Chatbot Enhanced Features

1. Görsel AI Entegrasyonu

2. Kişiselleştirilmiş Öneri Motoru  

3. Gelişmiş Ürün Karşılaştırma

"""

import os
import json
import base64
import requests
from datetime import datetime
import pandas as pd
from PIL import Image
import random

# Kullanıcı profili dosyası
USER_PROFILES_FILE = "user_profiles.json"

class UserProfileManager:
    """Kullanıcı profili yönetimi"""
    
    def __init__(self):
        self.profiles = self.load_profiles()
    
    def load_profiles(self):
        """Kullanıcı profillerini yükle"""
        if os.path.exists(USER_PROFILES_FILE):
            with open(USER_PROFILES_FILE, 'r', encoding='utf-8') as f:
                return json.load(f)
        return {}
    
    def save_profiles(self):
        """Kullanıcı profillerini kaydet"""
        with open(USER_PROFILES_FILE, 'w', encoding='utf-8') as f:
            json.dump(self.profiles, f, ensure_ascii=False, indent=2)
    
    def get_or_create_profile(self, user_id="default_user"):
        """Kullanıcı profili al veya oluştur"""
        if user_id not in self.profiles:
            self.profiles[user_id] = {
                "created_at": datetime.now().isoformat(),
                "preferences": {
                    "budget_range": None,
                    "bike_category": None,
                    "size": None,
                    "usage_purpose": None
                },
                "interaction_history": [],
                "favorite_products": [],
                "viewed_products": []
            }
        return self.profiles[user_id]
    
    def update_user_preference(self, user_id, key, value):
        """Kullanıcı tercihini güncelle"""
        profile = self.get_or_create_profile(user_id)
        profile["preferences"][key] = value
        self.save_profiles()
    
    def add_interaction(self, user_id, interaction_type, data):
        """Kullanıcı etkileşimi ekle"""
        profile = self.get_or_create_profile(user_id)
        interaction = {
            "timestamp": datetime.now().isoformat(),
            "type": interaction_type,
            "data": data
        }
        profile["interaction_history"].append(interaction)
        # Son 50 etkileşimi tut
        profile["interaction_history"] = profile["interaction_history"][-50:]
        
        # Otomatik tercih çıkarımı
        self._extract_preferences_from_interaction(user_id, interaction_type, data)
        
        self.save_profiles()
    
    def _extract_preferences_from_interaction(self, user_id, interaction_type, data):
        """Etkileşimden otomatik tercih çıkarımı"""
        profile = self.get_or_create_profile(user_id)
        
        if interaction_type == "chat_message":
            user_message = data.get("user_message", "").lower()
            
            # Bütçe tespiti
            import re
            if "bütçe" in user_message or "budget" in user_message:
                numbers = re.findall(r'\d+', user_message)
                if len(numbers) >= 1:
                    try:
                        budget_value = int(numbers[0]) * 1000  # K TL formatı için
                        if budget_value > 10000:  # Makul bütçe aralığı
                            current_budget = profile["preferences"].get("budget_range")
                            if not current_budget:
                                # Bütçe aralığını tahmin et
                                budget_max = budget_value * 1.5
                                profile["preferences"]["budget_range"] = [budget_value, budget_max]
                    except ValueError:
                        pass
            
            # Bisiklet kategorisi tespiti
            bike_categories = {
                "dağ": "dağ bisikleti",
                "mountain": "dağ bisikleti", 
                "mtb": "dağ bisikleti",
                "yol": "yol bisikleti",
                "road": "yol bisikleti",
                "şehir": "şehir bisikleti",
                "city": "şehir bisikleti",
                "urban": "şehir bisikleti",
                "elektrikli": "elektrikli bisiklet",
                "electric": "elektrikli bisiklet",
                "e-bike": "elektrikli bisiklet",
                "gravel": "gravel bisiklet"
            }
            
            for keyword, category in bike_categories.items():
                if keyword in user_message:
                    profile["preferences"]["bike_category"] = category
                    break
            
            # Kullanım amacı tespiti
            usage_purposes = {
                "işe": "günlük ulaşım",
                "work": "günlük ulaşım",
                "spor": "spor ve egzersiz",
                "sport": "spor ve egzersiz",
                "egzersiz": "spor ve egzersiz",
                "fitness": "spor ve egzersiz",
                "tur": "tur ve gezi",
                "tour": "tur ve gezi",
                "gezi": "tur ve gezi",
                "yarış": "yarış ve performans",
                "race": "yarış ve performans",
                "performance": "yarış ve performans"
            }
            
            for keyword, purpose in usage_purposes.items():
                if keyword in user_message:
                    profile["preferences"]["usage_purpose"] = purpose
                    break

class VisualAI:
    """Görsel AI işlemleri"""
    
    def __init__(self, openai_api_key):
        self.api_key = openai_api_key
    
    def analyze_bike_image(self, image_path):
        """Bisiklet görselini analiz et"""
        if not self.api_key:
            # Yerel görsel analiz (demo amaçlı)
            return self.local_image_analysis(image_path)
        
        return self.openai_image_analysis(image_path)
    
    def local_image_analysis(self, image_path):
        """Yerel görsel analiz (demo)"""
        try:
            # Görseli yükle ve temel bilgileri al
            img = Image.open(image_path)
            width, height = img.size
            
            # Basit analiz mantığı (demo amaçlı)
            bike_types = ["Yol Bisikleti", "Dağ Bisikleti", "Şehir Bisikleti", "Elektrikli Bisiklet"]
            trek_models = ["Madone", "Émonda", "Domane", "Marlin", "Fuel EX", "FX", "Powerfly"]
            colors = ["Siyah", "Beyaz", "Kırmızı", "Mavi", "Gri", "Yeşil"]
            
            # Rastgele ama mantıklı analiz
            detected_type = random.choice(bike_types)
            detected_model = random.choice(trek_models)
            detected_color = random.choice(colors)
            
            return f"""🖼️ **Görsel Analiz Sonucu**



📊 **Görsel Bilgileri:**

• Boyut: {width}x{height} piksel

• Format: {img.format if img.format else 'Bilinmiyor'}



🚲 **Bisiklet Analizi:**

• **Tip:** {detected_type}

• **Tahmini Model:** Trek {detected_model}

• **Renk:** {detected_color}



🔍 **Tespit Edilen Özellikler:**

• Karbon kadro yapısı görünüyor

• Profesyonel seviye ekipman

• Aerodinamik tasarım elementleri



💡 **Önerilerim:**

Bu bisiklet {detected_type.lower()} kategorisinde. Eğer {detected_model} modeli ilginizi çekiyorsa, 

stoklarımızda bu seriyle ilgili güncel modelleri gösterebilirim.



*Not: Bu yerel analiz sistemidir. Daha detaylı analiz için Vision API entegrasyonu önerilir.*"""
            
        except Exception as e:
            return f"🖼️ Görsel analiz hatası: {str(e)}"
    
    def openai_image_analysis(self, image_path):
        """OpenAI Vision API ile analiz"""
        
        try:
            # Görseli base64'e çevir
            with open(image_path, "rb") as image_file:
                base64_image = base64.b64encode(image_file.read()).decode('utf-8')
            
            headers = {
                "Content-Type": "application/json",
                "Authorization": f"Bearer {self.api_key}"
            }
            
            payload = {
                "model": "gpt-4-vision-preview",
                "messages": [
                    {
                        "role": "user",
                        "content": [
                            {
                                "type": "text",
                                "text": "Bu bisiklet görselini analiz et. Hangi tip bisiklet? Marka, model tahmininde bulun. Trek bisikletleri hakkında uzmanısın."
                            },
                            {
                                "type": "image_url",
                                "image_url": {
                                    "url": f"data:image/jpeg;base64,{base64_image}"
                                }
                            }
                        ]
                    }
                ],
                "max_tokens": 300
            }
            
            response = requests.post("https://api.openai.com/v1/chat/completions", 
                                   headers=headers, json=payload)
            
            if response.status_code == 200:
                result = response.json()
                return result["choices"][0]["message"]["content"]
            else:
                return f"Görsel analiz hatası: {response.status_code}"
                
        except Exception as e:
            return f"Görsel analiz hatası: {str(e)}"

class ProductComparison:
    """Ürün karşılaştırma sistemi"""
    
    def __init__(self, products_data):
        self.products = products_data
    
    def round_price(self, price_str):
        """Fiyatı yuvarlama formülüne göre yuvarla"""
        try:
            price_float = float(price_str)
            # Fiyat 200000 üzerindeyse en yakın 5000'lik basamağa yuvarla
            if price_float > 200000:
                return str(round(price_float / 5000) * 5000)
            # Fiyat 30000 üzerindeyse en yakın 1000'lik basamağa yuvarla
            elif price_float > 30000:
                return str(round(price_float / 1000) * 1000)
            # Fiyat 10000 üzerindeyse en yakın 100'lük basamağa yuvarla
            elif price_float > 10000:
                return str(round(price_float / 100) * 100)
            # Diğer durumlarda en yakın 10'luk basamağa yuvarla
            else:
                return str(round(price_float / 10) * 10)
        except (ValueError, TypeError):
            return price_str
    
    def find_products_by_name(self, product_names):
        """İsimlere göre ürünleri bul"""
        found_products = []
        for name in product_names:
            for product in self.products:
                if name.lower() in product[2].lower():  # product[2] = full_name
                    found_products.append(product)
                    break
        return found_products
    
    def create_comparison_table(self, product_names):
        """Karşılaştırma tablosu oluştur"""
        products = self.find_products_by_name(product_names)
        
        if len(products) < 2:
            return "Karşılaştırma için en az 2 ürün gerekli."
        
        # Tablo verilerini hazırla
        comparison_data = []
        for product in products:
            name, item_info, full_name = product
            
            # Ürün bilgilerini parse et
            stock_status = item_info[0] if len(item_info) > 0 else "Bilgi yok"
            price_raw = item_info[1] if len(item_info) > 1 and item_info[1] else "Fiyat yok"
            product_link = item_info[2] if len(item_info) > 2 else ""
            image_url = item_info[6] if len(item_info) > 6 and item_info[6] else ""
            
            # Fiyatı yuvarlama formülüne göre yuvarla
            if price_raw != "Fiyat yok":
                price = self.round_price(price_raw)
                price_display = f"{price} TL"
            else:
                price_display = price_raw
            
            comparison_data.append({
                "Ürün": full_name,
                "Stok": stock_status,
                "Fiyat": price_display,
                "Link": product_link,
                "Resim": image_url if image_url else "Resim yok"
            })
        
        # DataFrame oluştur
        df = pd.DataFrame(comparison_data)
        
        # Markdown tablosu olarak döndür
        return df.to_markdown(index=False)
    
    def get_similar_products(self, product_name, category_filter=None):
        """Benzer ürünleri bul"""
        similar_products = []
        base_name = product_name.lower().split()[0]  # İlk kelimeyi al
        
        for product in self.products:
            product_full_name = product[2].lower()
            if base_name in product_full_name and product_name.lower() != product_full_name:
                if category_filter:
                    if category_filter.lower() in product_full_name:
                        similar_products.append(product)
                else:
                    similar_products.append(product)
        
        return similar_products[:5]  # İlk 5 benzer ürün

class PersonalizedRecommendations:
    """Kişiselleştirilmiş öneriler"""
    
    def __init__(self, profile_manager, products_data):
        self.profile_manager = profile_manager
        self.products = products_data
    
    def get_budget_recommendations(self, user_id, budget_min, budget_max):
        """Bütçeye uygun öneriler"""
        suitable_products = []
        
        for product in self.products:
            if product[1][0] == "stokta" and product[1][1]:  # Stokta ve fiyatı var
                try:
                    price = float(product[1][1])
                    if budget_min <= price <= budget_max:
                        suitable_products.append(product)
                except (ValueError, TypeError):
                    continue
        
        # Kullanıcı tercihlerini kaydet
        self.profile_manager.update_user_preference(user_id, "budget_range", [budget_min, budget_max])
        
        return suitable_products[:5]  # İlk 5 öneri
    
    def get_personalized_suggestions(self, user_id):
        """Geçmiş davranışlara göre öneriler"""
        profile = self.profile_manager.get_or_create_profile(user_id)
        preferences = profile["preferences"]
        
        suggestions = []
        
        # Bütçe tercihi varsa ona göre filtrele
        if preferences.get("budget_range"):
            budget_min, budget_max = preferences["budget_range"]
            suggestions.extend(self.get_budget_recommendations(user_id, budget_min, budget_max))
        
        # Kategori tercihi varsa ona göre filtrele  
        if preferences.get("bike_category"):
            category = preferences["bike_category"]
            for product in self.products:
                if category.lower() in product[2].lower() and product[1][0] == "stokta":
                    suggestions.append(product)
        
        return list(set(suggestions))[:3]  # Duplicate'ları kaldır ve ilk 3'ü al

# Global instance'lar
profile_manager = UserProfileManager()
visual_ai = None  # OpenAI key ile başlatılacak
product_comparison = None  # Products data ile başlatılacak
personalized_recommendations = None  # Profile manager ve products ile başlatılacak

def initialize_enhanced_features(openai_api_key, products_data):
    """Enhanced özellikleri başlat"""
    global visual_ai, product_comparison, personalized_recommendations
    
    visual_ai = VisualAI(openai_api_key)
    product_comparison = ProductComparison(products_data)
    personalized_recommendations = PersonalizedRecommendations(profile_manager, products_data)

def process_image_message(image_path, user_message):
    """Görsel mesajını işle"""
    if visual_ai and image_path:
        image_analysis = visual_ai.analyze_bike_image(image_path)
        return f"Görsel Analiz: {image_analysis}\n\nSoru: {user_message}"
    return user_message

def handle_comparison_request(user_message):
    """Karşılaştırma talebini işle"""
    try:
        if "karşılaştır" in user_message.lower() or "compare" in user_message.lower():
            # Ürün isimlerini çıkarmaya çalış
            words = user_message.lower().split()
            potential_products = []
            
            # Bilinen model isimlerini ara
            known_models = ["émonda", "madone", "domane", "marlin", "fuel", "powerfly", "fx"]
            for word in words:
                for model in known_models:
                    if model in word:
                        potential_products.append(model)
            
            if len(potential_products) >= 2 and product_comparison:
                comparison_table = product_comparison.create_comparison_table(potential_products)
                return f"Ürün Karşılaştırması:\n\n{comparison_table}"
        
        return None
    except Exception as e:
        print(f"Comparison error: {e}")
        return None

def get_user_chat_context(user_id, limit=5):
    """Son sohbet geçmişini kontekst için al"""
    try:
        profile = profile_manager.get_or_create_profile(user_id)
        interactions = profile.get("interaction_history", [])
        
        # Son chat mesajlarını al
        chat_messages = []
        for interaction in reversed(interactions):
            if interaction['type'] == 'chat_message' and len(chat_messages) < limit:
                data = interaction['data']
                chat_messages.append({
                    "user": data.get('user_message', ''),
                    "assistant": data.get('bot_response', ''),
                    "timestamp": data.get('timestamp', '')
                })
        
        return list(reversed(chat_messages))  # Kronolojik sıra
        
    except Exception as e:
        print(f"Chat context error: {e}")
        return []

def get_user_profile_summary(user_id):
    """Kullanıcı profil özetini döndür"""
    try:
        profile = profile_manager.get_or_create_profile(user_id)
        preferences = profile.get("preferences", {})
        
        if not any(preferences.values()):
            return "Henüz tercihleriniz kaydedilmemiş. Bisiklet arayışınız hakkında konuşarak size daha iyi öneriler verebilirim."
        
        summary = "🔄 **Kaydedilen Tercihleriniz:**\n\n"
        
        if preferences.get("bike_category"):
            summary += f"🚲 **Bisiklet Kategorisi:** {preferences['bike_category']}\n"
        
        if preferences.get("budget_range"):
            budget_min, budget_max = preferences['budget_range']
            summary += f"💰 **Bütçe Aralığı:** {budget_min:,.0f} - {budget_max:,.0f} TL\n"
        
        if preferences.get("usage_purpose"):
            summary += f"🎯 **Kullanım Amacı:** {preferences['usage_purpose']}\n"
        
        if preferences.get("size"):
            summary += f"📏 **Boyut:** {preferences['size']}\n"
        
        # Son etkileşimler
        interactions = profile.get("interaction_history", [])
        if interactions:
            recent_chats = [i for i in interactions[-5:] if i['type'] == 'chat_message']
            if recent_chats:
                summary += f"\n📝 **Son {len(recent_chats)} Sohbet:**\n"
                for chat in recent_chats:
                    timestamp = chat['data'].get('timestamp', 'Bilinmiyor')
                    summary += f"• {timestamp}: Sohbet\n"
        
        summary += "\n*Bu tercihler sohbetlerimizden otomatik olarak çıkarıldı.*"
        return summary
        
    except Exception as e:
        print(f"Profile summary error: {e}")
        return "Profil bilgilerine şu anda erişilemiyor."

def get_user_recommendations(user_id, user_message):
    """Kullanıcıya özel öneriler al"""
    try:
        # Kullanıcı etkileşimini kaydet (tercih çıkarımı için)
        profile_manager.add_interaction(user_id, "recommendation_query", {
            "message": user_message,
            "timestamp": datetime.now().isoformat()
        })
        
        # Bütçe sorgusu varsa
        if "bütçe" in user_message.lower() or "budget" in user_message.lower():
            # Rakamları çıkarmaya çalış
            import re
            numbers = re.findall(r'\d+', user_message)
            if len(numbers) >= 2 and personalized_recommendations:
                budget_min = int(numbers[0]) * 1000  # K TL formatı için
                budget_max = int(numbers[1]) * 1000
                recommendations = personalized_recommendations.get_budget_recommendations(
                    user_id, budget_min, budget_max
                )
                
                if recommendations:
                    rec_text = "Bütçenize uygun öneriler:\n\n"
                    for product in recommendations[:3]:
                        rec_text += f"• {product[2]} - {product[1][1]} TL\n"
                    return rec_text
            elif len(numbers) >= 1 and personalized_recommendations:
                # Tek sayı varsa aralık oluştur
                budget_center = int(numbers[0]) * 1000
                budget_min = int(budget_center * 0.8)
                budget_max = int(budget_center * 1.2)
                recommendations = personalized_recommendations.get_budget_recommendations(
                    user_id, budget_min, budget_max
                )
                
                if recommendations:
                    rec_text = f"{numbers[0]}K TL bütçenize uygun öneriler:\n\n"
                    for product in recommendations[:3]:
                        rec_text += f"• {product[2]} - {product[1][1]} TL\n"
                    return rec_text
        
        # Kullanıcı profili tercihleri varsa öneri ver
        if personalized_recommendations:
            profile = profile_manager.get_or_create_profile(user_id)
            preferences = profile.get("preferences", {})
            
            # Eğer kullanıcının kaydedilmiş tercihleri varsa
            if any(preferences.values()):
                suggestions = personalized_recommendations.get_personalized_suggestions(user_id)
                if suggestions:
                    sug_text = "Tercihlerinize göre önerilerimiz:\n\n"
                    for product in suggestions[:3]:
                        sug_text += f"• {product[2]} - {product[1][1]} TL\n"
                    
                    # Tercih özetini ekle
                    pref_summary = []
                    if preferences.get("bike_category"):
                        pref_summary.append(f"Kategori: {preferences['bike_category']}")
                    if preferences.get("budget_range"):
                        pref_summary.append(f"Bütçe: {preferences['budget_range'][0]:,.0f}-{preferences['budget_range'][1]:,.0f} TL")
                    if preferences.get("usage_purpose"):
                        pref_summary.append(f"Kullanım: {preferences['usage_purpose']}")
                    
                    if pref_summary:
                        sug_text += f"\n*Kaydedilen tercihleriniz: {', '.join(pref_summary)}*"
                    
                    return sug_text
        
        return None
    except Exception as e:
        print(f"Recommendations error: {e}")
        return None