<?php
/**
 * ============================================================================
 * classes/Chat.php - Chat Management Class
 * ============================================================================
 */

namespace App;

class Chat {
    private $conn;
    private $table_name = "chats";
    
    public function __construct($db) {
        $this->conn = $db;
    }
    
    /**
     * Get all chats for a user
     */
    public function getUserChats($userId) {
        $query = "SELECT 
                    c.id,
                    c.chat_type,
                    c.chat_name,
                    c.chat_avatar,
                    c.created_at,
                    c.updated_at,
                    CASE 
                        WHEN c.chat_type = 'one_to_one' THEN 
                            (SELECT u.full_name 
                             FROM users u 
                             INNER JOIN chat_members cm2 ON u.id = cm2.user_id 
                             WHERE cm2.chat_id = c.id AND cm2.user_id != :user_id 
                             LIMIT 1)
                        ELSE c.chat_name
                    END as chat_name,
                    CASE 
                        WHEN c.chat_type = 'one_to_one' THEN 
                            (SELECT u.profile_picture 
                             FROM users u 
                             INNER JOIN chat_members cm2 ON u.id = cm2.user_id 
                             WHERE cm2.chat_id = c.id AND cm2.user_id != :user_id2 
                             LIMIT 1)
                        ELSE c.chat_avatar
                    END as chat_avatar,
                    (SELECT m.content 
                     FROM messages m 
                     WHERE m.chat_id = c.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 
                     ORDER BY m.created_at DESC 
                     LIMIT 1) as last_message_time,
                    (SELECT COUNT(*) 
                     FROM messages m 
                     WHERE m.chat_id = c.id 
                     AND m.created_at > COALESCE(cm.last_read_at, '2000-01-01')
                     AND m.sender_id != :user_id3) as unread_count
                FROM chats c
                INNER JOIN chat_members cm ON c.id = cm.chat_id
                WHERE cm.user_id = :user_id4
                ORDER BY last_message_time DESC";
        
        $stmt = $this->conn->prepare($query);
        $stmt->bindParam(':user_id', $userId);
        $stmt->bindParam(':user_id2', $userId);
        $stmt->bindParam(':user_id3', $userId);
        $stmt->bindParam(':user_id4', $userId);
        $stmt->execute();
        
        return $stmt->fetchAll(\PDO::FETCH_ASSOC);
    }
    
    /**
     * Create or get one-on-one chat
     */
    public function createOrGetOneOnOne($userId1, $userId2) {
        // Check if chat already exists
        $query = "SELECT c.id 
                  FROM chats c
                  INNER JOIN chat_members cm1 ON c.id = cm1.chat_id
                  INNER JOIN chat_members cm2 ON c.id = cm2.chat_id
                  WHERE c.chat_type = 'one_to_one'
                  AND cm1.user_id = :user1
                  AND cm2.user_id = :user2
                  LIMIT 1";
        
        $stmt = $this->conn->prepare($query);
        $stmt->bindParam(':user1', $userId1);
        $stmt->bindParam(':user2', $userId2);
        $stmt->execute();
        
        $existing = $stmt->fetch(\PDO::FETCH_ASSOC);
        
        if ($existing) {
            return $existing['id'];
        }
        
        // Create new chat
        $query = "INSERT INTO chats (chat_type, created_by) 
                  VALUES ('one_to_one', :created_by)";
        
        $stmt = $this->conn->prepare($query);
        $stmt->bindParam(':created_by', $userId1);
        $stmt->execute();
        
        $chatId = $this->conn->lastInsertId();
        
        // Add both members
        $this->addMember($chatId, $userId1);
        $this->addMember($chatId, $userId2);
        
        return $chatId;
    }
    
    /**
     * Create group chat
     */
    public function createGroup($creatorId, $groupName, $memberIds = []) {
        $query = "INSERT INTO chats (chat_type, chat_name, created_by) 
                  VALUES ('group', :chat_name, :created_by)";
        
        $stmt = $this->conn->prepare($query);
        $stmt->bindParam(':chat_name', $groupName);
        $stmt->bindParam(':created_by', $creatorId);
        $stmt->execute();
        
        $chatId = $this->conn->lastInsertId();
        
        // Add creator as admin
        $this->addMember($chatId, $creatorId, 'admin');
        
        // Add other members
        foreach ($memberIds as $memberId) {
            if ($memberId != $creatorId) {
                $this->addMember($chatId, $memberId);
            }
        }
        
        return $chatId;
    }
    
    /**
     * Add member to chat
     */
    public function addMember($chatId, $userId, $role = 'member') {
        $query = "INSERT INTO chat_members (chat_id, user_id, role) 
                  VALUES (:chat_id, :user_id, :role)";
        
        $stmt = $this->conn->prepare($query);
        $stmt->bindParam(':chat_id', $chatId);
        $stmt->bindParam(':user_id', $userId);
        $stmt->bindParam(':role', $role);
        
        return $stmt->execute();
    }
    
    /**
     * Get chat details
     */
    public function getChatDetails($chatId, $userId) {
        $query = "SELECT 
                    c.*,
                    CASE 
                        WHEN c.chat_type = 'one_to_one' THEN 
                            (SELECT u.full_name 
                             FROM users u 
                             INNER JOIN chat_members cm2 ON u.id = cm2.user_id 
                             WHERE cm2.chat_id = c.id AND cm2.user_id != :user_id 
                             LIMIT 1)
                        ELSE c.chat_name
                    END as display_name,
                    CASE 
                        WHEN c.chat_type = 'one_to_one' THEN 
                            (SELECT u.profile_picture 
                             FROM users u 
                             INNER JOIN chat_members cm2 ON u.id = cm2.user_id 
                             WHERE cm2.chat_id = c.id AND cm2.user_id != :user_id2 
                             LIMIT 1)
                        ELSE c.chat_avatar
                    END as display_avatar,
                    cm.role as user_role
                FROM chats c
                INNER JOIN chat_members cm ON c.id = cm.chat_id
                WHERE c.id = :chat_id AND cm.user_id = :user_id3";
        
        $stmt = $this->conn->prepare($query);
        $stmt->bindParam(':chat_id', $chatId);
        $stmt->bindParam(':user_id', $userId);
        $stmt->bindParam(':user_id2', $userId);
        $stmt->bindParam(':user_id3', $userId);
        $stmt->execute();
        
        return $stmt->fetch(\PDO::FETCH_ASSOC);
    }
    
    /**
     * Get chat members
     */
    public function getChatMembers($chatId) {
        $query = "SELECT 
                    u.id,
                    u.full_name,
                    u.profile_picture,
                    cm.role,
                    cm.joined_at
                FROM chat_members cm
                INNER JOIN users u ON cm.user_id = u.id
                WHERE cm.chat_id = :chat_id
                ORDER BY cm.role DESC, u.full_name ASC";
        
        $stmt = $this->conn->prepare($query);
        $stmt->bindParam(':chat_id', $chatId);
        $stmt->execute();
        
        return $stmt->fetchAll(\PDO::FETCH_ASSOC);
    }
    
    /**
     * Update last read timestamp
     */
    public function updateLastRead($chatId, $userId) {
        $query = "UPDATE chat_members 
                  SET last_read_at = NOW() 
                  WHERE chat_id = :chat_id AND user_id = :user_id";
        
        $stmt = $this->conn->prepare($query);
        $stmt->bindParam(':chat_id', $chatId);
        $stmt->bindParam(':user_id', $userId);
        
        return $stmt->execute();
    }
    
    /**
     * Check if user is member of chat
     */
    public function isMember($chatId, $userId) {
        $query = "SELECT COUNT(*) as count 
                  FROM chat_members 
                  WHERE chat_id = :chat_id AND user_id = :user_id";
        
        $stmt = $this->conn->prepare($query);
        $stmt->bindParam(':chat_id', $chatId);
        $stmt->bindParam(':user_id', $userId);
        $stmt->execute();
        
        $result = $stmt->fetch(\PDO::FETCH_ASSOC);
        return $result['count'] > 0;
    }
    
    /**
     * Remove member from chat
     */
    public function removeMember($chatId, $userId) {
        $query = "DELETE FROM chat_members 
                  WHERE chat_id = :chat_id AND user_id = :user_id";
        
        $stmt = $this->conn->prepare($query);
        $stmt->bindParam(':chat_id', $chatId);
        $stmt->bindParam(':user_id', $userId);
        
        return $stmt->execute();
    }
    
    /**
     * Update group info
     */
    public function updateGroupInfo($chatId, $groupName, $avatar = null) {
        if ($avatar) {
            $query = "UPDATE chats 
                      SET chat_name = :chat_name, chat_avatar = :avatar 
                      WHERE id = :chat_id AND chat_type = 'group'";
            
            $stmt = $this->conn->prepare($query);
            $stmt->bindParam(':avatar', $avatar);
        } else {
            $query = "UPDATE chats 
                      SET chat_name = :chat_name 
                      WHERE id = :chat_id AND chat_type = 'group'";
            
            $stmt = $this->conn->prepare($query);
        }
        
        $stmt->bindParam(':chat_name', $groupName);
        $stmt->bindParam(':chat_id', $chatId);
        
        return $stmt->execute();
    }
}