<?php
/**
 * Contrôleur Webhook
 * Gestion des webhooks WhatsApp et autres services
 */

namespace App\Controllers;

use Core\Controller;
use App\Services\WhatsAppService;
use App\Services\AIVoiceAgent;
use App\Models\Entreprise;
use App\Models\Client;
use App\Models\Conversation;

require_once APP_PATH . '/Services/WhatsAppService.php';
require_once APP_PATH . '/Services/AIVoiceAgent.php';
require_once APP_PATH . '/Models/Entreprise.php';
require_once APP_PATH . '/Models/Client.php';
require_once APP_PATH . '/Models/Conversation.php';

class WebhookController extends Controller
{
    private WhatsAppService $whatsappService;
    private AIVoiceAgent $aiAgent;
    private Entreprise $entrepriseModel;
    private Client $clientModel;
    private Conversation $conversationModel;
    
    public function __construct()
    {
        parent::__construct();
        $this->whatsappService = new WhatsAppService();
        $this->aiAgent = new AIVoiceAgent();
        $this->entrepriseModel = new Entreprise();
        $this->clientModel = new Client();
        $this->conversationModel = new Conversation();
    }
    
    /**
     * Webhook WhatsApp (Twilio)
     */
    public function whatsapp(): void
    {
        header('Content-Type: text/xml');
        
        // Parser le message entrant
        $incoming = $this->whatsappService->parseIncomingMessage($_POST);
        
        if (empty($incoming['body']) && $incoming['num_media'] === 0) {
            $this->respondTwiML('');
            return;
        }
        
        // Identifier l'entreprise par le numéro Twilio destinataire
        $entreprise = $this->findEntrepriseByWhatsAppNumber($incoming['to']);
        
        if (!$entreprise) {
            // Si pas trouvé, utiliser l'entreprise par défaut ou première active
            $entreprise = $this->getDefaultEntreprise();
        }
        
        if (!$entreprise) {
            $this->respondTwiML("Désolé, ce service n'est pas disponible.");
            return;
        }
        
        // Vérifier que WhatsApp est activé pour cette entreprise
        $canaux = json_decode($entreprise['canaux_actifs'] ?? '[]', true);
        if (!in_array('whatsapp', $canaux)) {
            $this->respondTwiML("Ce canal n'est pas activé pour cette entreprise.");
            return;
        }
        
        // Trouver ou créer le client
        $client = $this->findOrCreateClient($entreprise['id'], $incoming);
        
        // Trouver ou créer la conversation
        $conversation = $this->findOrCreateConversation($entreprise['id'], $client['id']);
        
        // Sauvegarder le message client
        $messageContent = $incoming['body'];
        if ($incoming['num_media'] > 0) {
            $messageContent .= "\n[Média reçu: " . ($incoming['media_type'] ?? 'fichier') . "]";
        }
        $this->saveMessage($conversation['id'], 'client', $messageContent, $incoming);
        
        // Générer la réponse
        $response = $this->generateResponse($entreprise, $client, $conversation, $incoming);
        
        // Sauvegarder la réponse
        $this->saveMessage($conversation['id'], 'bot', $response, ['ai_generated' => true]);
        
        // Répondre via TwiML
        $this->respondTwiML($response);
    }
    
    /**
     * Générer une réponse (IA ou standard)
     */
    private function generateResponse(array $entreprise, array $client, array $conversation, array $incoming): string
    {
        $message = $incoming['body'];
        
        // Vérifier si l'IA est activée
        $iaConfig = json_decode($entreprise['ia_config'] ?? '{}', true);
        $iaEnabled = $iaConfig['enabled'] ?? false;
        
        if ($iaEnabled && $this->aiAgent->isConfigured()) {
            // Utiliser l'agent IA
            $response = $this->aiAgent->generateResponse(
                $entreprise['id'],
                $message,
                'whatsapp_' . $conversation['id'],
                $client['langue_preferee'] ?? 'fr'
            );
            
            // Analyser l'intention
            $intent = $this->aiAgent->analyzeIntent($message);
            
            if ($intent['intent'] === 'transfer_human') {
                $response .= "\n\n_Un agent va prendre en charge votre demande._";
                $this->escalateConversation($conversation['id']);
            }
            
            return $response;
        }
        
        // Réponse par défaut si IA non activée
        return $this->getDefaultResponse($entreprise, $message);
    }
    
    /**
     * Réponse par défaut (sans IA)
     */
    private function getDefaultResponse(array $entreprise, string $message): string
    {
        $nom = $entreprise['nom'] ?? 'Notre service';
        
        // Rechercher dans la FAQ
        $faq = $this->searchFAQ($entreprise['id'], $message);
        if ($faq) {
            return $faq['reponse'];
        }
        
        // Message générique
        return "Merci de contacter {$nom}. Votre message a bien été reçu. Un agent vous répondra dans les plus brefs délais.";
    }
    
    /**
     * Rechercher dans la FAQ
     */
    private function searchFAQ(int $entrepriseId, string $query): ?array
    {
        $query = strtolower($query);
        
        $result = $this->db->query(
            "SELECT * FROM faq 
             WHERE entreprise_id = :eid AND is_active = 1
             ORDER BY views_count DESC",
            ['eid' => $entrepriseId]
        );
        
        $faqs = $result->fetchAll(\PDO::FETCH_ASSOC);
        
        foreach ($faqs as $faq) {
            $keywords = json_decode($faq['keywords'] ?? '[]', true) ?: [];
            $question = strtolower($faq['question']);
            
            // Correspondance par mots-clés
            foreach ($keywords as $keyword) {
                if (strpos($query, strtolower($keyword)) !== false) {
                    $this->incrementFAQViews($faq['id']);
                    return $faq;
                }
            }
            
            // Correspondance par question
            if (similar_text($query, $question) / strlen($question) > 0.5) {
                $this->incrementFAQViews($faq['id']);
                return $faq;
            }
        }
        
        return null;
    }
    
    /**
     * Incrémenter les vues FAQ
     */
    private function incrementFAQViews(int $faqId): void
    {
        $this->db->query(
            "UPDATE faq SET views_count = views_count + 1 WHERE id = :id",
            ['id' => $faqId]
        );
    }
    
    /**
     * Trouver l'entreprise par numéro WhatsApp
     */
    private function findEntrepriseByWhatsAppNumber(string $number): ?array
    {
        $number = preg_replace('/[^0-9+]/', '', $number);
        
        $result = $this->db->query(
            "SELECT * FROM entreprises 
             WHERE twilio_whatsapp_number = :num OR twilio_phone_number = :num2
             AND is_active = 1 
             LIMIT 1",
            ['num' => $number, 'num2' => $number]
        );
        
        return $result->fetch(\PDO::FETCH_ASSOC) ?: null;
    }
    
    /**
     * Obtenir l'entreprise par défaut
     */
    private function getDefaultEntreprise(): ?array
    {
        $result = $this->db->query(
            "SELECT * FROM entreprises 
             WHERE is_active = 1 
             ORDER BY id ASC 
             LIMIT 1"
        );
        
        return $result->fetch(\PDO::FETCH_ASSOC) ?: null;
    }
    
    /**
     * Trouver ou créer un client
     */
    private function findOrCreateClient(int $entrepriseId, array $incoming): array
    {
        $phone = $incoming['from'];
        $waId = $incoming['wa_id'] ?? $phone;
        $name = $incoming['profile_name'] ?? null;
        
        // Chercher par whatsapp_id
        $result = $this->db->query(
            "SELECT * FROM clients 
             WHERE entreprise_id = :eid AND (whatsapp_id = :waid OR telephone = :phone)
             LIMIT 1",
            ['eid' => $entrepriseId, 'waid' => $waId, 'phone' => $phone]
        );
        
        $client = $result->fetch(\PDO::FETCH_ASSOC);
        
        if ($client) {
            // Mettre à jour le nom si disponible
            if ($name && empty($client['nom'])) {
                $this->db->query(
                    "UPDATE clients SET nom = :nom, updated_at = NOW() WHERE id = :id",
                    ['nom' => $name, 'id' => $client['id']]
                );
                $client['nom'] = $name;
            }
            return $client;
        }
        
        // Créer un nouveau client
        $this->db->query(
            "INSERT INTO clients (entreprise_id, whatsapp_id, telephone, nom, created_at)
             VALUES (:eid, :waid, :phone, :nom, NOW())",
            ['eid' => $entrepriseId, 'waid' => $waId, 'phone' => $phone, 'nom' => $name]
        );
        
        return [
            'id' => $this->db->lastInsertId(),
            'entreprise_id' => $entrepriseId,
            'whatsapp_id' => $waId,
            'telephone' => $phone,
            'nom' => $name,
            'langue_preferee' => 'fr'
        ];
    }
    
    /**
     * Trouver ou créer une conversation
     */
    private function findOrCreateConversation(int $entrepriseId, int $clientId): array
    {
        // Chercher une conversation ouverte récente
        $result = $this->db->query(
            "SELECT * FROM conversations 
             WHERE entreprise_id = :eid AND client_id = :cid 
             AND canal = 'whatsapp' AND statut IN ('open', 'in_progress')
             AND created_at > DATE_SUB(NOW(), INTERVAL 24 HOUR)
             ORDER BY created_at DESC 
             LIMIT 1",
            ['eid' => $entrepriseId, 'cid' => $clientId]
        );
        
        $conversation = $result->fetch(\PDO::FETCH_ASSOC);
        
        if ($conversation) {
            return $conversation;
        }
        
        // Créer une nouvelle conversation
        $this->db->query(
            "INSERT INTO conversations (entreprise_id, client_id, canal, statut, created_at)
             VALUES (:eid, :cid, 'whatsapp', 'open', NOW())",
            ['eid' => $entrepriseId, 'cid' => $clientId]
        );
        
        return [
            'id' => $this->db->lastInsertId(),
            'entreprise_id' => $entrepriseId,
            'client_id' => $clientId,
            'canal' => 'whatsapp',
            'statut' => 'open'
        ];
    }
    
    /**
     * Sauvegarder un message
     */
    private function saveMessage(int $conversationId, string $senderType, string $content, array $metadata = []): void
    {
        $this->db->query(
            "INSERT INTO messages (conversation_id, sender_type, contenu, type_message, metadata, created_at)
             VALUES (:cid, :sender, :contenu, 'text', :meta, NOW())",
            [
                'cid' => $conversationId,
                'sender' => $senderType,
                'contenu' => $content,
                'meta' => json_encode($metadata)
            ]
        );
        
        // Mettre à jour la conversation
        $this->db->query(
            "UPDATE conversations SET updated_at = NOW() WHERE id = :id",
            ['id' => $conversationId]
        );
    }
    
    /**
     * Escalader la conversation vers un agent
     */
    private function escalateConversation(int $conversationId): void
    {
        $this->db->query(
            "UPDATE conversations 
             SET is_escalated = 1, statut = 'in_progress', escalation_reason = 'Demande client WhatsApp'
             WHERE id = :id",
            ['id' => $conversationId]
        );
    }
    
    /**
     * Répondre avec TwiML
     */
    private function respondTwiML(string $message): void
    {
        echo '<?xml version="1.0" encoding="UTF-8"?>';
        echo '<Response>';
        if (!empty($message)) {
            echo '<Message>' . htmlspecialchars($message) . '</Message>';
        }
        echo '</Response>';
    }
}
