File size: 28,547 Bytes
ab3b796
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
"""

Prompt Marketplace Module

Enables users to create, sell, purchase, and use AI prompts

"""
import os
import json
import uuid
import logging
from typing import Dict, Any, List, Optional
from datetime import datetime

from prompts.prompt_templates import PromptTemplate, PromptTemplateManager

# Setup logging
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger("prompt_marketplace")

class PromptMarketplace:
    """Manages the prompt marketplace functionality"""
    
    def __init__(self, data_dir: str = None):
        """Initialize the prompt marketplace"""
        self.data_dir = data_dir or os.path.join(os.path.dirname(__file__), "marketplace_data")
        
        # Create data directory if it doesn't exist
        os.makedirs(self.data_dir, exist_ok=True)
        
        # Paths for data files
        self.purchases_file = os.path.join(self.data_dir, "purchases.json")
        self.sales_file = os.path.join(self.data_dir, "sales.json")
        self.stats_file = os.path.join(self.data_dir, "stats.json")
        
        # Initialize data files if they don't exist
        self._initialize_data_files()
        
        # Create prompt template manager
        self.template_manager = PromptTemplateManager()
    
    def _initialize_data_files(self):
        """Initialize data files if they don't exist"""
        if not os.path.exists(self.purchases_file):
            with open(self.purchases_file, "w") as f:
                json.dump([], f)
        
        if not os.path.exists(self.sales_file):
            with open(self.sales_file, "w") as f:
                json.dump([], f)
        
        if not os.path.exists(self.stats_file):
            with open(self.stats_file, "w") as f:
                json.dump({
                    "total_sales": 0,
                    "total_revenue": 0,
                    "prompt_usage": {},
                    "popular_categories": {}
                }, f, indent=2)
    
    def list_marketplace_prompts(self, category: str = None, sort_by: str = "popular") -> List[Dict[str, Any]]:
        """

        List prompts available in the marketplace

        

        Args:

            category: Optional category to filter by

            sort_by: Sorting method ('popular', 'newest', 'price_low', 'price_high')

            

        Returns:

            List of prompt templates available for purchase

        """
        # Get all public templates
        all_templates = self.template_manager.get_public_templates()
        
        # Filter by category if specified
        if category:
            all_templates = [t for t in all_templates if t.category.lower() == category.lower()]
        
        # Convert to dictionaries for easier manipulation
        templates_dict = [t.to_dict() for t in all_templates]
        
        # Add usage statistics
        templates_with_stats = self._add_stats_to_templates(templates_dict)
        
        # Sort the templates
        if sort_by == "popular":
            templates_with_stats.sort(key=lambda x: x.get("stats", {}).get("usage_count", 0), reverse=True)
        elif sort_by == "newest":
            templates_with_stats.sort(key=lambda x: x.get("created_at", ""), reverse=True)
        elif sort_by == "price_low":
            templates_with_stats.sort(key=lambda x: x.get("price", 0))
        elif sort_by == "price_high":
            templates_with_stats.sort(key=lambda x: x.get("price", 0), reverse=True)
        
        return templates_with_stats
    
    def _add_stats_to_templates(self, templates: List[Dict[str, Any]]) -> List[Dict[str, Any]]:
        """Add usage statistics to template dictionaries"""
        try:
            with open(self.stats_file, "r") as f:
                stats = json.load(f)
            
            prompt_usage = stats.get("prompt_usage", {})
            
            # Add stats to each template
            for template in templates:
                template_id = template.get("id")
                template["stats"] = {
                    "usage_count": prompt_usage.get(template_id, {}).get("count", 0),
                    "purchase_count": prompt_usage.get(template_id, {}).get("purchases", 0),
                    "rating": prompt_usage.get(template_id, {}).get("avg_rating", 0),
                    "reviews": prompt_usage.get(template_id, {}).get("review_count", 0)
                }
            
            return templates
        except Exception as e:
            logger.error(f"Error adding stats to templates: {e}")
            return templates
    
    def get_prompt_details(self, prompt_id: str) -> Dict[str, Any]:
        """

        Get detailed information about a marketplace prompt

        

        Args:

            prompt_id: ID of the prompt template

            

        Returns:

            Detailed prompt information including stats and sample outputs

        """
        prompt = self.template_manager.get_template(prompt_id)
        
        if not prompt:
            return {"success": False, "error": "Prompt not found"}
        
        if not prompt.is_public and prompt.created_by != "system":
            return {"success": False, "error": "Prompt is not available in the marketplace"}
        
        # Get prompt details
        prompt_dict = prompt.to_dict()
        
        # Add stats
        prompt_dict = self._add_stats_to_templates([prompt_dict])[0]
        
        # Get purchase information
        prompt_dict["purchases"] = self._get_prompt_purchases(prompt_id)
        
        return {
            "success": True,
            "prompt": prompt_dict
        }
    
    def _get_prompt_purchases(self, prompt_id: str) -> Dict[str, Any]:
        """Get purchase information for a prompt"""
        try:
            with open(self.sales_file, "r") as f:
                sales = json.load(f)
            
            # Filter sales for this prompt
            prompt_sales = [s for s in sales if s.get("prompt_id") == prompt_id]
            
            return {
                "total": len(prompt_sales),
                "recent": len([s for s in prompt_sales if 
                              (datetime.now() - datetime.fromisoformat(s.get("timestamp", ""))).days < 7])
            }
        except Exception as e:
            logger.error(f"Error getting prompt purchases: {e}")
            return {"total": 0, "recent": 0}
    
    def create_prompt_for_sale(self, 

                              name: str,

                              description: str,

                              template: str,

                              system_message: str,

                              category: str,

                              price: float,

                              parameters: Dict[str, Any],

                              created_by: str,

                              provider_defaults: Dict[str, Any] = None) -> Dict[str, Any]:
        """

        Create a new prompt template for sale in the marketplace

        

        Args:

            name: Name of the prompt template

            description: Description of what the prompt does

            template: The prompt template text

            system_message: System message for the prompt

            category: Category for the prompt

            price: Price in credits

            parameters: Dictionary of parameters for the prompt

            created_by: User ID of the creator

            provider_defaults: Default settings for different providers

            

        Returns:

            Result dictionary with success status and prompt information

        """
        # Validate inputs
        if not name or not template:
            return {"success": False, "error": "Name and template are required"}
        
        if price < 0:
            return {"success": False, "error": "Price cannot be negative"}
        
        # Create the prompt template
        new_prompt = PromptTemplate(
            name=name,
            description=description,
            template=template,
            system_message=system_message,
            category=category,
            is_public=True,  # It's for sale, so make it public
            created_by=created_by,
            price=price,
            parameters=parameters,
            provider_defaults=provider_defaults or {}
        )
        
        # Save the prompt
        created_prompt = self.template_manager.create_template(new_prompt)
        
        # Initialize stats for this prompt
        self._initialize_prompt_stats(created_prompt.id)
        
        return {
            "success": True,
            "prompt": created_prompt.to_dict(),
            "message": "Prompt successfully created and listed in the marketplace"
        }
    
    def _initialize_prompt_stats(self, prompt_id: str):
        """Initialize statistics for a new prompt"""
        try:
            with open(self.stats_file, "r") as f:
                stats = json.load(f)
            
            prompt_usage = stats.get("prompt_usage", {})
            prompt_usage[prompt_id] = {
                "count": 0,
                "purchases": 0,
                "avg_rating": 0,
                "review_count": 0,
                "last_used": None
            }
            
            stats["prompt_usage"] = prompt_usage
            
            with open(self.stats_file, "w") as f:
                json.dump(stats, f, indent=2)
                
        except Exception as e:
            logger.error(f"Error initializing prompt stats: {e}")
    
    def purchase_prompt(self, prompt_id: str, user_id: str, credits_available: float) -> Dict[str, Any]:
        """

        Purchase a prompt from the marketplace

        

        Args:

            prompt_id: ID of the prompt to purchase

            user_id: ID of the user making the purchase

            credits_available: Credits available to the user

            

        Returns:

            Result dictionary with success status and transaction details

        """
        # Get the prompt
        prompt = self.template_manager.get_template(prompt_id)
        
        if not prompt:
            return {"success": False, "error": "Prompt not found"}
        
        if not prompt.is_public:
            return {"success": False, "error": "Prompt is not available for purchase"}
        
        # Check if user already owns this prompt
        if self._user_owns_prompt(user_id, prompt_id):
            return {"success": False, "error": "You already own this prompt"}
        
        # Check if user has enough credits
        if credits_available < prompt.price:
            return {"success": False, "error": "Insufficient credits", "credits_needed": prompt.price}
        
        # Process the purchase
        purchase_id = str(uuid.uuid4())
        purchase_time = datetime.now().isoformat()
        
        purchase_record = {
            "id": purchase_id,
            "prompt_id": prompt_id,
            "user_id": user_id,
            "seller_id": prompt.created_by,
            "price": prompt.price,
            "timestamp": purchase_time
        }
        
        # Record the purchase
        self._record_purchase(purchase_record)
        
        # Record the sale
        self._record_sale(purchase_record)
        
        # Update statistics
        self._update_stats_after_purchase(prompt_id)
        
        return {
            "success": True,
            "transaction": {
                "id": purchase_id,
                "prompt_id": prompt_id,
                "prompt_name": prompt.name,
                "price": prompt.price,
                "timestamp": purchase_time
            },
            "credits_used": prompt.price,
            "message": f"Successfully purchased prompt: {prompt.name}"
        }
    
    def _user_owns_prompt(self, user_id: str, prompt_id: str) -> bool:
        """Check if a user already owns a prompt"""
        try:
            with open(self.purchases_file, "r") as f:
                purchases = json.load(f)
            
            # Check if the user has already purchased this prompt
            for purchase in purchases:
                if purchase.get("user_id") == user_id and purchase.get("prompt_id") == prompt_id:
                    return True
            
            return False
            
        except Exception as e:
            logger.error(f"Error checking if user owns prompt: {e}")
            return False
    
    def _record_purchase(self, purchase_record: Dict[str, Any]):
        """Record a prompt purchase"""
        try:
            with open(self.purchases_file, "r") as f:
                purchases = json.load(f)
            
            purchases.append(purchase_record)
            
            with open(self.purchases_file, "w") as f:
                json.dump(purchases, f, indent=2)
                
        except Exception as e:
            logger.error(f"Error recording purchase: {e}")
    
    def _record_sale(self, purchase_record: Dict[str, Any]):
        """Record a prompt sale"""
        try:
            with open(self.sales_file, "r") as f:
                sales = json.load(f)
            
            sales.append(purchase_record)
            
            with open(self.sales_file, "w") as f:
                json.dump(sales, f, indent=2)
                
        except Exception as e:
            logger.error(f"Error recording sale: {e}")
    
    def _update_stats_after_purchase(self, prompt_id: str):
        """Update statistics after a prompt purchase"""
        try:
            with open(self.stats_file, "r") as f:
                stats = json.load(f)
            
            # Update prompt-specific stats
            prompt_usage = stats.get("prompt_usage", {})
            if prompt_id not in prompt_usage:
                prompt_usage[prompt_id] = {
                    "count": 0,
                    "purchases": 0,
                    "avg_rating": 0,
                    "review_count": 0
                }
            
            prompt_usage[prompt_id]["purchases"] = prompt_usage[prompt_id].get("purchases", 0) + 1
            
            # Update global stats
            stats["total_sales"] = stats.get("total_sales", 0) + 1
            
            # Get the prompt price
            prompt = self.template_manager.get_template(prompt_id)
            if prompt:
                stats["total_revenue"] = stats.get("total_revenue", 0) + prompt.price
                
                # Update category popularity
                category = prompt.category
                popular_categories = stats.get("popular_categories", {})
                popular_categories[category] = popular_categories.get(category, 0) + 1
                stats["popular_categories"] = popular_categories
            
            # Save updated stats
            with open(self.stats_file, "w") as f:
                json.dump(stats, f, indent=2)
                
        except Exception as e:
            logger.error(f"Error updating stats after purchase: {e}")
    
    def get_user_purchased_prompts(self, user_id: str) -> List[Dict[str, Any]]:
        """

        Get prompts purchased by a specific user

        

        Args:

            user_id: ID of the user

            

        Returns:

            List of prompts owned by the user

        """
        purchased_prompt_ids = self._get_user_purchased_prompt_ids(user_id)
        
        # Get the prompt details for each purchased prompt
        purchased_prompts = []
        for prompt_id in purchased_prompt_ids:
            prompt = self.template_manager.get_template(prompt_id)
            if prompt:
                prompt_dict = prompt.to_dict()
                purchased_prompts.append(prompt_dict)
        
        return purchased_prompts
    
    def _get_user_purchased_prompt_ids(self, user_id: str) -> List[str]:
        """Get IDs of prompts purchased by a user"""
        try:
            with open(self.purchases_file, "r") as f:
                purchases = json.load(f)
            
            # Get unique prompt IDs purchased by this user
            prompt_ids = set()
            for purchase in purchases:
                if purchase.get("user_id") == user_id:
                    prompt_ids.add(purchase.get("prompt_id"))
            
            return list(prompt_ids)
            
        except Exception as e:
            logger.error(f"Error getting user purchased prompt IDs: {e}")
            return []
    
    def get_user_sales(self, user_id: str) -> Dict[str, Any]:
        """

        Get sales information for a specific seller

        

        Args:

            user_id: ID of the seller

            

        Returns:

            Dictionary with sales information

        """
        try:
            with open(self.sales_file, "r") as f:
                sales = json.load(f)
            
            # Filter sales by this seller
            user_sales = [s for s in sales if s.get("seller_id") == user_id]
            
            # Calculate total revenue
            total_revenue = sum(s.get("price", 0) for s in user_sales)
            
            # Group sales by prompt
            sales_by_prompt = {}
            for sale in user_sales:
                prompt_id = sale.get("prompt_id")
                if prompt_id not in sales_by_prompt:
                    sales_by_prompt[prompt_id] = []
                sales_by_prompt[prompt_id].append(sale)
            
            # Get prompt details and calculate stats for each prompt
            prompt_sales = []
            for prompt_id, sales_list in sales_by_prompt.items():
                prompt = self.template_manager.get_template(prompt_id)
                if not prompt:
                    continue
                
                prompt_revenue = sum(s.get("price", 0) for s in sales_list)
                
                prompt_sales.append({
                    "prompt_id": prompt_id,
                    "prompt_name": prompt.name,
                    "price": prompt.price,
                    "sales_count": len(sales_list),
                    "revenue": prompt_revenue,
                    "last_sale": max(s.get("timestamp", "") for s in sales_list)
                })
            
            # Sort by revenue
            prompt_sales.sort(key=lambda x: x.get("revenue", 0), reverse=True)
            
            return {
                "success": True,
                "total_sales": len(user_sales),
                "total_revenue": total_revenue,
                "prompt_count": len(prompt_sales),
                "prompts": prompt_sales
            }
            
        except Exception as e:
            logger.error(f"Error getting user sales: {e}")
            return {
                "success": False,
                "error": str(e)
            }
    
    def record_prompt_usage(self, prompt_id: str, user_id: str, provider: str = None) -> bool:
        """

        Record usage of a prompt

        

        Args:

            prompt_id: ID of the prompt used

            user_id: ID of the user using the prompt

            provider: Optional provider used

            

        Returns:

            Success status

        """
        try:
            with open(self.stats_file, "r") as f:
                stats = json.load(f)
            
            # Update prompt usage stats
            prompt_usage = stats.get("prompt_usage", {})
            if prompt_id not in prompt_usage:
                prompt_usage[prompt_id] = {
                    "count": 0,
                    "purchases": 0,
                    "avg_rating": 0,
                    "review_count": 0
                }
            
            prompt_usage[prompt_id]["count"] = prompt_usage[prompt_id].get("count", 0) + 1
            prompt_usage[prompt_id]["last_used"] = datetime.now().isoformat()
            
            # Track provider usage if provided
            if provider:
                providers = prompt_usage[prompt_id].get("providers", {})
                providers[provider] = providers.get(provider, 0) + 1
                prompt_usage[prompt_id]["providers"] = providers
            
            # Save updated stats
            with open(self.stats_file, "w") as f:
                json.dump(stats, f, indent=2)
            
            return True
                
        except Exception as e:
            logger.error(f"Error recording prompt usage: {e}")
            return False
    
    def rate_prompt(self, prompt_id: str, user_id: str, rating: int, review: str = None) -> Dict[str, Any]:
        """

        Rate and review a prompt

        

        Args:

            prompt_id: ID of the prompt to rate

            user_id: ID of the user providing the rating

            rating: Rating value (1-5)

            review: Optional review text

            

        Returns:

            Result dictionary with success status

        """
        # Validate rating
        if rating < 1 or rating > 5:
            return {"success": False, "error": "Rating must be between 1 and 5"}
        
        # Check if the user owns the prompt
        if not self._user_owns_prompt(user_id, prompt_id):
            return {"success": False, "error": "You must purchase a prompt before rating it"}
        
        try:
            # Update the stats with the new rating
            with open(self.stats_file, "r") as f:
                stats = json.load(f)
            
            prompt_usage = stats.get("prompt_usage", {})
            if prompt_id not in prompt_usage:
                return {"success": False, "error": "Prompt not found"}
            
            # Calculate new average rating
            current_avg = prompt_usage[prompt_id].get("avg_rating", 0)
            current_count = prompt_usage[prompt_id].get("review_count", 0)
            
            if current_count == 0:
                new_avg = rating
            else:
                new_avg = (current_avg * current_count + rating) / (current_count + 1)
            
            prompt_usage[prompt_id]["avg_rating"] = new_avg
            prompt_usage[prompt_id]["review_count"] = current_count + 1
            
            # Save the review if provided
            if review:
                reviews = prompt_usage[prompt_id].get("reviews", [])
                reviews.append({
                    "user_id": user_id,
                    "rating": rating,
                    "review": review,
                    "timestamp": datetime.now().isoformat()
                })
                prompt_usage[prompt_id]["reviews"] = reviews
            
            # Save updated stats
            with open(self.stats_file, "w") as f:
                json.dump(stats, f, indent=2)
            
            return {
                "success": True,
                "message": "Rating submitted successfully",
                "new_rating": new_avg,
                "review_count": current_count + 1
            }
                
        except Exception as e:
            logger.error(f"Error rating prompt: {e}")
            return {
                "success": False,
                "error": str(e)
            }
    
    def get_marketplace_stats(self) -> Dict[str, Any]:
        """Get overall marketplace statistics"""
        try:
            with open(self.stats_file, "r") as f:
                stats = json.load(f)
            
            # Get the top prompts by usage
            prompt_usage = stats.get("prompt_usage", {})
            top_prompts = []
            
            for prompt_id, usage in prompt_usage.items():
                prompt = self.template_manager.get_template(prompt_id)
                if not prompt:
                    continue
                
                top_prompts.append({
                    "id": prompt_id,
                    "name": prompt.name,
                    "creator": prompt.created_by,
                    "category": prompt.category,
                    "price": prompt.price,
                    "usage_count": usage.get("count", 0),
                    "purchase_count": usage.get("purchases", 0),
                    "rating": usage.get("avg_rating", 0),
                    "review_count": usage.get("review_count", 0)
                })
            
            # Sort by usage count
            top_prompts.sort(key=lambda x: x.get("usage_count", 0), reverse=True)
            top_prompts = top_prompts[:10]  # Get top 10
            
            # Get top categories
            categories = stats.get("popular_categories", {})
            top_categories = [{"category": k, "count": v} for k, v in categories.items()]
            top_categories.sort(key=lambda x: x.get("count", 0), reverse=True)
            
            return {
                "success": True,
                "total_sales": stats.get("total_sales", 0),
                "total_revenue": stats.get("total_revenue", 0),
                "top_prompts": top_prompts,
                "top_categories": top_categories
            }
                
        except Exception as e:
            logger.error(f"Error getting marketplace stats: {e}")
            return {
                "success": False,
                "error": str(e)
            }

# Example usage
if __name__ == "__main__":
    # Initialize the marketplace
    marketplace = PromptMarketplace()
    
    # Create a sample prompt for sale
    prompt_result = marketplace.create_prompt_for_sale(
        name="Advanced SEO Article Writer",
        description="Generate comprehensive SEO-optimized articles with proper keyword placement and structure",
        template="Write a {length} word SEO-optimized article about {topic}. Target the keyword {keyword} with a keyword density of {density}%. Include {headings} headings, a compelling introduction, and a conclusion with call-to-action.",
        system_message="You are an expert SEO content writer who creates engaging, well-researched content that ranks well in search engines.",
        category="marketing",
        price=25.0,
        parameters={
            "topic": {"type": "string", "description": "Main topic of the article", "required": True},
            "keyword": {"type": "string", "description": "Target keyword to optimize for", "required": True},
            "length": {"type": "number", "description": "Word count", "default": 1500},
            "density": {"type": "number", "description": "Keyword density percentage", "default": 2},
            "headings": {"type": "number", "description": "Number of headings to include", "default": 5}
        },
        created_by="seller123",
        provider_defaults={
            "openai": {"model": "gpt-4-turbo"}
        }
    )
    
    print(f"Created prompt: {prompt_result['success']}")
    
    if prompt_result['success']:
        # Simulate a purchase
        purchase_result = marketplace.purchase_prompt(
            prompt_id=prompt_result['prompt']['id'],
            user_id="buyer456",
            credits_available=100.0
        )
        
        print(f"Purchase result: {purchase_result['success']}")
        
        # Record usage of the prompt
        marketplace.record_prompt_usage(
            prompt_id=prompt_result['prompt']['id'],
            user_id="buyer456",
            provider="openai"
        )
        
        # Rate the prompt
        rating_result = marketplace.rate_prompt(
            prompt_id=prompt_result['prompt']['id'],
            user_id="buyer456",
            rating=5,
            review="This prompt generated an excellent SEO article that ranked quickly!"
        )
        
        print(f"Rating result: {rating_result['success']}")
        
    # Get marketplace stats
    stats = marketplace.get_marketplace_stats()
    print(f"Marketplace stats: {stats['success']}")
    if stats['success']:
        print(f"Total sales: {stats['total_sales']}")