<?php

namespace App\Services\AI;

use App\Models\Conversation;
use App\Models\ConversationMessage;
use App\Models\AIInsight;
use Illuminate\Support\Facades\Storage;
use Illuminate\Support\Facades\Log;

class TrainingDataService
{
    private $trainingDataPath;
    private $phi3Service;

    public function __construct(Phi3Service $phi3Service)
    {
        $this->phi3Service = $phi3Service;
        $this->trainingDataPath = storage_path('app/ai/training');
        $this->ensureTrainingDirectory();
    }

    /**
     * Collect training data from conversations
     */
    public function collectTrainingData(int $userId = null, int $days = 30): array
    {
        try {
            $query = Conversation::with(['messages', 'insights', 'user'])
                ->where('created_at', '>=', now()->subDays($days));

            if ($userId) {
                $query->where('user_id', $userId);
            }

            $conversations = $query->get();
            
            $trainingData = [
                'conversations' => [],
                'insights' => [],
                'patterns' => [],
                'statistics' => []
            ];

            foreach ($conversations as $conversation) {
                $conversationData = $this->extractConversationData($conversation);
                $trainingData['conversations'][] = $conversationData;
            }

            // Extract insights and patterns
            $trainingData['insights'] = $this->extractInsights($conversations);
            $trainingData['patterns'] = $this->extractPatterns($conversations);
            $trainingData['statistics'] = $this->generateStatistics($conversations);

            // Save to file
            $this->saveTrainingData($trainingData);

            return [
                'success' => true,
                'data' => $trainingData,
                'conversations_processed' => $conversations->count(),
                'file_path' => $this->getTrainingDataFilePath()
            ];

        } catch (\Exception $e) {
            Log::error('Training Data Collection Error: ' . $e->getMessage());
            return [
                'success' => false,
                'error' => 'Failed to collect training data: ' . $e->getMessage()
            ];
        }
    }

    /**
     * Generate fine-tuning dataset for the AI model
     */
    public function generateFineTuningDataset(int $userId = null): array
    {
        try {
            $conversations = Conversation::with(['messages', 'insights'])
                ->where('user_id', $userId ?? '>', 0)
                ->where('status', 'completed')
                ->orderBy('created_at', 'desc')
                ->limit(100)
                ->get();

            $dataset = [];
            
            foreach ($conversations as $conversation) {
                $messages = $conversation->messages->sortBy('timestamp');
                $conversationText = $this->formatConversationForTraining($messages, $conversation->type);
                
                if (!empty($conversationText)) {
                    $dataset[] = [
                        'conversation_id' => $conversation->id,
                        'type' => $conversation->type,
                        'text' => $conversationText,
                        'insights' => $conversation->insights->pluck('content')->toArray(),
                        'sentiment' => $conversation->sentiment_score,
                        'outcome' => $conversation->outcome
                    ];
                }
            }

            // Save dataset
            $datasetPath = $this->trainingDataPath . '/fine_tuning_dataset.json';
            file_put_contents($datasetPath, json_encode($dataset, JSON_PRETTY_PRINT));

            return [
                'success' => true,
                'dataset' => $dataset,
                'total_conversations' => count($dataset),
                'file_path' => $datasetPath
            ];

        } catch (\Exception $e) {
            Log::error('Fine-tuning Dataset Generation Error: ' . $e->getMessage());
            return [
                'success' => false,
                'error' => 'Failed to generate fine-tuning dataset: ' . $e->getMessage()
            ];
        }
    }

    /**
     * Analyze conversation patterns for improvement
     */
    public function analyzeConversationPatterns(int $userId = null): array
    {
        try {
            $conversations = Conversation::with(['messages', 'insights'])
                ->where('user_id', $userId ?? '>', 0)
                ->where('created_at', '>=', now()->subDays(30))
                ->get();

            $patterns = [
                'common_questions' => $this->extractCommonQuestions($conversations),
                'successful_patterns' => $this->extractSuccessfulPatterns($conversations),
                'problem_areas' => $this->identifyProblemAreas($conversations),
                'improvement_suggestions' => $this->generateImprovementSuggestions($conversations)
            ];

            return [
                'success' => true,
                'patterns' => $patterns,
                'conversations_analyzed' => $conversations->count()
            ];

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

    /**
     * Create custom training prompts based on collected data
     */
    public function generateCustomPrompts(int $userId = null): array
    {
        try {
            $conversations = Conversation::with(['messages', 'insights'])
                ->where('user_id', $userId ?? '>', 0)
                ->where('status', 'completed')
                ->get();

            $prompts = [
                'sales' => $this->generateSalesPrompts($conversations),
                'support' => $this->generateSupportPrompts($conversations),
                'general' => $this->generateGeneralPrompts($conversations)
            ];

            // Save prompts
            $promptsPath = $this->trainingDataPath . '/custom_prompts.json';
            file_put_contents($promptsPath, json_encode($prompts, JSON_PRETTY_PRINT));

            return [
                'success' => true,
                'prompts' => $prompts,
                'file_path' => $promptsPath
            ];

        } catch (\Exception $e) {
            Log::error('Custom Prompts Generation Error: ' . $e->getMessage());
            return [
                'success' => false,
                'error' => 'Failed to generate custom prompts: ' . $e->getMessage()
            ];
        }
    }

    // Private helper methods

    private function ensureTrainingDirectory(): void
    {
        if (!is_dir($this->trainingDataPath)) {
            mkdir($this->trainingDataPath, 0755, true);
        }
    }

    private function extractConversationData(Conversation $conversation): array
    {
        $messages = $conversation->messages->sortBy('timestamp');
        
        return [
            'id' => $conversation->id,
            'type' => $conversation->type,
            'status' => $conversation->status,
            'duration' => $conversation->duration_seconds,
            'sentiment_score' => $conversation->sentiment_score,
            'satisfaction_score' => $conversation->satisfaction_score,
            'outcome' => $conversation->outcome,
            'messages' => $messages->map(function($message) {
                return [
                    'role' => $message->role,
                    'content' => $message->content,
                    'sentiment' => $message->sentiment,
                    'confidence' => $message->confidence_score,
                    'timestamp' => $message->timestamp
                ];
            })->toArray(),
            'insights' => $conversation->insights->map(function($insight) {
                return [
                    'type' => $insight->insight_type,
                    'content' => $insight->content,
                    'confidence' => $insight->confidence_score
                ];
            })->toArray()
        ];
    }

    private function extractInsights($conversations): array
    {
        $insights = [];
        
        foreach ($conversations as $conversation) {
            foreach ($conversation->insights as $insight) {
                $insights[$insight->insight_type][] = [
                    'content' => $insight->content,
                    'confidence' => $insight->confidence_score,
                    'conversation_id' => $conversation->id
                ];
            }
        }

        return $insights;
    }

    private function extractPatterns($conversations): array
    {
        $patterns = [
            'conversation_lengths' => [],
            'response_times' => [],
            'sentiment_distribution' => [],
            'common_topics' => []
        ];

        foreach ($conversations as $conversation) {
            $patterns['conversation_lengths'][] = $conversation->total_messages;
            $patterns['sentiment_distribution'][] = $conversation->sentiment_score ?? 0.5;
            
            // Extract topics from insights
            $topics = $conversation->insights->where('insight_type', 'entity')->pluck('content');
            foreach ($topics as $topic) {
                $patterns['common_topics'][] = $topic;
            }
        }

        return $patterns;
    }

    private function generateStatistics($conversations): array
    {
        return [
            'total_conversations' => $conversations->count(),
            'avg_duration' => $conversations->avg('duration_seconds'),
            'avg_sentiment' => $conversations->avg('sentiment_score'),
            'completion_rate' => $conversations->where('status', 'completed')->count() / max($conversations->count(), 1) * 100,
            'conversation_types' => $conversations->groupBy('type')->map->count(),
            'date_range' => [
                'start' => $conversations->min('created_at'),
                'end' => $conversations->max('created_at')
            ]
        ];
    }

    private function saveTrainingData(array $data): void
    {
        $filename = 'training_data_' . date('Y_m_d_H_i_s') . '.json';
        $filepath = $this->trainingDataPath . '/' . $filename;
        file_put_contents($filepath, json_encode($data, JSON_PRETTY_PRINT));
    }

    private function getTrainingDataFilePath(): string
    {
        $files = glob($this->trainingDataPath . '/training_data_*.json');
        return end($files) ?: '';
    }

    private function formatConversationForTraining($messages, string $type): string
    {
        $formatted = "Conversation Type: {$type}\n\n";
        
        foreach ($messages as $message) {
            $role = $message->role === 'assistant' ? 'AI' : 'User';
            $formatted .= "{$role}: {$message->content}\n";
        }
        
        return $formatted;
    }

    private function extractCommonQuestions($conversations): array
    {
        $questions = [];
        
        foreach ($conversations as $conversation) {
            $userMessages = $conversation->messages->where('role', 'user');
            foreach ($userMessages as $message) {
                if (str_contains($message->content, '?')) {
                    $questions[] = $message->content;
                }
            }
        }

        return array_count_values($questions);
    }

    private function extractSuccessfulPatterns($conversations): array
    {
        $successfulConversations = $conversations->where('status', 'completed')
            ->where('satisfaction_score', '>', 0.7);

        $patterns = [];
        
        foreach ($successfulConversations as $conversation) {
            $aiMessages = $conversation->messages->where('role', 'assistant');
            foreach ($aiMessages as $message) {
                $patterns[] = [
                    'response' => $message->content,
                    'sentiment' => $message->sentiment,
                    'conversation_type' => $conversation->type
                ];
            }
        }

        return $patterns;
    }

    private function identifyProblemAreas($conversations): array
    {
        $problems = [];
        
        $lowSatisfactionConversations = $conversations->where('satisfaction_score', '<', 0.5);
        
        foreach ($lowSatisfactionConversations as $conversation) {
            $problems[] = [
                'conversation_id' => $conversation->id,
                'satisfaction_score' => $conversation->satisfaction_score,
                'sentiment_score' => $conversation->sentiment_score,
                'outcome' => $conversation->outcome
            ];
        }

        return $problems;
    }

    private function generateImprovementSuggestions($conversations): array
    {
        $suggestions = [];
        
        $avgSentiment = $conversations->avg('sentiment_score');
        $completionRate = $conversations->where('status', 'completed')->count() / max($conversations->count(), 1) * 100;

        if ($avgSentiment < 0.5) {
            $suggestions[] = 'Improve response tone and empathy in AI responses';
        }

        if ($completionRate < 70) {
            $suggestions[] = 'Focus on better conversation flow and goal achievement';
        }

        $suggestions[] = 'Collect more training data for better personalization';
        $suggestions[] = 'Implement real-time feedback collection';

        return $suggestions;
    }

    private function generateSalesPrompts($conversations): array
    {
        return [
            'system_prompt' => 'You are a professional sales AI assistant for DizzCall AI CRM. Focus on understanding customer needs, qualifying leads, and guiding them through the sales process.',
            'qualification_questions' => [
                'What challenges are you currently facing with your current solution?',
                'What is your timeline for implementing a new solution?',
                'Who else is involved in the decision-making process?',
                'What is your budget range for this project?'
            ],
            'objection_handling' => [
                'Price concerns: "I understand budget is important. Let me show you the ROI of our solution..."',
                'Timeline concerns: "I appreciate your timeline. Let me explain how we can expedite the process..."',
                'Feature concerns: "That\'s a great question. Let me demonstrate how our solution addresses that specific need..."'
            ]
        ];
    }

    private function generateSupportPrompts($conversations): array
    {
        return [
            'system_prompt' => 'You are a helpful customer support AI assistant. Focus on resolving issues quickly, providing clear solutions, and ensuring customer satisfaction.',
            'troubleshooting_steps' => [
                'First, gather detailed information about the issue',
                'Provide step-by-step troubleshooting instructions',
                'Escalate to human support if needed',
                'Follow up to ensure resolution'
            ],
            'common_solutions' => [
                'Login issues: Check credentials and reset password if needed',
                'Feature questions: Provide clear documentation and examples',
                'Technical problems: Gather system information and escalate'
            ]
        ];
    }

    private function generateGeneralPrompts($conversations): array
    {
        return [
            'system_prompt' => 'You are a helpful AI assistant for DizzCall AI CRM. Be professional, friendly, and provide accurate information.',
            'conversation_starters' => [
                'How can I help you today?',
                'What would you like to know about our services?',
                'Is there anything specific you\'d like assistance with?'
            ],
            'fallback_responses' => [
                'I\'m not sure I understand. Could you please rephrase that?',
                'Let me connect you with a human specialist for that question.',
                'I\'d be happy to help. Could you provide more details?'
            ]
        ];
    }
}
