<?php
/**
 * Service d'intégration OpenAI
 * mySupport - Plateforme de Service Client Intelligent
 */

namespace Core;

class OpenAIService
{
    private string $apiKey;
    private string $model;
    private int $maxTokens;
    private float $temperature;
    
    public function __construct()
    {
        $this->apiKey = OPENAI_API_KEY;
        $this->model = OPENAI_MODEL;
        $this->maxTokens = OPENAI_MAX_TOKENS;
        $this->temperature = OPENAI_TEMPERATURE;
    }
    
    /**
     * Vérifie si l'API est configurée
     */
    public function isConfigured(): bool
    {
        return !empty($this->apiKey);
    }
    
    /**
     * Génère une réponse IA pour un message client
     */
    public function generateResponse(string $message, array $context = []): array
    {
        if (!$this->isConfigured()) {
            return [
                'success' => false,
                'error' => 'API OpenAI non configurée',
                'fallback' => true
            ];
        }
        
        $systemPrompt = $this->buildSystemPrompt($context);
        $messages = $this->buildMessages($systemPrompt, $message, $context['history'] ?? []);
        
        try {
            $response = $this->callAPI($messages);
            
            if (isset($response['error'])) {
                return [
                    'success' => false,
                    'error' => $response['error']['message'] ?? 'Erreur API',
                    'fallback' => true
                ];
            }
            
            $content = $response['choices'][0]['message']['content'] ?? '';
            $shouldEscalate = $this->shouldEscalateToHuman($content, $message);
            
            return [
                'success' => true,
                'message' => $content,
                'should_escalate' => $shouldEscalate,
                'tokens_used' => $response['usage']['total_tokens'] ?? 0
            ];
            
        } catch (\Exception $e) {
            return [
                'success' => false,
                'error' => $e->getMessage(),
                'fallback' => true
            ];
        }
    }
    
    /**
     * Construit le prompt système personnalisé
     */
    private function buildSystemPrompt(array $context): string
    {
        $prompt = OPENAI_SYSTEM_PROMPT;
        
        $entreprise = $context['entreprise_nom'] ?? 'notre entreprise';
        $contexteEntreprise = $context['entreprise_contexte'] ?? 'Service client général';
        
        $prompt = str_replace('{entreprise}', $entreprise, $prompt);
        $prompt = str_replace('{contexte}', $contexteEntreprise, $prompt);
        
        // Ajouter le ton si spécifié
        if (!empty($context['ton'])) {
            $tonInstructions = [
                'professionnel' => 'Adopte un ton professionnel et courtois.',
                'amical' => 'Adopte un ton amical et chaleureux, comme un ami qui aide.',
                'formel' => 'Adopte un ton très formel et respectueux.'
            ];
            $prompt .= "\n\nTon de communication: " . ($tonInstructions[$context['ton']] ?? $tonInstructions['professionnel']);
        }

        // Ajouter les instructions spéciales si disponibles
        if (!empty($context['instructions'])) {
            $prompt .= "\n\nInstructions spéciales: " . $context['instructions'];
        }

        // Ajouter les FAQ si disponibles
        if (!empty($context['faq'])) {
            $prompt .= "\n\nFAQ de l'entreprise:\n";
            foreach ($context['faq'] as $faq) {
                $prompt .= "Q: {$faq['question']}\nR: {$faq['reponse']}\n\n";
            }
        }

        // Ajouter les documents de la base de connaissances
        if (!empty($context['documents'])) {
            $prompt .= "\n\nDocumentation et informations supplémentaires:\n";
            foreach ($context['documents'] as $doc) {
                $prompt .= "--- {$doc['titre']} ---\n";
                if (!empty($doc['description'])) {
                    $prompt .= "Description: {$doc['description']}\n";
                }
                // Limiter le contenu de chaque document pour éviter de dépasser les limites de tokens
                $contenu = $doc['contenu_extrait'] ?? '';
                if (strlen($contenu) > 3000) {
                    $contenu = substr($contenu, 0, 3000) . '...';
                }
                $prompt .= "Contenu: {$contenu}\n\n";
            }
        }
        
        return $prompt;
    }
    
    /**
     * Construit le tableau de messages pour l'API
     */
    private function buildMessages(string $systemPrompt, string $currentMessage, array $history = []): array
    {
        $messages = [
            ['role' => 'system', 'content' => $systemPrompt]
        ];
        
        // Ajouter l'historique (max 10 derniers messages)
        $recentHistory = array_slice($history, -10);
        foreach ($recentHistory as $msg) {
            $role = $msg['sender_type'] === 'client' ? 'user' : 'assistant';
            $messages[] = [
                'role' => $role,
                'content' => $msg['contenu']
            ];
        }
        
        // Ajouter le message actuel
        $messages[] = [
            'role' => 'user',
            'content' => $currentMessage
        ];
        
        return $messages;
    }
    
    /**
     * Appelle l'API OpenAI
     */
    private function callAPI(array $messages): array
    {
        $url = 'https://api.openai.com/v1/chat/completions';
        
        $data = [
            'model' => $this->model,
            'messages' => $messages,
            'max_tokens' => $this->maxTokens,
            'temperature' => $this->temperature
        ];
        
        $ch = curl_init($url);
        curl_setopt_array($ch, [
            CURLOPT_RETURNTRANSFER => true,
            CURLOPT_POST => true,
            CURLOPT_HTTPHEADER => [
                'Content-Type: application/json',
                'Authorization: Bearer ' . $this->apiKey
            ],
            CURLOPT_POSTFIELDS => json_encode($data),
            CURLOPT_TIMEOUT => 30
        ]);
        
        $response = curl_exec($ch);
        $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
        $error = curl_error($ch);
        curl_close($ch);
        
        if ($error) {
            throw new \Exception("Erreur cURL: $error");
        }
        
        if ($httpCode !== 200) {
            $decoded = json_decode($response, true);
            throw new \Exception($decoded['error']['message'] ?? "Erreur HTTP: $httpCode");
        }
        
        return json_decode($response, true);
    }
    
    /**
     * Détermine si la conversation doit être escaladée à un humain
     */
    private function shouldEscalateToHuman(string $aiResponse, string $userMessage): bool
    {
        $escalationKeywords = [
            'agent humain', 'parler à quelqu\'un', 'représentant',
            'je ne peux pas', 'je ne suis pas en mesure',
            'transférer', 'escalader', 'réclamation',
            'plainte', 'urgent', 'problème grave'
        ];
        
        $combinedText = strtolower($aiResponse . ' ' . $userMessage);
        
        foreach ($escalationKeywords as $keyword) {
            if (strpos($combinedText, strtolower($keyword)) !== false) {
                return true;
            }
        }
        
        return false;
    }
    
    /**
     * Génère une réponse de fallback si l'IA n'est pas disponible
     */
    public function getFallbackResponse(string $message): string
    {
        $responses = [
            "Merci pour votre message. Un agent va vous répondre dans les plus brefs délais.",
            "Votre demande a bien été reçue. Notre équipe vous contactera rapidement.",
            "Merci de nous avoir contactés. Nous traitons votre demande.",
        ];
        
        return $responses[array_rand($responses)];
    }
    
    /**
     * Analyse le sentiment d'un message
     */
    public function analyzeSentiment(string $message): string
    {
        if (!$this->isConfigured()) {
            return 'neutral';
        }
        
        $prompt = "Analyse le sentiment de ce message et réponds uniquement par un mot: positive, negative, ou neutral.\n\nMessage: \"$message\"";
        
        try {
            $response = $this->callAPI([
                ['role' => 'user', 'content' => $prompt]
            ]);
            
            $sentiment = strtolower(trim($response['choices'][0]['message']['content'] ?? 'neutral'));
            
            if (in_array($sentiment, ['positive', 'negative', 'neutral'])) {
                return $sentiment;
            }
            
            return 'neutral';
            
        } catch (\Exception $e) {
            return 'neutral';
        }
    }
}
