<?php

declare(strict_types=1);

namespace App\Controllers;

use App\Core\Controller;

/**
 * ChatController — Frontend Chat API
 *
 * Handles AJAX requests from the visitor chat widget.
 * All responses are JSON. No CSRF required for the init/message
 * endpoints because they are meant for unauthenticated visitors.
 */
class ChatController extends Controller
{
    /**
     * Initialize or retrieve an active conversation for the visitor.
     *
     * POST /chat/init
     * Body: { name, email, phone (optional) }
     *
     * Creates a session-bound conversation if none exists.
     */
    public function init(): never
    {
        // Ensure session is started
        if (session_status() === PHP_SESSION_NONE) {
            session_start();
        }

        // Generate or retrieve visitor session ID
        if (empty($_SESSION['chat_session_id'])) {
            $_SESSION['chat_session_id'] = bin2hex(random_bytes(16));
        }

        $sessionId = $_SESSION['chat_session_id'];

        $convModel  = $this->model('ChatConversation');
        $msgModel   = $this->model('ChatMessage');

        // Find existing active conversation
        $conversation = $convModel->findActiveBySession($sessionId);

        if ($conversation) {
            // Update visitor info if provided
            $name  = trim($_POST['name'] ?? '');
            $email = trim($_POST['email'] ?? '');
            $phone = trim($_POST['phone'] ?? '');

            if ($name || $email || $phone) {
                $convModel->updateVisitorInfo(
                    (int) $conversation['id'],
                    $name ?: null,
                    $email ?: null,
                    $phone ?: null
                );
            }

            // Reset visitor unread (they are opening the chat)
            $convModel->resetVisitorUnread((int) $conversation['id']);
            $msgModel->markAdminMessagesRead((int) $conversation['id']);

            // Get messages
            $messages = $msgModel->getByConversation((int) $conversation['id']);

            $this->json([
                'success'      => true,
                'conversation' => [
                    'id'     => (int) $conversation['id'],
                    'status' => $conversation['status'],
                    'name'   => $conversation['visitor_name'],
                ],
                'messages'  => $messages,
                'last_id'   => $msgModel->getLastId((int) $conversation['id']),
            ]);
        }

        // Create new conversation
        $name  = trim($_POST['name'] ?? '') ?: null;
        $email = trim($_POST['email'] ?? '') ?: null;
        $phone = trim($_POST['phone'] ?? '') ?: null;

        $convId = $convModel->createConversation($sessionId, $name, $email, $phone);

        $this->json([
            'success'      => true,
            'conversation' => [
                'id'     => $convId,
                'status' => 'pending',
                'name'   => $name,
            ],
            'messages' => [],
            'last_id'  => 0,
        ]);
    }

    /**
     * Send a message from the visitor.
     *
     * POST /chat/send
     * Body: { conversation_id, message }
     */
    public function send(): never
    {
        if (session_status() === PHP_SESSION_NONE) {
            session_start();
        }

        $conversationId = (int) ($_POST['conversation_id'] ?? 0);
        $message        = trim($_POST['message'] ?? '');

        if ($conversationId <= 0 || empty($message)) {
            $this->json(['success' => false, 'error' => 'Invalid request'], 400);
        }

        // Verify this conversation belongs to the visitor's session
        $sessionId = $_SESSION['chat_session_id'] ?? '';
        $convModel = $this->model('ChatConversation');
        $conversation = $convModel->find($conversationId);

        if (!$conversation || $conversation['session_id'] !== $sessionId) {
            $this->json(['success' => false, 'error' => 'Unauthorized'], 403);
        }

        // Add message
        $msgModel = $this->model('ChatMessage');
        $msgId = $msgModel->addMessage($conversationId, 'visitor', $message);

        // Mark conversation as active (first message)
        if ($conversation['status'] === 'pending') {
            $convModel->markActive($conversationId);
        }

        // Increment admin unread count
        $convModel->incrementAdminUnread($conversationId);

        $this->json([
            'success'   => true,
            'message_id' => $msgId,
            'time'      => date('h:i A'),
        ]);
    }

    /**
     * Poll for new messages (called by visitor widget periodically).
     *
     * GET /chat/poll?conversation_id=X&after_id=Y
     */
    public function poll(): never
    {
        if (session_status() === PHP_SESSION_NONE) {
            session_start();
        }

        $conversationId = (int) ($_GET['conversation_id'] ?? 0);
        $afterId        = (int) ($_GET['after_id'] ?? 0);

        if ($conversationId <= 0) {
            $this->json(['success' => false, 'error' => 'Invalid request'], 400);
        }

        // Verify ownership
        $sessionId = $_SESSION['chat_session_id'] ?? '';
        $convModel = $this->model('ChatConversation');
        $conversation = $convModel->find($conversationId);

        if (!$conversation || $conversation['session_id'] !== $sessionId) {
            $this->json(['success' => false, 'error' => 'Unauthorized'], 403);
        }

        $msgModel = $this->model('ChatMessage');

        // Mark admin messages as read (visitor is actively polling = viewing)
        $msgModel->markAdminMessagesRead($conversationId);
        $convModel->resetVisitorUnread($conversationId);

        // Get new messages
        $messages = $msgModel->getNewerThan($conversationId, $afterId);

        $this->json([
            'success'  => true,
            'messages' => $messages,
            'last_id'  => $msgModel->getLastId($conversationId),
        ]);
    }
}
