from fastapi import APIRouter, HTTPException, Depends, Query from app.models import ChatbotPublicResponse, MarketplaceResponse, RatingCreate from app.database import get_supabase from app.dependencies import get_optional_user, get_current_user from typing import Optional import logging logger = logging.getLogger(__name__) router = APIRouter(prefix="/marketplace", tags=["Marketplace"]) CATEGORIES = [ "Customer Support", "Sales", "FAQ", "E-commerce", "Healthcare", "Finance", "Education", "HR", "Legal", "Other" ] INDUSTRIES = [ "Technology", "E-commerce", "Healthcare", "Finance", "Education", "Legal", "Real Estate", "Hospitality", "Retail", "Other" ] @router.get("/chatbots", response_model=MarketplaceResponse) async def list_marketplace_chatbots( category: Optional[str] = Query(None), industry: Optional[str] = Query(None), language: Optional[str] = Query(None), search: Optional[str] = Query(None), page: int = Query(1, ge=1), limit: int = Query(20, ge=1, le=100), user=Depends(get_optional_user), ): supabase = get_supabase() query = supabase.table("chatbots").select( "*, companies(name, logo_url)" ).eq("is_published", True).eq("visibility", "published") if category: query = query.eq("category", category) if industry: query = query.eq("industry", industry) if search: query = query.ilike("name", f"%{search}%") offset = (page - 1) * limit result = query.order("created_at", desc=True).range(offset, offset + limit - 1).execute() all_result = supabase.table("chatbots").select("id", count="exact").eq("is_published", True).execute() total = all_result.count or 0 chatbots = [] for c in (result.data or []): company_data = c.get("companies") or {} chatbots.append( ChatbotPublicResponse( id=c["id"], name=c["name"], description=c.get("description"), category=c.get("category"), industry=c.get("industry"), languages=c.get("languages", ["en"]), primary_color=c.get("primary_color", "#6366f1"), welcome_message=c.get("welcome_message", "Hello!"), average_rating=c.get("average_rating"), total_conversations=c.get("total_conversations", 0), company_name=company_data.get("name"), company_logo=company_data.get("logo_url"), created_at=c.get("created_at"), published_at=c.get("published_at"), ) ) return MarketplaceResponse( chatbots=chatbots, total=total, page=page, limit=limit, has_more=(offset + limit) < total, ) @router.get("/chatbots/{chatbot_id}", response_model=ChatbotPublicResponse) async def get_marketplace_chatbot(chatbot_id: str): supabase = get_supabase() result = supabase.table("chatbots").select("*, companies(name, logo_url)") \ .eq("id", chatbot_id) \ .eq("is_published", True) \ .execute() if not result.data: raise HTTPException(status_code=404, detail="Chatbot not found in marketplace") c = result.data[0] company_data = c.get("companies") or {} return ChatbotPublicResponse( id=c["id"], name=c["name"], description=c.get("description"), category=c.get("category"), industry=c.get("industry"), languages=c.get("languages", ["en"]), primary_color=c.get("primary_color", "#6366f1"), welcome_message=c.get("welcome_message", "Hello!"), average_rating=c.get("average_rating"), total_conversations=c.get("total_conversations", 0), company_name=company_data.get("name"), company_logo=company_data.get("logo_url"), created_at=c.get("created_at"), published_at=c.get("published_at"), ) @router.get("/categories") async def get_categories(): return {"categories": CATEGORIES, "industries": INDUSTRIES} @router.post("/chatbots/{chatbot_id}/rate") async def rate_chatbot( chatbot_id: str, rating: RatingCreate, user=Depends(get_current_user), ): supabase = get_supabase() chatbot = supabase.table("chatbots").select("id, average_rating").eq("id", chatbot_id).eq("is_published", True).execute() if not chatbot.data: raise HTTPException(status_code=404, detail="Chatbot not found") # Simple rating update (average) current = chatbot.data[0].get("average_rating") or rating.rating new_avg = (current + rating.rating) / 2 supabase.table("chatbots").update({"average_rating": round(new_avg, 1)}).eq("id", chatbot_id).execute() return {"message": "Rating submitted", "new_average": round(new_avg, 1)}