Skip to main content
Winnerr’s AI Assistant acts as a virtual real estate consultant, providing intelligent recommendations, automated insights, and contextual guidance to help agents maximize their productivity and close more deals.

AI Assistant Capabilities

Smart Recommendations

Context-aware suggestions for next actions, follow-ups, and deal strategies

Automated Insights

Real-time analysis of client behavior, market trends, and opportunity identification

Content Generation

AI-powered email templates, property descriptions, and marketing content

Decision Support

Data-driven recommendations for pricing, timing, and negotiation strategies

AI Assistant Architecture

Intelligent Recommendation Engine

Core AI Assistant Service

// lib/ai/ai-assistant-service.ts
export class AIAssistantService {
  private nlpEngine: NLPEngine;
  private recommendationEngine: RecommendationEngine;
  private marketAnalyzer: MarketAnalyzer;
  private contentGenerator: ContentGenerator;
  
  constructor() {
    this.nlpEngine = new NLPEngine();
    this.recommendationEngine = new RecommendationEngine();
    this.marketAnalyzer = new MarketAnalyzer();
    this.contentGenerator = new ContentGenerator();
  }
  
  async generateContextualRecommendations(
    userId: string,
    organizationId: string,
    context: AssistantContext
  ): Promise<AIRecommendations> {
    try {
      // Gather comprehensive user context
      const userContext = await this.gatherUserContext(userId, organizationId);
      
      // Analyze current situation
      const situationAnalysis = await this.analyzeSituation(userContext, context);
      
      // Generate targeted recommendations
      const recommendations = await this.generateRecommendations(
        userContext,
        situationAnalysis
      );
      
      // Prioritize and personalize
      const prioritizedRecommendations = await this.prioritizeRecommendations(
        recommendations,
        userContext
      );
      
      // Generate supporting content
      const supportingContent = await this.generateSupportingContent(
        prioritizedRecommendations,
        userContext
      );
      
      return {
        recommendations: prioritizedRecommendations,
        insights: situationAnalysis.insights,
        supportingContent,
        confidence: this.calculateConfidence(recommendations),
        generatedAt: new Date(),
        expiresAt: this.calculateExpiration(recommendations)
      };
      
    } catch (error) {
      log.error('AI Assistant recommendation generation failed', {
        userId,
        organizationId,
        error: parseError(error)
      });
      throw error;
    }
  }
  
  private async gatherUserContext(
    userId: string,
    organizationId: string
  ): Promise<UserContext> {
    // Gather comprehensive user data
    const user = await database.user.findUnique({
      where: { clerkId: userId },
      include: {
        OrganizationMembership: {
          where: { organizationId },
          include: {
            Organization: {
              include: {
                settings: true,
                promptSettings: true
              }
            }
          }
        }
      }
    });
    
    // Get recent activity
    const recentContacts = await database.person.findMany({
      where: { 
        organizationId,
        lastContactAt: {
          gte: new Date(Date.now() - 7 * 24 * 60 * 60 * 1000) // Last 7 days
        }
      },
      include: {
        deals: { where: { status: 'OPEN' } },
        communications: { 
          take: 5, 
          orderBy: { createdAt: 'desc' } 
        }
      },
      orderBy: { lastContactAt: 'desc' },
      take: 50
    });
    
    // Get active deals
    const activeDeals = await database.deal.findMany({
      where: { 
        organizationId,
        status: 'OPEN'
      },
      include: {
        person: true,
        property: true,
        tasks: { 
          where: { status: { not: 'COMPLETED' } },
          orderBy: { dueDate: 'asc' }
        }
      },
      orderBy: { lastStageChange: 'asc' }
    });
    
    // Get pending tasks
    const pendingTasks = await database.task.findMany({
      where: {
        organizationId,
        status: { not: 'COMPLETED' },
        dueDate: {
          lte: new Date(Date.now() + 7 * 24 * 60 * 60 * 1000) // Next 7 days
        }
      },
      include: {
        person: true,
        deal: true
      },
      orderBy: { dueDate: 'asc' }
    });
    
    // Get performance metrics
    const performanceMetrics = await this.gatherPerformanceMetrics(
      userId,
      organizationId
    );
    
    return {
      user,
      recentContacts,
      activeDeals,
      pendingTasks,
      performanceMetrics,
      marketConditions: await this.marketAnalyzer.getCurrentConditions(organizationId)
    };
  }
  
  private async analyzeSituation(
    userContext: UserContext,
    context: AssistantContext
  ): Promise<SituationAnalysis> {
    const insights: AssistantInsight[] = [];
    
    // Analyze deal pipeline health
    const pipelineAnalysis = this.analyzePipelineHealth(userContext.activeDeals);
    insights.push(...pipelineAnalysis);
    
    // Analyze contact engagement
    const engagementAnalysis = this.analyzeContactEngagement(userContext.recentContacts);
    insights.push(...engagementAnalysis);
    
    // Analyze task management
    const taskAnalysis = this.analyzeTaskManagement(userContext.pendingTasks);
    insights.push(...taskAnalysis);
    
    // Analyze market opportunities
    const marketAnalysis = await this.analyzeMarketOpportunities(userContext);
    insights.push(...marketAnalysis);
    
    // Performance gap analysis
    const performanceAnalysis = this.analyzePerformanceGaps(
      userContext.performanceMetrics
    );
    insights.push(...performanceAnalysis);
    
    return {
      insights,
      urgentItems: this.identifyUrgentItems(userContext),
      opportunities: this.identifyOpportunities(userContext),
      riskFactors: this.identifyRiskFactors(userContext),
      overallScore: this.calculateOverallHealth(insights)
    };
  }
  
  private async generateRecommendations(
    userContext: UserContext,
    situationAnalysis: SituationAnalysis
  ): Promise<AIRecommendation[]> {
    const recommendations: AIRecommendation[] = [];
    
    // High-priority urgent actions
    for (const urgentItem of situationAnalysis.urgentItems) {
      recommendations.push(await this.generateUrgentActionRecommendation(urgentItem));
    }
    
    // Opportunity-based recommendations
    for (const opportunity of situationAnalysis.opportunities) {
      recommendations.push(await this.generateOpportunityRecommendation(opportunity));
    }
    
    // Performance improvement recommendations
    for (const insight of situationAnalysis.insights) {
      if (insight.actionable) {
        recommendations.push(await this.generateImprovementRecommendation(insight));
      }
    }
    
    // Proactive recommendations
    const proactiveRecs = await this.generateProactiveRecommendations(userContext);
    recommendations.push(...proactiveRecs);
    
    return recommendations;
  }
  
  private async generateUrgentActionRecommendation(
    urgentItem: UrgentItem
  ): Promise<AIRecommendation> {
    return {
      id: generateId(),
      type: 'URGENT_ACTION',
      priority: 'HIGH',
      title: urgentItem.title,
      description: urgentItem.description,
      actionType: urgentItem.actionType,
      estimatedImpact: 'HIGH',
      estimatedEffort: urgentItem.effort,
      deadline: urgentItem.deadline,
      actions: [
        {
          type: urgentItem.actionType,
          label: urgentItem.actionLabel,
          url: urgentItem.actionUrl,
          params: urgentItem.actionParams
        }
      ],
      reasoning: urgentItem.reasoning,
      suggestedContent: await this.generateSuggestedContent(urgentItem)
    };
  }
  
  private async generateOpportunityRecommendation(
    opportunity: Opportunity
  ): Promise<AIRecommendation> {
    const suggestedActions = await this.generateOpportunityActions(opportunity);
    
    return {
      id: generateId(),
      type: 'OPPORTUNITY',
      priority: opportunity.priority,
      title: opportunity.title,
      description: opportunity.description,
      actionType: 'PURSUE_OPPORTUNITY',
      estimatedImpact: opportunity.estimatedValue,
      estimatedEffort: 'MEDIUM',
      deadline: opportunity.timeline,
      actions: suggestedActions,
      reasoning: opportunity.reasoning,
      supportingData: opportunity.data,
      suggestedContent: await this.generateOpportunityContent(opportunity)
    };
  }
  
  private async generateProactiveRecommendations(
    userContext: UserContext
  ): Promise<AIRecommendation[]> {
    const recommendations: AIRecommendation[] = [];
    
    // Market-based recommendations
    const marketRecs = await this.generateMarketRecommendations(userContext);
    recommendations.push(...marketRecs);
    
    // Relationship maintenance recommendations
    const relationshipRecs = await this.generateRelationshipRecommendations(userContext);
    recommendations.push(...relationshipRecs);
    
    // Content creation recommendations
    const contentRecs = await this.generateContentRecommendations(userContext);
    recommendations.push(...contentRecs);
    
    // Skill development recommendations
    const skillRecs = await this.generateSkillRecommendations(userContext);
    recommendations.push(...skillRecs);
    
    return recommendations;
  }
}

interface AIRecommendations {
  recommendations: AIRecommendation[];
  insights: AssistantInsight[];
  supportingContent: SupportingContent[];
  confidence: number;
  generatedAt: Date;
  expiresAt: Date;
}

interface AIRecommendation {
  id: string;
  type: 'URGENT_ACTION' | 'OPPORTUNITY' | 'IMPROVEMENT' | 'PROACTIVE';
  priority: 'HIGH' | 'MEDIUM' | 'LOW';
  title: string;
  description: string;
  actionType: string;
  estimatedImpact: 'HIGH' | 'MEDIUM' | 'LOW';
  estimatedEffort: 'HIGH' | 'MEDIUM' | 'LOW';
  deadline?: Date;
  actions: RecommendedAction[];
  reasoning: string;
  supportingData?: unknown;
  suggestedContent?: SuggestedContent;
}

interface AssistantInsight {
  id: string;
  category: 'PIPELINE' | 'CONTACTS' | 'PERFORMANCE' | 'MARKET' | 'TASKS';
  severity: 'INFO' | 'WARNING' | 'CRITICAL';
  title: string;
  description: string;
  actionable: boolean;
  impact: 'HIGH' | 'MEDIUM' | 'LOW';
  data?: unknown;
}

Smart Content Generation

AI-Powered Email Templates

// lib/ai/content-generator.ts
export class AIContentGenerator {
  private openAI: OpenAI;
  private templateEngine: TemplateEngine;
  
  constructor() {
    this.openAI = new OpenAI({
      apiKey: process.env.OPENAI_API_KEY
    });
    this.templateEngine = new TemplateEngine();
  }
  
  async generatePersonalizedEmail(
    context: EmailGenerationContext
  ): Promise<GeneratedEmail> {
    const prompt = this.buildEmailPrompt(context);
    
    const response = await this.openAI.chat.completions.create({
      model: MODEL_DEFAULTS.chat,
      messages: [
        {
          role: 'system',
          content: `You are an expert real estate email copywriter. Generate professional, 
          personalized emails that are engaging but not overly salesy. Focus on providing 
          value and building relationships. Keep emails concise and action-oriented.`
        },
        {
          role: 'user',
          content: prompt
        }
      ],
      temperature: 0.7,
      max_tokens: 500
    });
    
    const generatedContent = response.choices[0]?.message?.content || '';
    
    return {
      subject: this.extractSubject(generatedContent),
      body: this.extractBody(generatedContent),
      tone: context.preferredTone,
      personalization: context.personalizationData,
      suggestedFollowUp: this.generateFollowUpSuggestion(context),
      estimatedEngagement: this.estimateEngagementScore(generatedContent, context)
    };
  }
  
  private buildEmailPrompt(context: EmailGenerationContext): string {
    return `
    Generate a personalized email for the following scenario:
    
    **Recipient:** ${context.recipient.firstName} ${context.recipient.lastName}
    **Relationship Stage:** ${context.recipient.status}
    **Email Purpose:** ${context.purpose}
    **Key Context:** ${context.context}
    
    **Recipient Details:**
    - Location: ${context.recipient.city}, ${context.recipient.state}
    - Lead Source: ${context.recipient.source}
    - Last Contact: ${context.recipient.lastContactAt}
    - Lead Score: ${context.recipient.leadScore}/100
    
    **Recent Activity:**
    ${context.recentActivity?.map(activity => `- ${activity}`).join('\n') || 'No recent activity'}
    
    **Market Context:**
    - Current market conditions: ${context.marketConditions}
    - Recent comparable sales: ${context.marketData?.recentSales || 'None available'}
    
    **Instructions:**
    - Tone: ${context.preferredTone}
    - Include call-to-action: ${context.callToAction}
    - Reference: ${context.reference || 'None'}
    - Max length: 200 words
    - Include subject line
    
    Format as:
    SUBJECT: [subject line]
    BODY: [email body]
    `;
  }
  
  async generatePropertyDescription(
    property: Property,
    targetAudience: string
  ): Promise<PropertyDescription> {
    const prompt = `
    Write a compelling property description for:
    
    **Property Details:**
    - Address: ${property.address}
    - Type: ${property.propertyType}
    - Bedrooms: ${property.bedrooms}
    - Bathrooms: ${property.bathrooms}
    - Square Feet: ${property.squareFootage}
    - Lot Size: ${property.lotSize}
    - Year Built: ${property.yearBuilt}
    - Price: $${property.price?.toLocaleString()}
    
    **Key Features:**
    ${property.features?.map(feature => `- ${feature}`).join('\n') || ''}
    
    **Target Audience:** ${targetAudience}
    
    Requirements:
    - Highlight unique selling points
    - Use engaging, descriptive language
    - Include lifestyle benefits
    - Mention neighborhood/location advantages
    - Max 300 words
    - Include suggested hashtags for social media
    `;
    
    const response = await this.openAI.chat.completions.create({
      model: MODEL_DEFAULTS.chat,
      messages: [
        {
          role: 'system',
          content: `You are a professional real estate copywriter specializing in 
          property descriptions that sell. Write compelling, accurate descriptions 
          that highlight benefits and create emotional connection.`
        },
        {
          role: 'user',
          content: prompt
        }
      ],
      temperature: 0.8,
      max_tokens: 400
    });
    
    const content = response.choices[0]?.message?.content || '';
    
    return {
      description: content,
      keyHighlights: this.extractKeyHighlights(content),
      suggestedHashtags: this.extractHashtags(content),
      targetKeywords: this.generateTargetKeywords(property, targetAudience),
      tone: 'professional',
      estimatedEngagement: this.estimatePropertyDescriptionEngagement(content)
    };
  }
  
  async generateMarketInsightContent(
    marketData: MarketData,
    audience: 'buyers' | 'sellers' | 'investors'
  ): Promise<MarketInsightContent> {
    const prompt = `
    Create market insight content based on:
    
    **Market Data:**
    - Average Price: $${marketData.averagePrice?.toLocaleString()}
    - Price Change: ${marketData.priceChange}% vs last quarter
    - Days on Market: ${marketData.averageDaysOnMarket} days
    - Inventory: ${marketData.activeListings} active listings
    - Sales Volume: ${marketData.salesVolume} transactions this month
    
    **Market Trends:**
    ${marketData.trends?.map(trend => `- ${trend}`).join('\n') || ''}
    
    **Target Audience:** ${audience}
    
    Create:
    1. Executive summary (50 words)
    2. Key insights (3-4 bullet points)
    3. Actionable recommendations
    4. Market outlook
    
    Make it valuable and actionable for ${audience}.
    `;
    
    const response = await this.openAI.chat.completions.create({
      model: MODEL_DEFAULTS.chat,
      messages: [
        {
          role: 'system',
          content: `You are a real estate market analyst creating insightful, 
          data-driven content for real estate professionals and their clients.`
        },
        {
          role: 'user',
          content: prompt
        }
      ],
      temperature: 0.6,
      max_tokens: 600
    });
    
    return {
      content: response.choices[0]?.message?.content || '',
      audience,
      dataPoints: Object.keys(marketData),
      suggestedDistribution: this.suggestDistributionChannels(audience),
      followUpTopics: this.generateFollowUpTopics(marketData, audience)
    };
  }
}

interface GeneratedEmail {
  subject: string;
  body: string;
  tone: string;
  personalization: PersonalizationData;
  suggestedFollowUp: string;
  estimatedEngagement: number;
}

interface PropertyDescription {
  description: string;
  keyHighlights: string[];
  suggestedHashtags: string[];
  targetKeywords: string[];
  tone: string;
  estimatedEngagement: number;
}

interface MarketInsightContent {
  content: string;
  audience: string;
  dataPoints: string[];
  suggestedDistribution: string[];
  followUpTopics: string[];
}

Real-time Assistant Interface

AI Assistant Chat Component

// components/ai-assistant-chat.tsx
export function AIAssistantChat() {
  const [messages, setMessages] = useState<ChatMessage[]>([]);
  const [isTyping, setIsTyping] = useState(false);
  const [inputValue, setInputValue] = useState('');
  const [context, setContext] = useState<AssistantContext | null>(null);
  
  const { user, organization } = useAuth();
  const messagesEndRef = useRef<HTMLDivElement>(null);
  
  useEffect(() => {
    // Initialize with welcome message and recommendations
    initializeAssistant();
  }, []);
  
  useEffect(() => {
    scrollToBottom();
  }, [messages]);
  
  const initializeAssistant = async () => {
    try {
      const response = await fetch('/api/ai/assistant/initialize', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({
          userId: user.id,
          organizationId: organization.id
        })
      });
      
      const data = await response.json();
      
      setMessages([
        {
          id: generateId(),
          type: 'assistant',
          content: data.welcomeMessage,
          recommendations: data.initialRecommendations,
          timestamp: new Date()
        }
      ]);
      
      setContext(data.context);
      
    } catch (error) {
      console.error('Failed to initialize AI assistant:', error);
    }
  };
  
  const handleSendMessage = async () => {
    if (!inputValue.trim()) return;
    
    const userMessage: ChatMessage = {
      id: generateId(),
      type: 'user',
      content: inputValue,
      timestamp: new Date()
    };
    
    setMessages(prev => [...prev, userMessage]);
    setInputValue('');
    setIsTyping(true);
    
    try {
      const response = await fetch('/api/ai/assistant/chat', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({
          message: inputValue,
          context,
          conversationHistory: messages.slice(-10) // Last 10 messages for context
        })
      });
      
      const data = await response.json();
      
      const assistantMessage: ChatMessage = {
        id: generateId(),
        type: 'assistant',
        content: data.response,
        recommendations: data.recommendations,
        actions: data.suggestedActions,
        timestamp: new Date()
      };
      
      setMessages(prev => [...prev, assistantMessage]);
      setContext(data.updatedContext);
      
    } catch (error) {
      const errorMessage: ChatMessage = {
        id: generateId(),
        type: 'error',
        content: 'Sorry, I encountered an error. Please try again.',
        timestamp: new Date()
      };
      
      setMessages(prev => [...prev, errorMessage]);
    } finally {
      setIsTyping(false);
    }
  };
  
  const executeRecommendation = async (recommendation: AIRecommendation) => {
    try {
      await fetch('/api/ai/assistant/execute-recommendation', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({
          recommendationId: recommendation.id,
          action: recommendation.actions[0] // Execute first action
        })
      });
      
      toast.success('Action executed successfully');
      
      // Add confirmation message
      const confirmationMessage: ChatMessage = {
        id: generateId(),
        type: 'assistant',
        content: `✅ I've executed the recommendation: ${recommendation.title}`,
        timestamp: new Date()
      };
      
      setMessages(prev => [...prev, confirmationMessage]);
      
    } catch (error) {
      toast.error('Failed to execute recommendation');
    }
  };
  
  const scrollToBottom = () => {
    messagesEndRef.current?.scrollIntoView({ behavior: 'smooth' });
  };
  
  return (
    <div className="flex flex-col h-full max-h-[600px]">
      {/* Chat Header */}
      <div className="flex items-center justify-between p-4 border-b">
        <div className="flex items-center space-x-3">
          <div className="w-8 h-8 bg-blue-500 rounded-full flex items-center justify-center">
            <Bot className="h-5 w-5 text-white" />
          </div>
          <div>
            <h3 className="font-semibold">AI Assistant</h3>
            <p className="text-sm text-gray-500">
              {isTyping ? 'Thinking...' : 'Ready to help'}
            </p>
          </div>
        </div>
        
        <Button variant="ghost" size="sm">
          <Settings className="h-4 w-4" />
        </Button>
      </div>
      
      {/* Messages */}
      <div className="flex-1 overflow-y-auto p-4 space-y-4">
        {messages.map((message) => (
          <div
            key={message.id}
            className={`flex ${message.type === 'user' ? 'justify-end' : 'justify-start'}`}
          >
            <div
              className={`max-w-[80%] rounded-lg p-3 ${
                message.type === 'user'
                  ? 'bg-blue-500 text-white'
                  : message.type === 'error'
                  ? 'bg-red-100 text-red-800'
                  : 'bg-gray-100 text-gray-800'
              }`}
            >
              <p className="text-sm">{message.content}</p>
              
              {/* Recommendations */}
              {message.recommendations && message.recommendations.length > 0 && (
                <div className="mt-3 space-y-2">
                  <p className="text-xs font-semibold">Recommendations:</p>
                  {message.recommendations.map((rec) => (
                    <div
                      key={rec.id}
                      className="bg-white rounded border p-2 text-gray-800"
                    >
                      <div className="flex items-start justify-between">
                        <div className="flex-1">
                          <p className="text-xs font-medium">{rec.title}</p>
                          <p className="text-xs text-gray-600 mt-1">
                            {rec.description}
                          </p>
                        </div>
                        <Badge
                          variant={rec.priority === 'HIGH' ? 'destructive' : 'secondary'}
                          className="text-xs"
                        >
                          {rec.priority}
                        </Badge>
                      </div>
                      
                      {rec.actions && rec.actions.length > 0 && (
                        <div className="mt-2 flex space-x-2">
                          {rec.actions.map((action, index) => (
                            <Button
                              key={index}
                              size="sm"
                              variant="outline"
                              onClick={() => executeRecommendation(rec)}
                              className="text-xs"
                            >
                              {action.label}
                            </Button>
                          ))}
                        </div>
                      )}
                    </div>
                  ))}
                </div>
              )}
              
              <p className="text-xs opacity-70 mt-2">
                {formatDistanceToNow(message.timestamp)} ago
              </p>
            </div>
          </div>
        ))}
        
        {isTyping && (
          <div className="flex justify-start">
            <div className="bg-gray-100 rounded-lg p-3">
              <div className="flex space-x-1">
                <div className="w-2 h-2 bg-gray-400 rounded-full animate-bounce" />
                <div className="w-2 h-2 bg-gray-400 rounded-full animate-bounce" style={{ animationDelay: '0.1s' }} />
                <div className="w-2 h-2 bg-gray-400 rounded-full animate-bounce" style={{ animationDelay: '0.2s' }} />
              </div>
            </div>
          </div>
        )}
        
        <div ref={messagesEndRef} />
      </div>
      
      {/* Input */}
      <div className="border-t p-4">
        <div className="flex space-x-2">
          <Input
            value={inputValue}
            onChange={(e) => setInputValue(e.target.value)}
            placeholder="Ask me anything about your real estate business..."
            onKeyDown={(e) => {
              if (e.key === 'Enter' && !e.shiftKey) {
                e.preventDefault();
                handleSendMessage();
              }
            }}
            className="flex-1"
          />
          <Button
            onClick={handleSendMessage}
            disabled={!inputValue.trim() || isTyping}
            size="sm"
          >
            <Send className="h-4 w-4" />
          </Button>
        </div>
        
        {/* Quick Actions */}
        <div className="flex flex-wrap gap-2 mt-2">
          <Button
            variant="outline"
            size="sm"
            onClick={() => setInputValue('Show me my hot leads')}
            className="text-xs"
          >
            Hot Leads
          </Button>
          <Button
            variant="outline"
            size="sm"
            onClick={() => setInputValue('What deals need attention?')}
            className="text-xs"
          >
            Deal Health
          </Button>
          <Button
            variant="outline"
            size="sm"
            onClick={() => setInputValue('Generate market report')}
            className="text-xs"
          >
            Market Report
          </Button>
        </div>
      </div>
    </div>
  );
}

interface ChatMessage {
  id: string;
  type: 'user' | 'assistant' | 'error';
  content: string;
  recommendations?: AIRecommendation[];
  actions?: RecommendedAction[];
  timestamp: Date;
}

Recommendation Dashboard

AI Insights Widget

// components/ai-insights-dashboard.tsx
export function AIInsightsDashboard() {
  const { data: insights } = useQuery({
    queryKey: ['ai-insights'],
    queryFn: () => fetch('/api/ai/insights/dashboard').then(res => res.json()),
    refetchInterval: 5 * 60 * 1000 // Refresh every 5 minutes
  });
  
  const [filter, setFilter] = useState<'all' | 'urgent' | 'opportunities' | 'improvements'>('all');
  
  const filteredInsights = useMemo(() => {
    if (!insights?.recommendations) return [];
    
    switch (filter) {
      case 'urgent':
        return insights.recommendations.filter((r: AIRecommendation) => r.priority === 'HIGH');
      case 'opportunities':
        return insights.recommendations.filter((r: AIRecommendation) => r.type === 'OPPORTUNITY');
      case 'improvements':
        return insights.recommendations.filter((r: AIRecommendation) => r.type === 'IMPROVEMENT');
      default:
        return insights.recommendations;
    }
  }, [insights, filter]);
  
  return (
    <div className="space-y-6">
      {/* AI Health Score */}
      <Card>
        <CardHeader>
          <CardTitle className="flex items-center space-x-2">
            <Brain className="h-5 w-5" />
            <span>AI Business Health Score</span>
          </CardTitle>
        </CardHeader>
        <CardContent>
          <div className="flex items-center space-x-4">
            <div className="relative w-16 h-16">
              <CircularProgressbar
                value={insights?.healthScore || 0}
                text={`${insights?.healthScore || 0}`}
                styles={buildStyles({
                  textSize: '24px',
                  pathColor: getHealthScoreColor(insights?.healthScore || 0),
                  textColor: getHealthScoreColor(insights?.healthScore || 0)
                })}
              />
            </div>
            <div className="flex-1">
              <p className="text-sm text-gray-600">
                {getHealthScoreDescription(insights?.healthScore || 0)}
              </p>
              <div className="mt-2 flex space-x-4 text-xs">
                <div>
                  <span className="text-gray-500">Pipeline Health:</span>
                  <span className="ml-1 font-medium">{insights?.pipelineHealth || 0}/100</span>
                </div>
                <div>
                  <span className="text-gray-500">Activity Score:</span>
                  <span className="ml-1 font-medium">{insights?.activityScore || 0}/100</span>
                </div>
                <div>
                  <span className="text-gray-500">Engagement:</span>
                  <span className="ml-1 font-medium">{insights?.engagementScore || 0}/100</span>
                </div>
              </div>
            </div>
          </div>
        </CardContent>
      </Card>
      
      {/* Quick Stats */}
      <div className="grid grid-cols-1 md:grid-cols-4 gap-4">
        <Card>
          <CardContent className="pt-4">
            <div className="flex items-center justify-between">
              <div>
                <p className="text-sm text-gray-600">Active Recommendations</p>
                <p className="text-2xl font-bold">{insights?.stats?.activeRecommendations || 0}</p>
              </div>
              <Lightbulb className="h-8 w-8 text-yellow-500" />
            </div>
          </CardContent>
        </Card>
        
        <Card>
          <CardContent className="pt-4">
            <div className="flex items-center justify-between">
              <div>
                <p className="text-sm text-gray-600">Opportunities Identified</p>
                <p className="text-2xl font-bold">{insights?.stats?.opportunities || 0}</p>
              </div>
              <Target className="h-8 w-8 text-green-500" />
            </div>
          </CardContent>
        </Card>
        
        <Card>
          <CardContent className="pt-4">
            <div className="flex items-center justify-between">
              <div>
                <p className="text-sm text-gray-600">Actions Taken</p>
                <p className="text-2xl font-bold">{insights?.stats?.actionsTaken || 0}</p>
              </div>
              <CheckCircle className="h-8 w-8 text-blue-500" />
            </div>
          </CardContent>
        </Card>
        
        <Card>
          <CardContent className="pt-4">
            <div className="flex items-center justify-between">
              <div>
                <p className="text-sm text-gray-600">Success Rate</p>
                <p className="text-2xl font-bold">{insights?.stats?.successRate || 0}%</p>
              </div>
              <TrendingUp className="h-8 w-8 text-purple-500" />
            </div>
          </CardContent>
        </Card>
      </div>
      
      {/* Filters */}
      <div className="flex space-x-2">
        {(['all', 'urgent', 'opportunities', 'improvements'] as const).map((filterType) => (
          <Button
            key={filterType}
            variant={filter === filterType ? 'default' : 'outline'}
            size="sm"
            onClick={() => setFilter(filterType)}
            className="capitalize"
          >
            {filterType === 'all' ? 'All' : filterType}
          </Button>
        ))}
      </div>
      
      {/* Recommendations List */}
      <div className="space-y-4">
        {filteredInsights.map((recommendation: AIRecommendation) => (
          <Card key={recommendation.id} className="hover:shadow-md transition-shadow">
            <CardContent className="pt-4">
              <div className="flex items-start justify-between">
                <div className="flex-1">
                  <div className="flex items-center space-x-2 mb-2">
                    <Badge
                      variant={recommendation.priority === 'HIGH' ? 'destructive' : 'secondary'}
                    >
                      {recommendation.priority}
                    </Badge>
                    <Badge variant="outline">
                      {recommendation.type.replace('_', ' ')}
                    </Badge>
                  </div>
                  
                  <h3 className="font-semibold mb-1">{recommendation.title}</h3>
                  <p className="text-sm text-gray-600 mb-3">
                    {recommendation.description}
                  </p>
                  
                  <div className="flex items-center space-x-4 text-xs text-gray-500 mb-3">
                    <div className="flex items-center space-x-1">
                      <Target className="h-3 w-3" />
                      <span>Impact: {recommendation.estimatedImpact}</span>
                    </div>
                    <div className="flex items-center space-x-1">
                      <Clock className="h-3 w-3" />
                      <span>Effort: {recommendation.estimatedEffort}</span>
                    </div>
                    {recommendation.deadline && (
                      <div className="flex items-center space-x-1">
                        <Calendar className="h-3 w-3" />
                        <span>Due: {formatDistanceToNow(recommendation.deadline)}</span>
                      </div>
                    )}
                  </div>
                  
                  <div className="text-xs text-gray-600 bg-gray-50 p-2 rounded">
                    <strong>Reasoning:</strong> {recommendation.reasoning}
                  </div>
                </div>
                
                <div className="ml-4">
                  <DropdownMenu>
                    <DropdownMenuTrigger asChild>
                      <Button variant="ghost" size="sm">
                        <MoreHorizontal className="h-4 w-4" />
                      </Button>
                    </DropdownMenuTrigger>
                    <DropdownMenuContent>
                      {recommendation.actions.map((action, index) => (
                        <DropdownMenuItem key={index}>
                          {action.label}
                        </DropdownMenuItem>
                      ))}
                      <DropdownMenuSeparator />
                      <DropdownMenuItem>Dismiss</DropdownMenuItem>
                      <DropdownMenuItem>Snooze</DropdownMenuItem>
                    </DropdownMenuContent>
                  </DropdownMenu>
                </div>
              </div>
            </CardContent>
          </Card>
        ))}
      </div>
    </div>
  );
}

const getHealthScoreColor = (score: number): string => {
  if (score >= 80) return '#10b981';
  if (score >= 60) return '#f59e0b';
  return '#ef4444';
};

const getHealthScoreDescription = (score: number): string => {
  if (score >= 80) return 'Your business is performing excellently! Keep up the great work.';
  if (score >= 60) return 'Good performance with room for improvement in some areas.';
  return 'Several areas need attention to optimize your business performance.';
};

Next Steps

Predictive Models

Explore market prediction and forecasting capabilities

Communication Hub

See how AI integrates with communication features

Analytics Dashboard

Comprehensive business analytics and reporting

The AI Assistant transforms real estate productivity by providing intelligent, context-aware recommendations and automating routine decision-making processes.