<?php

class MessageModel
{
    public static function sendMessage($sender_id, $receiver_id, $group_type, $subject, $message)
    {
        $database = DatabaseFactory::getFactory()->getConnection();
        
        $sql = "INSERT INTO messages (sender_id, receiver_id, group_type, subject, message, is_read) 
                VALUES (:sender_id, :receiver_id, :group_type, :subject, :message, 0)";
        $query = $database->prepare($sql);
        return $query->execute(array(
            ':sender_id' => $sender_id,
            ':receiver_id' => $receiver_id,
            ':group_type' => $group_type,
            ':subject' => $subject,
            ':message' => $message
        ));
    }
    
    public static function sendToUser($sender_id, $receiver_id, $subject, $message)
    {
        return self::sendMessage($sender_id, $receiver_id, null, $subject, $message);
    }
    
    public static function sendToGroup($sender_id, $group_type, $subject, $message)
    {
        return self::sendMessage($sender_id, null, $group_type, $subject, $message);
    }
    
    public static function getUnreadCount($user_id)
    {
        $database = DatabaseFactory::getFactory()->getConnection();
        
        $sql = "SELECT COUNT(*) as count FROM messages 
                WHERE receiver_id = :user_id AND is_read = 0";
        $query = $database->prepare($sql);
        $query->execute(array(':user_id' => $user_id));
        $result = $query->fetch();
        
        return $result->count;
    }
    
    public static function getUnreadCountForUser($user_id, $sender_id)
    {
        $database = DatabaseFactory::getFactory()->getConnection();
        
        $sql = "SELECT COUNT(*) as count FROM messages 
                WHERE receiver_id = :user_id AND sender_id = :sender_id AND is_read = 0";
        $query = $database->prepare($sql);
        $query->execute(array(
            ':user_id' => $user_id,
            ':sender_id' => $sender_id
        ));
        $result = $query->fetch();
        
        return $result->count;
    }
    
    public static function getConversations($user_id)
    {
        $database = DatabaseFactory::getFactory()->getConnection();
        
        $sql = "SELECT DISTINCT 
                    CASE 
                        WHEN sender_id = :user_id THEN receiver_id 
                        ELSE sender_id 
                    END as other_user_id,
                    u.user_name,
                    u.user_email,
                    MAX(m.created_at) as last_message_time,
                    (SELECT COUNT(*) FROM messages m2 
                     WHERE ((m2.sender_id = :user_id AND m2.receiver_id = other_user_id) OR 
                           (m2.receiver_id = :user_id AND m2.sender_id = other_user_id)) 
                     AND m2.is_read = 0 AND m2.receiver_id = :user_id) as unread_count
                FROM messages m
                JOIN users u ON (CASE 
                    WHEN sender_id = :user_id THEN receiver_id 
                    ELSE sender_id 
                END) = u.user_id
                WHERE (sender_id = :user_id OR receiver_id = :user_id)
                  AND receiver_id IS NOT NULL
                GROUP BY other_user_id
                ORDER BY last_message_time DESC";
        
        $query = $database->prepare($sql);
        $query->execute(array(':user_id' => $user_id));
        return $query->fetchAll();
    }
    
    public static function getMessagesWithUser($user_id, $other_user_id)
    {
        $database = DatabaseFactory::getFactory()->getConnection();
        
        $sql = "SELECT m.*, u_sender.user_name as sender_name, 
                       CASE 
                           WHEN m.sender_id = :user_id THEN 'sent' 
                           ELSE 'received' 
                       END as message_type
                FROM messages m
                JOIN users u_sender ON m.sender_id = u_sender.user_id
                WHERE ((m.sender_id = :user_id AND m.receiver_id = :other_user_id) OR 
                       (m.receiver_id = :user_id AND m.sender_id = :other_user_id))
                  AND m.group_type IS NULL
                ORDER BY m.created_at ASC";
        
        $query = $database->prepare($sql);
        $query->execute(array(
            ':user_id' => $user_id,
            ':other_user_id' => $other_user_id
        ));
        $messages = $query->fetchAll();
        
        // Mark received messages as read
        self::markAsRead($user_id, $other_user_id);
        
        return $messages;
    }
    
    public static function markAsRead($user_id, $sender_id)
    {
        $database = DatabaseFactory::getFactory()->getConnection();
        
        $sql = "UPDATE messages SET is_read = 1 
                WHERE receiver_id = :user_id AND sender_id = :sender_id AND is_read = 0";
        $query = $database->prepare($sql);
        return $query->execute(array(
            ':user_id' => $user_id,
            ':sender_id' => $sender_id
        ));
    }
    
    public static function getGroupMessages($user_id)
    {
        $database = DatabaseFactory::getFactory()->getConnection();
        
        // Check user role to determine which group messages they should receive
        $user_role = UserModel::getUserRole($user_id);
        
        $where_conditions = [];
        $params = [':user_id' => $user_id];
        
        // All users receive all_users messages
        $where_conditions[] = "group_type = 'all_users'";
        
        // Admins receive admin messages
        if ($user_role === 'admin') {
            $where_conditions[] = "group_type = 'admins'";
        }
        
        // Moderators receive moderator messages (and admin messages if not already covered)
        if ($user_role === 'moderator' || $user_role === 'admin') {
            $where_conditions[] = "group_type = 'moderators'";
        }
        
        if (empty($where_conditions)) {
            return []; // User has no role that qualifies for group messages
        }
        
        $where_clause = "(" . implode(" OR ", $where_conditions) . ")";
        
        $sql = "SELECT m.*, u.user_name as sender_name 
                FROM messages m
                JOIN users u ON m.sender_id = u.user_id
                WHERE $where_clause AND m.receiver_id IS NULL
                ORDER BY m.created_at DESC";
        
        $query = $database->prepare($sql);
        $query->execute($params);
        return $query->fetchAll();
    }
    
    public static function getGlobalMessages()
    {
        $database = DatabaseFactory::getFactory()->getConnection();
        
        $sql = "SELECT m.*, u.user_name as sender_name,
                       'received' as message_type
                FROM messages m
                JOIN users u ON m.sender_id = u.user_id
                WHERE m.group_type = 'global' 
                  AND m.receiver_id IS NULL
                ORDER BY m.created_at ASC";
        
        $query = $database->prepare($sql);
        $query->execute();
        return $query->fetchAll();
    }
    
    public static function sendToGlobal($sender_id, $message)
    {
        $database = DatabaseFactory::getFactory()->getConnection();
        
        $sql = "INSERT INTO messages (sender_id, group_type, subject, message, is_read) 
                VALUES (:sender_id, 'global', 'Global Chat', :message, 1)";
        $query = $database->prepare($sql);
        return $query->execute(array(
            ':sender_id' => $sender_id,
            ':message' => $message
        ));
    }
    
    public static function getAllUsers($current_user_id)
    {
        $database = DatabaseFactory::getFactory()->getConnection();
        
        $sql = "SELECT user_id, user_name, user_email 
                FROM users 
                WHERE user_id != :current_user_id
                ORDER BY user_name ASC";
        
        $query = $database->prepare($sql);
        $query->execute(array(':current_user_id' => $current_user_id));
        return $query->fetchAll();
    }
}