<?php
/**
 * ============================================================================
 * Message.php - FIXED with Sender/Receiver Privacy
 * ============================================================================
 */

namespace App;

class Message {
    private $db;
    
    public function __construct($db) {
        $this->db = $db;
    }
    
    /**
     * Get chat messages for a specific user
     * CRITICAL: Only returns messages where user is sender OR receiver
     */
    public function getChatMessages($chatId, $userId, $limit = 50, $beforeId = null) {
        $sql = "SELECT 
                    m.id,
                    m.chat_id,
                    m.sender_id,
                    m.receiver_id,
                    m.message_type,
                    m.content,
                    m.media_url,
                    m.is_encrypted,
                    m.encrypted_content,
                    m.encrypted_key,
                    m.iv,
                    m.created_at,
                    u.full_name as sender_name,
                    u.profile_picture as sender_avatar
                FROM messages m
                INNER JOIN users u ON m.sender_id = u.id
                WHERE m.chat_id = ?
                AND (m.sender_id = ? OR m.receiver_id = ?)";
        
        $params = [$chatId, $userId, $userId];
        
        if ($beforeId) {
            $sql .= " AND m.id < ?";
            $params[] = $beforeId;
        }
        
        $sql .= " ORDER BY m.created_at DESC LIMIT ?";
        $params[] = $limit;
        
        $stmt = $this->db->prepare($sql);
        $stmt->execute($params);
        
        $messages = $stmt->fetchAll(\PDO::FETCH_ASSOC);
        
        // Reverse to show oldest first
        return array_reverse($messages);
    }
    
    /**
     * Send message with proper sender/receiver
     * CRITICAL: Sets both sender_id AND receiver_id for privacy
     */
    public function send($chatId, $senderId, $data, $encrypt = false) {
        try {
            // Get receiver ID (the other person in the chat)
            $receiverSql = "SELECT user_id 
                           FROM chat_members 
                           WHERE chat_id = ? AND user_id != ? 
                           LIMIT 1";
            
            $stmt = $this->db->prepare($receiverSql);
            $stmt->execute([$chatId, $senderId]);
            $receiver = $stmt->fetch(\PDO::FETCH_ASSOC);
            
            if (!$receiver) {
                return [
                    'success' => false,
                    'message' => 'Receiver not found in chat'
                ];
            }
            
            $receiverId = $receiver['user_id'];
            $content = $data['content'] ?? '';
            $messageType = $data['message_type'] ?? 'text';
            $mediaUrl = $data['media_url'] ?? null;
            
            // Encryption handling
            $encryptedContent = null;
            $encryptedKey = null;
            $iv = null;
            $messageHash = null;
            
            if ($encrypt) {
                // Get receiver's public key
                $keyQuery = "SELECT public_key FROM user_encryption_keys WHERE user_id = ?";
                $stmt = $this->db->prepare($keyQuery);
                $stmt->execute([$receiverId]);
                $keyData = $stmt->fetch(\PDO::FETCH_ASSOC);
                
                if (!$keyData) {
                    return [
                        'success' => false,
                        'message' => 'Receiver does not have encryption keys'
                    ];
                }
                
                // Use Encryption class to encrypt
                $encryption = new \App\Encryption($this->db);
                $encrypted = $encryption->encryptMessage($content, $keyData['public_key']);
                
                if (!$encrypted['success']) {
                    return [
                        'success' => false,
                        'message' => 'Encryption failed'
                    ];
                }
                
                $encryptedContent = $encrypted['encrypted_data'];
                $encryptedKey = $encrypted['encrypted_key'];
                $iv = $encrypted['iv'];
                $messageHash = hash('sha256', $content);
            }
            
            // Insert message
            $insertSql = "INSERT INTO messages (
                            chat_id, 
                            sender_id, 
                            receiver_id,
                            message_type, 
                            content, 
                            encrypted_content,
                            encrypted_key,
                            iv,
                            message_hash,
                            media_url, 
                            is_encrypted,
                            created_at
                          ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, NOW())";
            
            $stmt = $this->db->prepare($insertSql);
            $success = $stmt->execute([
                $chatId,
                $senderId,
                $receiverId,
                $messageType,
                $encrypt ? '' : $content,  // Empty if encrypted
                $encryptedContent,
                $encryptedKey,
                $iv,
                $messageHash,
                $mediaUrl,
                $encrypt ? 1 : 0
            ]);
            
            if ($success) {
                $messageId = $this->db->lastInsertId();
                
                // Update chat timestamp
                $updateChat = "UPDATE chats SET updated_at = NOW() WHERE id = ?";
                $stmt = $this->db->prepare($updateChat);
                $stmt->execute([$chatId]);
                
                // Create notification for receiver
                $this->notifyRecipient($receiverId, $senderId, $chatId, $content);
                
                return [
                    'success' => true,
                    'message_id' => $messageId
                ];
            }
            
            return [
                'success' => false,
                'message' => 'Failed to insert message'
            ];
            
        } catch (\Exception $e) {
            error_log("Error sending message: " . $e->getMessage());
            return [
                'success' => false,
                'message' => $e->getMessage()
            ];
        }
    }
    
    /**
     * Get new messages after a specific message ID
     * CRITICAL: Only returns messages for this user
     */
    public function getNewMessages($chatId, $userId, $afterId) {
        $sql = "SELECT 
                    m.id,
                    m.chat_id,
                    m.sender_id,
                    m.receiver_id,
                    m.message_type,
                    m.content,
                    m.media_url,
                    m.is_encrypted,
                    m.created_at,
                    u.full_name as sender_name,
                    u.profile_picture as sender_avatar
                FROM messages m
                INNER JOIN users u ON m.sender_id = u.id
                WHERE m.chat_id = ?
                AND m.id > ?
                AND (m.sender_id = ? OR m.receiver_id = ?)
                ORDER BY m.created_at ASC";
        
        $stmt = $this->db->prepare($sql);
        $stmt->execute([$chatId, $afterId, $userId, $userId]);
        
        return $stmt->fetchAll(\PDO::FETCH_ASSOC);
    }
    
    /**
     * Decrypt encrypted message
     */
    public function decryptMessage($messageId, $userId, $password) {
        try {
            // Get message
            $sql = "SELECT * FROM messages WHERE id = ? AND receiver_id = ?";
            $stmt = $this->db->prepare($sql);
            $stmt->execute([$messageId, $userId]);
            $message = $stmt->fetch(\PDO::FETCH_ASSOC);
            
            if (!$message || !$message['is_encrypted']) {
                return [
                    'success' => false,
                    'message' => 'Message not found or not encrypted'
                ];
            }
            
            // Use Encryption class
            $encryption = new \App\Encryption($this->db);
            $decrypted = $encryption->decryptMessage(
                $message['encrypted_content'],
                $message['encrypted_key'],
                $message['iv'],
                $userId,
                $password
            );
            
            return $decrypted;
            
        } catch (\Exception $e) {
            return [
                'success' => false,
                'message' => $e->getMessage()
            ];
        }
    }
    
    /**
     * Get unread message count for user
     * FIXED: If $chatId is null, returns total unread across all chats
     */
    public function getUnreadCount($userId, $chatId = null) {
        if ($chatId === null) {
            // Get total unread count across all chats
            $sql = "SELECT COUNT(*) as count
                    FROM messages m
                    INNER JOIN chat_members cm ON m.chat_id = cm.chat_id AND cm.user_id = ?
                    WHERE m.receiver_id = ?
                    AND m.created_at > COALESCE(cm.last_read_at, '1970-01-01')";
            
            $stmt = $this->db->prepare($sql);
            $stmt->execute([$userId, $userId]);
        } else {
            // Get unread count for specific chat
            $sql = "SELECT COUNT(*) as count
                    FROM messages m
                    INNER JOIN chat_members cm ON m.chat_id = cm.chat_id AND cm.user_id = ?
                    WHERE m.chat_id = ?
                    AND m.receiver_id = ?
                    AND m.created_at > COALESCE(cm.last_read_at, '1970-01-01')";
            
            $stmt = $this->db->prepare($sql);
            $stmt->execute([$userId, $chatId, $userId]);
        }
        
        $result = $stmt->fetch(\PDO::FETCH_ASSOC);
        return $result['count'] ?? 0;
    }
    
    /**
     * Notify recipient of new message
     */
    private function notifyRecipient($receiverId, $senderId, $chatId, $content) {
        try {
            // Get sender name
            $sql = "SELECT full_name FROM users WHERE id = ?";
            $stmt = $this->db->prepare($sql);
            $stmt->execute([$senderId]);
            $sender = $stmt->fetch(\PDO::FETCH_ASSOC);
            
            // Create notification
            $notifySql = "INSERT INTO notifications (
                            user_id, 
                            title, 
                            message, 
                            type, 
                            icon, 
                            link, 
                            created_at
                          ) VALUES (?, ?, ?, ?, ?, ?, NOW())";
            
            $stmt = $this->db->prepare($notifySql);
            $stmt->execute([
                $receiverId,
                'New Message',
                ($sender['full_name'] ?? 'Someone') . ': ' . substr($content, 0, 50),
                'info',
                'chat',
                '/chat/one-on-one.php?chat_id=' . $chatId
            ]);
            
        } catch (\Exception $e) {
            error_log("Error creating notification: " . $e->getMessage());
        }
    }
    
    /**
     * Mark messages as read
     */
    public function markAsRead($chatId, $userId) {
        $sql = "UPDATE chat_members 
                SET last_read_at = NOW() 
                WHERE chat_id = ? AND user_id = ?";
        
        $stmt = $this->db->prepare($sql);
        return $stmt->execute([$chatId, $userId]);
    }
}