<?php
/**
 * Controller Agent
 * mySupport - Plateforme de Service Client Intelligent
 */

namespace App\Controllers;

use Core\Controller;
use App\Models\Conversation;
use App\Models\Message;
use App\Models\Client;
use App\Models\User;
use App\Services\EscalationService;

require_once APP_PATH . '/Models/Conversation.php';
require_once APP_PATH . '/Models/Message.php';
require_once APP_PATH . '/Models/Client.php';
require_once APP_PATH . '/Models/User.php';
require_once APP_PATH . '/Services/EscalationService.php';

class AgentController extends Controller
{
    private Conversation $conversationModel;
    private Message $messageModel;
    private Client $clientModel;
    private User $userModel;
    private EscalationService $escalationService;
    private int $entrepriseId;
    private int $agentId;

    public function __construct()
    {
        parent::__construct();
        $this->requireRole(ROLE_AGENT);
        
        $this->entrepriseId = $_SESSION['entreprise_id'];
        $this->agentId = $_SESSION['user_id'];
        
        $this->conversationModel = new Conversation();
        $this->messageModel = new Message();
        $this->clientModel = new Client();
        $this->userModel = new User();
        $this->escalationService = new EscalationService();
    }

    public function dashboard(): void
    {
        $mesConversations = $this->conversationModel->getByAgent($this->agentId);
        $nonAssignees = $this->conversationModel->getUnassigned($this->entrepriseId);
        
        $enCours = array_filter($mesConversations, fn($c) => $c['statut'] === 'in_progress');
        $resolues = array_filter($mesConversations, fn($c) => $c['statut'] === 'resolved');
        
        // Données d'escalade
        $escalationCounts = $this->escalationService->getDashboardCounts($this->entrepriseId);
        $liveRequests = $this->escalationService->getPendingRequests($this->entrepriseId);
        $openTickets = $this->escalationService->getOpenTickets($this->entrepriseId);
        $notifications = $this->escalationService->getUnreadNotifications($this->entrepriseId, $this->agentId);
        
        $this->view('agent/dashboard', [
            'mesConversations' => $mesConversations,
            'nonAssignees' => $nonAssignees,
            'stats' => [
                'en_cours' => count($enCours),
                'resolues' => count($resolues),
                'total' => count($mesConversations)
            ],
            'escalation' => [
                'counts' => $escalationCounts,
                'live_requests' => $liveRequests,
                'open_tickets' => $openTickets,
                'notifications' => $notifications
            ],
            'user' => $this->currentUser()
        ]);
    }

    public function conversations(): void
    {
        $type = $this->input('type', 'mes');
        
        if ($type === 'non-assignees') {
            $conversations = $this->conversationModel->getUnassigned($this->entrepriseId);
        } else {
            $conversations = $this->conversationModel->getByAgent($this->agentId);
        }
        
        $this->view('agent/conversations/index', [
            'conversations' => $conversations,
            'type' => $type,
            'user' => $this->currentUser()
        ]);
    }

    public function viewConversation(string $id): void
    {
        $conversation = $this->conversationModel->getConversationWithMessages((int) $id);
        
        if (!$conversation || $conversation['entreprise_id'] != $this->entrepriseId) {
            $this->redirect('/agent/conversations');
            return;
        }

        if ($conversation['agent_id'] === null && $this->input('assign') === '1') {
            $this->conversationModel->assignToAgent((int) $id, $this->agentId);
            $conversation['agent_id'] = $this->agentId;
            $conversation['statut'] = 'in_progress';
        }

        $this->messageModel->markAsRead((int) $id, 'agent');

        $client = $this->clientModel->find($conversation['client_id']);
        $agents = $this->userModel->getAgentsByEntreprise($this->entrepriseId);
        
        $this->view('agent/conversations/view', [
            'conversation' => $conversation,
            'client' => $client,
            'agents' => $agents,
            'csrf_token' => $this->generateCsrf(),
            'user' => $this->currentUser()
        ]);
    }

    public function replyConversation(string $id): void
    {
        if (!$this->isPost() || !$this->validateCsrf()) {
            $this->redirect('/agent/conversations/' . $id);
            return;
        }

        $conversation = $this->conversationModel->find((int) $id);
        
        if (!$conversation || $conversation['entreprise_id'] != $this->entrepriseId) {
            $this->redirect('/agent/conversations');
            return;
        }

        if ($conversation['agent_id'] === null) {
            $this->conversationModel->assignToAgent((int) $id, $this->agentId);
        }

        $contenu = $this->sanitize($this->input('message'));
        
        if (!empty($contenu)) {
            $this->messageModel->addMessage(
                (int) $id,
                'agent',
                $this->agentId,
                $contenu,
                ['langue' => 'fr']
            );
        }

        if ($this->isAjax()) {
            $this->json(['success' => true]);
        } else {
            $this->redirect('/agent/conversations/' . $id);
        }
    }

    public function closeConversation(string $id): void
    {
        if (!$this->isPost()) {
            $this->redirect('/agent/conversations/' . $id);
            return;
        }

        $conversation = $this->conversationModel->find((int) $id);
        
        if (!$conversation || $conversation['entreprise_id'] != $this->entrepriseId) {
            $this->redirect('/agent/conversations');
            return;
        }

        $satisfaction = $this->input('satisfaction');
        $this->conversationModel->resolve((int) $id, $satisfaction ? (int) $satisfaction : null);

        if ($this->isAjax()) {
            $this->json(['success' => true]);
        } else {
            $_SESSION['flash_success'] = 'Conversation résolue avec succès.';
            $this->redirect('/agent/conversations');
        }
    }

    public function transferConversation(string $id): void
    {
        if (!$this->isPost() || !$this->validateCsrf()) {
            $this->redirect('/agent/conversations/' . $id);
            return;
        }

        $conversation = $this->conversationModel->find((int) $id);
        
        if (!$conversation || $conversation['entreprise_id'] != $this->entrepriseId) {
            $this->redirect('/agent/conversations');
            return;
        }

        $newAgentId = (int) $this->input('agent_id');
        $reason = $this->sanitize($this->input('reason', ''));
        
        if ($newAgentId === 0) {
            $this->conversationModel->escalate((int) $id, $reason ?: 'Transfert par agent');
        } else {
            $this->conversationModel->assignToAgent((int) $id, $newAgentId);
            
            if ($reason) {
                $this->messageModel->addMessage(
                    (int) $id,
                    'bot',
                    null,
                    "Conversation transférée. Raison: {$reason}",
                    ['type' => 'system']
                );
            }
        }

        $_SESSION['flash_success'] = 'Conversation transférée avec succès.';
        $this->redirect('/agent/conversations');
    }

    /**
     * Prendre en charge une demande de chat en direct
     */
    public function takeLiveRequest(string $id): void
    {
        if (!$this->isPost()) {
            $this->redirect('/agent/dashboard');
            return;
        }

        $this->escalationService->assignLiveRequest((int)$id, $this->agentId);
        
        // Récupérer la demande pour obtenir l'ID de conversation
        $request = $this->db->fetch(
            "SELECT conversation_id FROM live_assistance_requests WHERE id = :id",
            ['id' => $id]
        );

        // Ajouter un message système dans la conversation
        if ($request) {
            $agent = $this->currentUser();
            $this->messageModel->create([
                'conversation_id' => $request['conversation_id'],
                'sender_type' => 'bot',
                'contenu' => "🎉 **{$agent['prenom']} {$agent['nom']}** a pris en charge votre conversation. Vous pouvez maintenant discuter directement.",
                'type_message' => 'text'
            ]);

            $_SESSION['flash_success'] = 'Demande prise en charge avec succès.';
            $this->redirect('/agent/conversations/' . $request['conversation_id']);
            return;
        }

        $_SESSION['flash_success'] = 'Demande prise en charge.';
        $this->redirect('/agent/dashboard');
    }

    /**
     * Prendre en charge un ticket
     */
    public function takeTicket(string $id): void
    {
        if (!$this->isPost()) {
            $this->redirect('/agent/tickets');
            return;
        }

        $this->escalationService->assignTicket((int)$id, $this->agentId);

        $_SESSION['flash_success'] = 'Ticket assigné avec succès.';
        $this->redirect('/agent/tickets/' . $id);
    }

    /**
     * Liste des tickets
     */
    public function tickets(): void
    {
        $filter = $this->input('filter', 'all');
        
        if ($filter === 'mes') {
            $tickets = $this->db->fetchAll(
                "SELECT t.*, c.nom as client_nom, c.telephone, c.email
                 FROM support_tickets t
                 JOIN clients c ON t.client_id = c.id
                 WHERE t.entreprise_id = :eid AND t.assigned_agent_id = :aid
                 ORDER BY t.created_at DESC",
                ['eid' => $this->entrepriseId, 'aid' => $this->agentId]
            );
        } else {
            $tickets = $this->escalationService->getOpenTickets($this->entrepriseId);
        }

        $this->view('agent/tickets/index', [
            'tickets' => $tickets,
            'filter' => $filter,
            'user' => $this->currentUser()
        ]);
    }

    /**
     * Voir un ticket
     */
    public function viewTicket(string $id): void
    {
        $ticket = $this->db->fetch(
            "SELECT t.*, c.nom as client_nom, c.telephone, c.email,
                    u.nom as agent_nom, u.prenom as agent_prenom
             FROM support_tickets t
             JOIN clients c ON t.client_id = c.id
             LEFT JOIN users u ON t.assigned_agent_id = u.id
             WHERE t.id = :id AND t.entreprise_id = :eid",
            ['id' => $id, 'eid' => $this->entrepriseId]
        );

        if (!$ticket) {
            $_SESSION['flash_error'] = 'Ticket non trouvé.';
            $this->redirect('/agent/tickets');
            return;
        }

        // Récupérer les messages de la conversation liée
        $messages = [];
        if ($ticket['conversation_id']) {
            $messages = $this->messageModel->getByConversation($ticket['conversation_id']);
        }

        $this->view('agent/tickets/view', [
            'ticket' => $ticket,
            'messages' => $messages,
            'user' => $this->currentUser()
        ]);
    }

    /**
     * Mettre à jour le statut d'un ticket
     */
    public function updateTicketStatus(string $id): void
    {
        if (!$this->isPost()) {
            $this->redirect('/agent/tickets/' . $id);
            return;
        }

        $status = $this->input('status');
        $notes = $this->sanitize($this->input('notes', ''));

        $updateData = [
            'statut' => $status,
            'updated_at' => date('Y-m-d H:i:s')
        ];

        if ($status === 'resolved') {
            $updateData['resolved_at'] = date('Y-m-d H:i:s');
            $updateData['resolution_notes'] = $notes;
        } elseif ($status === 'closed') {
            $updateData['closed_at'] = date('Y-m-d H:i:s');
        }

        $this->db->query(
            "UPDATE support_tickets SET 
                statut = :statut, 
                resolution_notes = :notes,
                resolved_at = :resolved,
                closed_at = :closed,
                updated_at = NOW()
             WHERE id = :id AND entreprise_id = :eid",
            [
                'statut' => $status,
                'notes' => $notes,
                'resolved' => $updateData['resolved_at'] ?? null,
                'closed' => $updateData['closed_at'] ?? null,
                'id' => $id,
                'eid' => $this->entrepriseId
            ]
        );

        $_SESSION['flash_success'] = 'Statut du ticket mis à jour.';
        $this->redirect('/agent/tickets/' . $id);
    }

    /**
     * API: Récupérer les notifications
     */
    public function getNotifications(): void
    {
        header('Content-Type: application/json');
        
        $notifications = $this->escalationService->getUnreadNotifications($this->entrepriseId, $this->agentId);
        $counts = $this->escalationService->getDashboardCounts($this->entrepriseId);
        
        echo json_encode([
            'success' => true,
            'notifications' => $notifications,
            'counts' => $counts
        ]);
    }

    /**
     * API: Marquer notifications comme lues
     */
    public function markNotificationsRead(): void
    {
        header('Content-Type: application/json');
        
        $input = json_decode(file_get_contents('php://input'), true);
        $ids = $input['ids'] ?? [];
        
        if (!empty($ids)) {
            $this->escalationService->markNotificationsRead($ids);
        }
        
        echo json_encode(['success' => true]);
    }
}
