<?php

namespace App\Services\AI;

use App\Models\User;
use App\Models\Call;
use App\Models\Conversation;
use App\Models\AIInsight;
use Illuminate\Support\Facades\Log;

class CRMIntelligenceService
{
    private $phi3Service;

    public function __construct(Phi3Service $phi3Service)
    {
        $this->phi3Service = $phi3Service;
    }

    /**
     * Analyze customer behavior and preferences
     */
    public function analyzeCustomerBehavior(int $userId, array $conversationData = []): array
    {
        try {
            $user = User::find($userId);
            if (!$user) {
                return ['success' => false, 'error' => 'User not found'];
            }

            // Get conversation history
            $conversations = Conversation::where('user_id', $userId)
                ->with(['messages', 'insights'])
                ->orderBy('created_at', 'desc')
                ->limit(20)
                ->get();

            // Analyze call patterns
            $callPatterns = $this->analyzeCallPatterns($userId);
            
            // Analyze conversation themes
            $conversationThemes = $this->analyzeConversationThemes($conversations);
            
            // Generate customer profile
            $customerProfile = $this->generateCustomerProfile($user, $conversations, $callPatterns);

            return [
                'success' => true,
                'customer_profile' => $customerProfile,
                'call_patterns' => $callPatterns,
                'conversation_themes' => $conversationThemes,
                'recommendations' => $this->generateCustomerRecommendations($customerProfile)
            ];

        } catch (\Exception $e) {
            Log::error('CRM Intelligence Error: ' . $e->getMessage());
            return [
                'success' => false,
                'error' => 'Failed to analyze customer behavior: ' . $e->getMessage()
            ];
        }
    }

    /**
     * Generate lead scoring based on AI analysis
     */
    public function generateLeadScore(int $userId, array $conversationContext = []): array
    {
        try {
            $user = User::find($userId);
            if (!$user) {
                return ['success' => false, 'error' => 'User not found'];
            }

            // Get recent conversations and insights
            $recentInsights = AIInsight::whereHas('conversation', function($query) use ($userId) {
                $query->where('user_id', $userId);
            })
            ->where('created_at', '>=', now()->subDays(30))
            ->get();

            // Analyze engagement level
            $engagementScore = $this->calculateEngagementScore($userId);
            
            // Analyze interest indicators
            $interestScore = $this->calculateInterestScore($recentInsights);
            
            // Analyze urgency indicators
            $urgencyScore = $this->calculateUrgencyScore($recentInsights);
            
            // Calculate overall lead score
            $leadScore = ($engagementScore * 0.4) + ($interestScore * 0.4) + ($urgencyScore * 0.2);
            
            // Determine lead status
            $leadStatus = $this->determineLeadStatus($leadScore);

            return [
                'success' => true,
                'lead_score' => round($leadScore, 2),
                'lead_status' => $leadStatus,
                'engagement_score' => $engagementScore,
                'interest_score' => $interestScore,
                'urgency_score' => $urgencyScore,
                'recommendations' => $this->getLeadRecommendations($leadStatus, $leadScore)
            ];

        } catch (\Exception $e) {
            Log::error('Lead Scoring Error: ' . $e->getMessage());
            return [
                'success' => false,
                'error' => 'Failed to generate lead score: ' . $e->getMessage()
            ];
        }
    }

    /**
     * Generate conversation suggestions based on context
     */
    public function generateConversationSuggestions(int $userId, string $conversationType, array $context = []): array
    {
        try {
            $suggestions = [];
            
            // Get user's conversation history
            $conversationHistory = Conversation::where('user_id', $userId)
                ->where('type', $conversationType)
                ->with(['messages', 'insights'])
                ->orderBy('created_at', 'desc')
                ->limit(10)
                ->get();

            // Generate AI-powered suggestions
            $prompt = $this->buildSuggestionPrompt($conversationType, $context, $conversationHistory);
            $aiResponse = $this->phi3Service->generateResponse($prompt, [], 'crm');

            if ($aiResponse['success']) {
                $suggestions = $this->parseSuggestions($aiResponse['response']);
            }

            // Add fallback suggestions
            $fallbackSuggestions = $this->getFallbackSuggestions($conversationType);

            return [
                'success' => true,
                'suggestions' => array_merge($suggestions, $fallbackSuggestions),
                'context' => $context,
                'conversation_type' => $conversationType
            ];

        } catch (\Exception $e) {
            Log::error('Conversation Suggestions Error: ' . $e->getMessage());
            return [
                'success' => true,
                'suggestions' => $this->getFallbackSuggestions($conversationType),
                'context' => $context,
                'conversation_type' => $conversationType
            ];
        }
    }

    /**
     * Analyze conversation sentiment trends
     */
    public function analyzeSentimentTrends(int $userId, int $days = 30): array
    {
        try {
            $conversations = Conversation::where('user_id', $userId)
                ->where('created_at', '>=', now()->subDays($days))
                ->with(['messages' => function($query) {
                    $query->whereNotNull('sentiment');
                }])
                ->get();

            $sentimentData = [];
            $dailySentiment = [];

            foreach ($conversations as $conversation) {
                $messages = $conversation->messages;
                $sentimentCounts = $messages->groupBy('sentiment')->map->count();
                
                $totalMessages = $messages->count();
                if ($totalMessages > 0) {
                    $sentimentData[] = [
                        'conversation_id' => $conversation->id,
                        'date' => $conversation->created_at->format('Y-m-d'),
                        'sentiment_breakdown' => $sentimentCounts->toArray(),
                        'avg_sentiment' => $this->calculateAverageSentiment($sentimentCounts)
                    ];
                }
            }

            // Group by date
            $groupedData = collect($sentimentData)->groupBy('date');
            
            foreach ($groupedData as $date => $conversations) {
                $dailySentiment[$date] = [
                    'positive' => $conversations->sum('sentiment_breakdown.positive'),
                    'negative' => $conversations->sum('sentiment_breakdown.negative'),
                    'neutral' => $conversations->sum('sentiment_breakdown.neutral'),
                    'avg_sentiment' => $conversations->avg('avg_sentiment')
                ];
            }

            return [
                'success' => true,
                'daily_sentiment' => $dailySentiment,
                'overall_trend' => $this->calculateSentimentTrend($dailySentiment),
                'insights' => $this->generateSentimentInsights($dailySentiment)
            ];

        } catch (\Exception $e) {
            Log::error('Sentiment Analysis Error: ' . $e->getMessage());
            return [
                'success' => false,
                'error' => 'Failed to analyze sentiment trends: ' . $e->getMessage()
            ];
        }
    }

    /**
     * Generate personalized follow-up recommendations
     */
    public function generateFollowUpRecommendations(int $userId): array
    {
        try {
            $user = User::find($userId);
            $recentConversations = Conversation::where('user_id', $userId)
                ->where('status', 'completed')
                ->with(['insights'])
                ->orderBy('created_at', 'desc')
                ->limit(5)
                ->get();

            $recommendations = [];

            foreach ($recentConversations as $conversation) {
                $insights = $conversation->insights;
                $actionItems = $insights->where('insight_type', 'action_item');
                $nextSteps = $insights->where('insight_type', 'next_step');

                if ($actionItems->count() > 0 || $nextSteps->count() > 0) {
                    $recommendations[] = [
                        'conversation_id' => $conversation->id,
                        'type' => 'follow_up',
                        'priority' => 'high',
                        'action_items' => $actionItems->pluck('content')->toArray(),
                        'next_steps' => $nextSteps->pluck('content')->toArray(),
                        'suggested_timing' => $this->suggestFollowUpTiming($conversation),
                        'recommended_approach' => $this->suggestFollowUpApproach($insights)
                    ];
                }
            }

            return [
                'success' => true,
                'recommendations' => $recommendations,
                'total_recommendations' => count($recommendations)
            ];

        } catch (\Exception $e) {
            Log::error('Follow-up Recommendations Error: ' . $e->getMessage());
            return [
                'success' => false,
                'error' => 'Failed to generate follow-up recommendations: ' . $e->getMessage()
            ];
        }
    }

    // Private helper methods

    private function analyzeCallPatterns(int $userId): array
    {
        $calls = Call::where('user_id', $userId)
            ->where('created_at', '>=', now()->subDays(30))
            ->get();

        return [
            'total_calls' => $calls->count(),
            'avg_duration' => $calls->avg('duration') ?? 0,
            'peak_hours' => $this->getPeakHours($calls),
            'call_frequency' => $this->getCallFrequency($calls),
            'success_rate' => $calls->where('status', 'completed')->count() / max($calls->count(), 1) * 100
        ];
    }

    private function analyzeConversationThemes($conversations): array
    {
        $themes = [];
        foreach ($conversations as $conversation) {
            $insights = $conversation->insights;
            $intents = $insights->where('insight_type', 'intent');
            $entities = $insights->where('insight_type', 'entity');
            
            $themes[] = [
                'conversation_id' => $conversation->id,
                'intents' => $intents->pluck('content')->toArray(),
                'entities' => $entities->pluck('content')->toArray(),
                'sentiment' => $conversation->sentiment_score
            ];
        }

        return $themes;
    }

    private function generateCustomerProfile($user, $conversations, $callPatterns): array
    {
        return [
            'user_id' => $user->id,
            'name' => $user->name,
            'company' => $user->company_name ?? 'N/A',
            'conversation_count' => $conversations->count(),
            'avg_sentiment' => $conversations->avg('sentiment_score') ?? 0,
            'preferred_communication_time' => $callPatterns['peak_hours'] ?? 'Unknown',
            'engagement_level' => $this->calculateEngagementLevel($conversations),
            'interests' => $this->extractInterests($conversations),
            'pain_points' => $this->extractPainPoints($conversations)
        ];
    }

    private function calculateEngagementScore(int $userId): float
    {
        $conversations = Conversation::where('user_id', $userId)
            ->where('created_at', '>=', now()->subDays(30))
            ->get();

        $totalMessages = $conversations->sum('total_messages');
        $activeDays = $conversations->groupBy(function($item) {
            return $item->created_at->format('Y-m-d');
        })->count();

        return min(($totalMessages / max($activeDays, 1)) * 0.1, 1.0);
    }

    private function calculateInterestScore($insights): float
    {
        $interestIndicators = $insights->whereIn('insight_type', ['interest', 'solution', 'budget', 'timeline']);
        return min($interestIndicators->count() * 0.2, 1.0);
    }

    private function calculateUrgencyScore($insights): float
    {
        $urgencyIndicators = $insights->whereIn('insight_type', ['urgency', 'timeline', 'follow_up']);
        return min($urgencyIndicators->count() * 0.3, 1.0);
    }

    private function determineLeadStatus(float $leadScore): string
    {
        if ($leadScore >= 0.8) return 'hot';
        if ($leadScore >= 0.6) return 'warm';
        if ($leadScore >= 0.4) return 'cool';
        return 'cold';
    }

    private function getLeadRecommendations(string $leadStatus, float $leadScore): array
    {
        $recommendations = [
            'hot' => [
                'Schedule immediate follow-up call',
                'Prepare detailed proposal',
                'Involve senior team members',
                'Set up product demo'
            ],
            'warm' => [
                'Send relevant case studies',
                'Schedule follow-up in 2-3 days',
                'Address any objections',
                'Provide additional information'
            ],
            'cool' => [
                'Send educational content',
                'Schedule follow-up in 1-2 weeks',
                'Focus on relationship building',
                'Identify specific needs'
            ],
            'cold' => [
                'Send nurturing content',
                'Schedule follow-up in 2-4 weeks',
                'Re-engage with different approach',
                'Qualify interest level'
            ]
        ];

        return $recommendations[$leadStatus] ?? [];
    }

    private function buildSuggestionPrompt(string $conversationType, array $context, $conversationHistory): string
    {
        $prompt = "Based on the conversation context and history, suggest 5 specific conversation topics or questions for a {$conversationType} call. ";
        $prompt .= "Context: " . json_encode($context) . " ";
        $prompt .= "Previous conversations: " . $conversationHistory->count() . " conversations. ";
        $prompt .= "Return as JSON array of suggestions with 'topic' and 'reason' fields.";

        return $prompt;
    }

    private function parseSuggestions(string $response): array
    {
        $suggestions = json_decode($response, true);
        return is_array($suggestions) ? $suggestions : [];
    }

    private function getFallbackSuggestions(string $conversationType): array
    {
        $suggestions = [
            'sales' => [
                ['topic' => 'Current challenges', 'reason' => 'Understand pain points'],
                ['topic' => 'Budget and timeline', 'reason' => 'Qualify opportunity'],
                ['topic' => 'Decision-making process', 'reason' => 'Identify stakeholders'],
                ['topic' => 'Competitive landscape', 'reason' => 'Position against competitors'],
                ['topic' => 'Next steps', 'reason' => 'Move deal forward']
            ],
            'support' => [
                ['topic' => 'Current issue details', 'reason' => 'Understand the problem'],
                ['topic' => 'Impact on business', 'reason' => 'Prioritize resolution'],
                ['topic' => 'Previous solutions tried', 'reason' => 'Avoid repetition'],
                ['topic' => 'Timeline expectations', 'reason' => 'Set proper expectations'],
                ['topic' => 'Follow-up process', 'reason' => 'Ensure resolution']
            ]
        ];

        return $suggestions[$conversationType] ?? [];
    }

    private function calculateAverageSentiment($sentimentCounts): float
    {
        $total = $sentimentCounts->sum();
        if ($total === 0) return 0.5;

        $positive = $sentimentCounts->get('positive', 0);
        $negative = $sentimentCounts->get('negative', 0);
        
        return ($positive - $negative + $total) / ($total * 2);
    }

    private function calculateSentimentTrend(array $dailySentiment): string
    {
        $values = array_values($dailySentiment);
        if (count($values) < 2) return 'stable';

        $first = $values[0]['avg_sentiment'] ?? 0.5;
        $last = end($values)['avg_sentiment'] ?? 0.5;

        if ($last > $first + 0.1) return 'improving';
        if ($last < $first - 0.1) return 'declining';
        return 'stable';
    }

    private function generateSentimentInsights(array $dailySentiment): array
    {
        $insights = [];
        
        if (count($dailySentiment) > 7) {
            $recent = array_slice($dailySentiment, -7);
            $avgSentiment = array_sum(array_column($recent, 'avg_sentiment')) / count($recent);
            
            if ($avgSentiment > 0.7) {
                $insights[] = 'Customer sentiment has been very positive recently';
            } elseif ($avgSentiment < 0.3) {
                $insights[] = 'Customer sentiment has been negative - immediate attention needed';
            }
        }

        return $insights;
    }

    private function suggestFollowUpTiming($conversation): string
    {
        $insights = $conversation->insights;
        $urgency = $insights->where('insight_type', 'urgency')->first();
        
        if ($urgency) {
            return 'Within 24 hours';
        }
        
        return 'Within 2-3 business days';
    }

    private function suggestFollowUpApproach($insights): string
    {
        $objections = $insights->where('insight_type', 'objection');
        $interests = $insights->where('insight_type', 'interest');
        
        if ($objections->count() > 0) {
            return 'Address objections with specific solutions';
        }
        
        if ($interests->count() > 0) {
            return 'Build on expressed interests with detailed information';
        }
        
        return 'General follow-up to maintain relationship';
    }

    private function getPeakHours($calls): array
    {
        $hours = $calls->groupBy(function($call) {
            return $call->created_at->format('H');
        })->map->count();

        return $hours->sortDesc()->take(3)->keys()->toArray();
    }

    private function getCallFrequency($calls): string
    {
        $days = $calls->groupBy(function($call) {
            return $call->created_at->format('Y-m-d');
        })->count();

        if ($days === 0) return 'No calls';
        if ($days <= 3) return 'Low';
        if ($days <= 7) return 'Medium';
        return 'High';
    }

    private function calculateEngagementLevel($conversations): string
    {
        $avgMessages = $conversations->avg('total_messages');
        
        if ($avgMessages >= 10) return 'High';
        if ($avgMessages >= 5) return 'Medium';
        return 'Low';
    }

    private function extractInterests($conversations): array
    {
        $interests = [];
        foreach ($conversations as $conversation) {
            $interestInsights = $conversation->insights->where('insight_type', 'interest');
            foreach ($interestInsights as $insight) {
                $interests[] = $insight->content;
            }
        }
        return array_unique($interests);
    }

    private function extractPainPoints($conversations): array
    {
        $painPoints = [];
        foreach ($conversations as $conversation) {
            $painPointInsights = $conversation->insights->where('insight_type', 'pain_point');
            foreach ($painPointInsights as $insight) {
                $painPoints[] = $insight->content;
            }
        }
        return array_unique($painPoints);
    }

    private function generateCustomerRecommendations(array $customerProfile): array
    {
        $recommendations = [];
        
        $engagementLevel = $customerProfile['engagement_level'] ?? 'Low';
        $avgSentiment = $customerProfile['avg_sentiment'] ?? 0.5;
        
        if ($engagementLevel === 'Low') {
            $recommendations[] = 'Increase engagement through personalized content and regular check-ins';
        }
        
        if ($avgSentiment < 0.5) {
            $recommendations[] = 'Focus on improving customer satisfaction and addressing concerns';
        }
        
        if (!empty($customerProfile['interests'])) {
            $recommendations[] = 'Leverage identified interests: ' . implode(', ', $customerProfile['interests']);
        }
        
        if (!empty($customerProfile['pain_points'])) {
            $recommendations[] = 'Address pain points: ' . implode(', ', $customerProfile['pain_points']);
        }
        
        $recommendations[] = 'Continue monitoring conversation patterns for optimization';
        
        return $recommendations;
    }
}
