<?php
/**
 * ============================================================================
 * Chat.php - FIXED One-on-One Chat Management with Privacy
 * ============================================================================
 */

namespace App;

class Chat {
    private $db;
    
    public function __construct($db) {
        $this->db = $db;
    }
    
    /**
     * Get user's one-on-one chats ONLY
     * CRITICAL: Only shows chats where user is a member
     * FIXED: Returns correct field names matching the frontend expectations
     */
    public function getUserChats($userId, $limit = 50, $offset = 0) {
        $sql = "SELECT 
                    c.id,
                    c.created_at,
                    c.updated_at,
                    u2.id as friend_id,
                    u2.full_name as chat_name,
                    u2.profile_picture as chat_avatar,
                    u2.last_activity as friend_last_activity,
                    TIMESTAMPDIFF(MINUTE, u2.last_activity, NOW()) < 5 as is_online,
                    (SELECT m.content 
                     FROM messages m 
                     WHERE m.chat_id = c.id 
                     AND (m.sender_id = ? OR m.receiver_id = ?)
                     ORDER BY m.created_at DESC 
                     LIMIT 1) as last_message,
                    (SELECT m.created_at 
                     FROM messages m 
                     WHERE m.chat_id = c.id 
                     AND (m.sender_id = ? OR m.receiver_id = ?)
                     ORDER BY m.created_at DESC 
                     LIMIT 1) as last_message_time,
                    (SELECT m.sender_id 
                     FROM messages m 
                     WHERE m.chat_id = c.id 
                     AND (m.sender_id = ? OR m.receiver_id = ?)
                     ORDER BY m.created_at DESC 
                     LIMIT 1) as last_sender_id,
                    (SELECT m.is_encrypted 
                     FROM messages m 
                     WHERE m.chat_id = c.id 
                     AND (m.sender_id = ? OR m.receiver_id = ?)
                     ORDER BY m.created_at DESC 
                     LIMIT 1) as last_message_encrypted,
                    (SELECT COUNT(*) 
                     FROM messages m 
                     WHERE m.chat_id = c.id 
                     AND m.receiver_id = ?
                     AND m.created_at > COALESCE(cm1.last_read_at, '1970-01-01')) as unread_count
                FROM chats c
                INNER JOIN chat_members cm1 ON c.id = cm1.chat_id AND cm1.user_id = ?
                INNER JOIN chat_members cm2 ON c.id = cm2.chat_id AND cm2.user_id != ?
                INNER JOIN users u2 ON cm2.user_id = u2.id
                WHERE c.chat_type = 'one_to_one'
                ORDER BY COALESCE(
                    (SELECT m.created_at FROM messages m 
                     WHERE m.chat_id = c.id 
                     ORDER BY m.created_at DESC LIMIT 1),
                    c.created_at
                ) DESC
                LIMIT ? OFFSET ?";
        
        $stmt = $this->db->prepare($sql);
        $stmt->execute([
            $userId, $userId,  // last_message subquery
            $userId, $userId,  // last_message_time subquery
            $userId, $userId,  // last_sender_id subquery
            $userId, $userId,  // last_message_encrypted subquery
            $userId,           // unread_count
            $userId,           // main query user
            $userId,           // main query friend
            $limit, 
            $offset
        ]);
        
        return $stmt->fetchAll(\PDO::FETCH_ASSOC);
    }
    
    /**
     * Create or get existing one-on-one chat
     * CRITICAL: Prevents duplicate chats between same users
     */
    public function createOrGetOneOnOne($userId, $friendId) {
        // Check if user is trying to chat with themselves
        if ($userId == $friendId) {
            return false;
        }
        
        // Check if chat already exists
        $sql = "SELECT c.id
                FROM chats c
                INNER JOIN chat_members cm1 ON c.id = cm1.chat_id AND cm1.user_id = ?
                INNER JOIN chat_members cm2 ON c.id = cm2.chat_id AND cm2.user_id = ?
                WHERE c.chat_type = 'one_to_one'
                LIMIT 1";
        
        $stmt = $this->db->prepare($sql);
        $stmt->execute([$userId, $friendId]);
        $existing = $stmt->fetch(\PDO::FETCH_ASSOC);
        
        if ($existing) {
            return $existing['id'];
        }
        
        // Create new chat
        try {
            $this->db->beginTransaction();
            
            $insertChat = "INSERT INTO chats (chat_type, created_by, created_at, updated_at) 
                          VALUES ('one_to_one', ?, NOW(), NOW())";
            $stmt = $this->db->prepare($insertChat);
            $stmt->execute([$userId]);
            
            $chatId = $this->db->lastInsertId();
            
            // Add both members
            $insertMember = "INSERT INTO chat_members (chat_id, user_id, role, joined_at) 
                            VALUES (?, ?, 'member', NOW())";
            $stmt = $this->db->prepare($insertMember);
            $stmt->execute([$chatId, $userId]);
            $stmt->execute([$chatId, $friendId]);
            
            $this->db->commit();
            return $chatId;
            
        } catch (\Exception $e) {
            $this->db->rollBack();
            error_log("Error creating chat: " . $e->getMessage());
            return false;
        }
    }
    
    /**
     * Get chat details with friend info
     * CRITICAL: Verifies user is member before showing details
     */
    public function getChatDetails($chatId, $userId) {
        $sql = "SELECT 
                    c.id,
                    c.chat_type,
                    u2.id as friend_id,
                    u2.full_name as display_name,
                    u2.profile_picture as display_avatar,
                    u2.last_activity as friend_last_activity,
                    TIMESTAMPDIFF(MINUTE, u2.last_activity, NOW()) < 5 as is_online
                FROM chats c
                INNER JOIN chat_members cm1 ON c.id = cm1.chat_id AND cm1.user_id = ?
                INNER JOIN chat_members cm2 ON c.id = cm2.chat_id AND cm2.user_id != ?
                INNER JOIN users u2 ON cm2.user_id = u2.id
                WHERE c.id = ? AND c.chat_type = 'one_to_one'
                LIMIT 1";
        
        $stmt = $this->db->prepare($sql);
        $stmt->execute([$userId, $userId, $chatId]);
        
        return $stmt->fetch(\PDO::FETCH_ASSOC);
    }
    
    /**
     * Check if user is member of chat
     * CRITICAL: Privacy check before allowing any action
     */
    public function isMember($chatId, $userId) {
        $sql = "SELECT COUNT(*) as count 
                FROM chat_members 
                WHERE chat_id = ? AND user_id = ?";
        
        $stmt = $this->db->prepare($sql);
        $stmt->execute([$chatId, $userId]);
        $result = $stmt->fetch(\PDO::FETCH_ASSOC);
        
        return $result['count'] > 0;
    }
    
    /**
     * Get friend ID from chat
     * CRITICAL: Gets the OTHER person in the conversation
     */
    public function getFriendId($chatId, $userId) {
        $sql = "SELECT user_id 
                FROM chat_members 
                WHERE chat_id = ? AND user_id != ? 
                LIMIT 1";
        
        $stmt = $this->db->prepare($sql);
        $stmt->execute([$chatId, $userId]);
        $result = $stmt->fetch(\PDO::FETCH_ASSOC);
        
        return $result ? $result['user_id'] : null;
    }
    
    /**
     * Update last read timestamp
     */
    public function updateLastRead($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]);
    }
    
    /**
     * Delete chat (removes user from members)
     */
    public function deleteChat($chatId, $userId) {
        $sql = "DELETE FROM chat_members 
                WHERE chat_id = ? AND user_id = ?";
        
        $stmt = $this->db->prepare($sql);
        return $stmt->execute([$chatId, $userId]);
    }
    
    /**
     * Search chats by friend name or message content
     */
    public function searchChats($userId, $query, $limit = 20) {
        $searchTerm = "%{$query}%";
        
        $sql = "SELECT DISTINCT
                    c.id as chat_id,
                    u2.id as friend_id,
                    u2.full_name as display_name,
                    u2.profile_picture as display_avatar,
                    (SELECT m.content 
                     FROM messages m 
                     WHERE m.chat_id = c.id 
                     ORDER BY m.created_at DESC 
                     LIMIT 1) as last_message
                FROM chats c
                INNER JOIN chat_members cm1 ON c.id = cm1.chat_id AND cm1.user_id = ?
                INNER JOIN chat_members cm2 ON c.id = cm2.chat_id AND cm2.user_id != ?
                INNER JOIN users u2 ON cm2.user_id = u2.id
                LEFT JOIN messages m ON c.id = m.chat_id 
                    AND (m.sender_id = ? OR m.receiver_id = ?)
                WHERE c.chat_type = 'one_to_one'
                AND (
                    u2.full_name LIKE ? 
                    OR m.content LIKE ?
                )
                ORDER BY c.updated_at DESC
                LIMIT ?";
        
        $stmt = $this->db->prepare($sql);
        $stmt->execute([
            $userId, 
            $userId, 
            $userId,
            $userId,
            $searchTerm, 
            $searchTerm, 
            $limit
        ]);
        
        return $stmt->fetchAll(\PDO::FETCH_ASSOC);
    }
    
    /**
     * Get online friends
     */
    public function getOnlineFriends($userId, $limit = 10) {
        $sql = "SELECT DISTINCT
                    u2.id,
                    u2.full_name,
                    u2.profile_picture,
                    u2.last_activity
                FROM friendships f
                INNER JOIN users u2 ON (
                    (f.user_id = ? AND f.friend_id = u2.id) OR
                    (f.friend_id = ? AND f.user_id = u2.id)
                )
                WHERE f.status = 'accepted'
                AND TIMESTAMPDIFF(MINUTE, u2.last_activity, NOW()) < 5
                ORDER BY u2.last_activity DESC
                LIMIT ?";
        
        $stmt = $this->db->prepare($sql);
        $stmt->execute([$userId, $userId, $limit]);
        
        return $stmt->fetchAll(\PDO::FETCH_ASSOC);
    }
}