<?php
use Ratchet\MessageComponentInterface;
use Ratchet\ConnectionInterface;
use Ratchet\Server\IoServer;
use Ratchet\Http\HttpServer;
use Ratchet\WebSocket\WsServer;

require_once __DIR__ . '/vendor/autoload.php';

class ChatServer implements MessageComponentInterface {
    protected $clients;
    protected $db;
    
    public function __construct() {
        $this->clients = new \SplObjectStorage;
        $this->initDatabase();
    }
    
    protected function initDatabase() {
        $this->db = new SQLite3('chatbox.db');
        
        $this->db->exec('CREATE TABLE IF NOT EXISTS sites (
            id INTEGER PRIMARY KEY AUTOINCREMENT,
            domain TEXT UNIQUE NOT NULL,
            name TEXT NOT NULL,
            admin_email TEXT NOT NULL,
            created_at DATETIME DEFAULT CURRENT_TIMESTAMP
        )');
        
        $this->db->exec('CREATE TABLE IF NOT EXISTS conversations (
            id INTEGER PRIMARY KEY AUTOINCREMENT,
            site_id INTEGER NOT NULL,
            visitor_id TEXT NOT NULL,
            created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
            FOREIGN KEY (site_id) REFERENCES sites (id)
        )');
        
        $this->db->exec('CREATE TABLE IF NOT EXISTS messages (
            id INTEGER PRIMARY KEY AUTOINCREMENT,
            conversation_id INTEGER NOT NULL,
            sender TEXT NOT NULL,
            message TEXT NOT NULL,
            created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
            FOREIGN KEY (conversation_id) REFERENCES conversations (id)
        )');
        
        $this->db->exec('CREATE TABLE IF NOT EXISTS settings (
            key TEXT PRIMARY KEY,
            value TEXT NOT NULL
        )');
    }
    
    public function onOpen(ConnectionInterface $conn) {
        $this->clients->attach($conn);
        $conn->send(json_encode(['type' => 'connected', 'id' => $conn->resourceId]));
    }
    
    public function onMessage(ConnectionInterface $from, $msg) {
        $data = json_decode($msg, true);
        
        switch($data['type']) {
            case 'init':
                $this->handleInit($from, $data);
                break;
            case 'message':
                $this->handleMessage($from, $data);
                break;
            case 'admin_message':
                $this->handleAdminMessage($from, $data);
                break;
            case 'get_conversations':
                $this->handleGetConversations($from, $data);
                break;
            case 'get_messages':
                $this->handleGetMessages($from, $data);
                break;
        }
    }
    
    protected function handleInit($conn, $data) {
        $domain = $data['domain'];
        $visitorId = $data['visitorId'];
        
        $site = $this->db->querySingle("SELECT * FROM sites WHERE domain = '$domain'", true);
        
        if (!$site) {
            $stmt = $this->db->prepare('INSERT INTO sites (domain, name, admin_email) VALUES (:domain, :name, :email)');
            $stmt->bindValue(':domain', $domain, SQLITE3_TEXT);
            $stmt->bindValue(':name', $domain, SQLITE3_TEXT);
            $stmt->bindValue(':email', 'admin@' . $domain, SQLITE3_TEXT);
            $stmt->execute();
            $site = ['id' => $this->db->lastInsertRowID()];
        }
        
        $conversation = $this->db->querySingle("SELECT * FROM conversations WHERE site_id = {$site['id']} AND visitor_id = '$visitorId'", true);
        
        if (!$conversation) {
            $stmt = $this->db->prepare('INSERT INTO conversations (site_id, visitor_id) VALUES (:site_id, :visitor_id)');
            $stmt->bindValue(':site_id', $site['id'], SQLITE3_INTEGER);
            $stmt->bindValue(':visitor_id', $visitorId, SQLITE3_TEXT);
            $stmt->execute();
            $conversation = ['id' => $this->db->lastInsertRowID()];
        }
        
        $conn->conversationId = $conversation['id'];
        $conn->siteId = $site['id'];
        $conn->visitorId = $visitorId;
        
        $messages = $this->db->query("SELECT * FROM messages WHERE conversation_id = {$conversation['id']} ORDER BY created_at ASC");
        $messageList = [];
        while ($row = $messages->fetchArray(SQLITE3_ASSOC)) {
            $messageList[] = $row;
        }
        
        $conn->send(json_encode([
            'type' => 'init_complete',
            'conversationId' => $conversation['id'],
            'messages' => $messageList
        ]));
    }
    
    protected function handleMessage($conn, $data) {
        $message = $data['message'];
        
        $stmt = $this->db->prepare('INSERT INTO messages (conversation_id, sender, message) VALUES (:conv_id, :sender, :message)');
        $stmt->bindValue(':conv_id', $conn->conversationId, SQLITE3_INTEGER);
        $stmt->bindValue(':sender', 'visitor', SQLITE3_TEXT);
        $stmt->bindValue(':message', $message, SQLITE3_TEXT);
        $stmt->execute();
        
        $messageId = $this->db->lastInsertRowID();
        
        $site = $this->db->querySingle("SELECT * FROM sites WHERE id = {$conn->siteId}", true);
        
        $this->sendEmail($site['admin_email'], "Nouveau message sur {$site['domain']}", 
            "Visiteur: {$conn->visitorId}\nMessage: $message\n\nRépondre sur: https://aktascorp.com/support-chatbox-intgr/");
        
        foreach ($this->clients as $client) {
            if (isset($client->isAdmin) && $client->isAdmin) {
                $client->send(json_encode([
                    'type' => 'new_visitor_message',
                    'conversationId' => $conn->conversationId,
                    'siteId' => $conn->siteId,
                    'message' => $message,
                    'messageId' => $messageId,
                    'visitorId' => $conn->visitorId
                ]));
            }
        }
        
        $conn->send(json_encode([
            'type' => 'message_sent',
            'messageId' => $messageId
        ]));
    }
    
    protected function handleAdminMessage($conn, $data) {
        $conversationId = $data['conversationId'];
        $message = $data['message'];
        
        $stmt = $this->db->prepare('INSERT INTO messages (conversation_id, sender, message) VALUES (:conv_id, :sender, :message)');
        $stmt->bindValue(':conv_id', $conversationId, SQLITE3_INTEGER);
        $stmt->bindValue(':sender', 'admin', SQLITE3_TEXT);
        $stmt->bindValue(':message', $message, SQLITE3_TEXT);
        $stmt->execute();
        
        $messageId = $this->db->lastInsertRowID();
        
        $conversation = $this->db->querySingle("SELECT * FROM conversations WHERE id = $conversationId", true);
        
        foreach ($this->clients as $client) {
            if (isset($client->conversationId) && $client->conversationId == $conversationId) {
                $client->send(json_encode([
                    'type' => 'admin_message',
                    'message' => $message,
                    'messageId' => $messageId
                ]));
                
                $site = $this->db->querySingle("SELECT * FROM sites WHERE id = {$conversation['site_id']}", true);
                $visitorEmail = "visitor_{$conversation['visitor_id']}@{$site['domain']}";
                
                $this->sendEmail($visitorEmail, "Réponse de {$site['domain']}", 
                    "Admin: $message\n\nContinuer la conversation sur: {$site['domain']}");
            }
        }
    }
    
    protected function handleGetConversations($conn, $data) {
        $conn->isAdmin = true;
        
        $query = "SELECT c.*, s.domain, s.name as site_name, 
                  (SELECT COUNT(*) FROM messages WHERE conversation_id = c.id) as message_count,
                  (SELECT message FROM messages WHERE conversation_id = c.id ORDER BY created_at DESC LIMIT 1) as last_message
                  FROM conversations c
                  JOIN sites s ON c.site_id = s.id
                  ORDER BY c.created_at DESC";
        
        $result = $this->db->query($query);
        $conversations = [];
        while ($row = $result->fetchArray(SQLITE3_ASSOC)) {
            $conversations[] = $row;
        }
        
        $conn->send(json_encode([
            'type' => 'conversations_list',
            'conversations' => $conversations
        ]));
    }
    
    protected function handleGetMessages($conn, $data) {
        $conversationId = $data['conversationId'];
        
        $messages = $this->db->query("SELECT * FROM messages WHERE conversation_id = $conversationId ORDER BY created_at ASC");
        $messageList = [];
        while ($row = $messages->fetchArray(SQLITE3_ASSOC)) {
            $messageList[] = $row;
        }
        
        $conn->send(json_encode([
            'type' => 'messages_list',
            'conversationId' => $conversationId,
            'messages' => $messageList
        ]));
    }
    
    protected function sendEmail($to, $subject, $body) {
        mail($to, $subject, $body, "From: noreply@chatbox.com\r\nContent-Type: text/plain; charset=UTF-8");
    }
    
    public function onClose(ConnectionInterface $conn) {
        $this->clients->detach($conn);
    }
    
    public function onError(ConnectionInterface $conn, \Exception $e) {
        $conn->close();
    }
}

if (php_sapi_name() === 'cli') {
    $server = IoServer::factory(
        new HttpServer(
            new WsServer(
                new ChatServer()
            )
        ),
        8081
    );
    
    echo "WebSocket server running on port 8081...\n";
    $server->run();
} else {
    if (!isset($_GET['action'])) {
        include 'dashboard.html';
        exit;
    }
    
    $db = new SQLite3('chatbox.db');
    
    switch($_GET['action']) {
        case 'update_site':
            $stmt = $db->prepare('UPDATE sites SET name = :name, admin_email = :email WHERE id = :id');
            $stmt->bindValue(':id', $_POST['id'], SQLITE3_INTEGER);
            $stmt->bindValue(':name', $_POST['name'], SQLITE3_TEXT);
            $stmt->bindValue(':email', $_POST['email'], SQLITE3_TEXT);
            $stmt->execute();
            echo json_encode(['success' => true]);
            break;
            
        case 'get_sites':
            $result = $db->query('SELECT * FROM sites ORDER BY created_at DESC');
            $sites = [];
            while ($row = $result->fetchArray(SQLITE3_ASSOC)) {
                $sites[] = $row;
            }
            echo json_encode($sites);
            break;
    }
}
?>