<?php
/**
 * HuSNS - 一款免费开源的社交平台
 * 
 * @author  HYR
 * @QQ      281900864
 * @website https://huyourui.com
 * @license MIT
 */
class MessageModel extends Model
{
    protected $table = 'messages';

    public function __construct()
    {
        parent::__construct();
        $this->createTableIfNotExists();
        $this->createCallTableIfNotExists();
    }

    private function createTableIfNotExists()
    {
        $sql = "CREATE TABLE IF NOT EXISTS `__PREFIX__messages` (
            `id` int(11) NOT NULL AUTO_INCREMENT,
            `sender_id` int(11) NOT NULL,
            `receiver_id` int(11) NOT NULL,
            `content` text NOT NULL,
            `type` varchar(20) DEFAULT 'text',
            `is_read` tinyint(1) DEFAULT 0,
            `created_at` int(11) NOT NULL,
            PRIMARY KEY (`id`),
            INDEX `sender_idx` (`sender_id`),
            INDEX `receiver_idx` (`receiver_id`),
            INDEX `read_idx` (`is_read`),
            INDEX `time_idx` (`created_at`)
        ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci";
        
        $this->db->query($sql);
    }

    private function createCallTableIfNotExists()
    {
        $sql = "CREATE TABLE IF NOT EXISTS `__PREFIX__call_requests` (
            `id` int(11) UNSIGNED NOT NULL AUTO_INCREMENT,
            `call_id` varchar(64) NOT NULL DEFAULT '' COMMENT '通话ID',
            `caller_id` int(11) NOT NULL DEFAULT 0 COMMENT '呼叫者ID',
            `caller_name` varchar(100) NOT NULL DEFAULT '' COMMENT '呼叫者名称',
            `caller_avatar` varchar(255) NOT NULL DEFAULT '' COMMENT '呼叫者头像',
            `callee_id` int(11) NOT NULL DEFAULT 0 COMMENT '被叫者ID',
            `type` varchar(10) NOT NULL DEFAULT 'voice' COMMENT '通话类型：voice/video',
            `status` varchar(20) NOT NULL DEFAULT 'pending' COMMENT '状态：pending/incoming/connected/ended/rejected',
            `created_at` int(11) NOT NULL DEFAULT 0 COMMENT '创建时间',
            `updated_at` int(11) NOT NULL DEFAULT 0 COMMENT '更新时间',
            PRIMARY KEY (`id`),
            UNIQUE KEY `call_id` (`call_id`),
            KEY `caller_id` (`caller_id`),
            KEY `callee_id` (`callee_id`),
            KEY `status` (`status`)
        ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='通话请求表'";
        
        $this->db->query($sql);
    }

    public function send($senderId, $receiverId, $content, $type = 'text')
    {
        if ($senderId == $receiverId) {
            return false;
        }

        $data = [
            'sender_id' => $senderId,
            'receiver_id' => $receiverId,
            'content' => Security::xssClean($content),
            'type' => $type,
            'is_read' => 0,
            'created_at' => time()
        ];

        return $this->insert($data);
    }

    public function getConversations($userId, $page = 1, $pageSize = 20)
    {
        $offset = ($page - 1) * $pageSize;

        $sql = "SELECT 
                    IF(m.sender_id = ?, m.receiver_id, m.sender_id) as partner_id,
                    u.username, u.avatar, u.last_activity,
                    MAX(m.created_at) as last_time,
                    SUBSTRING_INDEX(GROUP_CONCAT(m.content ORDER BY m.created_at DESC), ',', 1) as last_message,
                    COUNT(CASE WHEN m.receiver_id = ? AND m.is_read = 0 THEN 1 END) as unread_count,
                    COUNT(DISTINCT m.id) as message_count
                FROM __PREFIX__messages m
                INNER JOIN __PREFIX__users u ON IF(m.sender_id = ?, m.receiver_id, m.sender_id) = u.id
                WHERE m.sender_id = ? OR m.receiver_id = ?
                GROUP BY partner_id
                ORDER BY last_time DESC
                LIMIT {$offset}, {$pageSize}";

        $conversations = $this->db->fetchAll($sql, [$userId, $userId, $userId, $userId, $userId]);

        foreach ($conversations as &$conv) {
            $conv['time_ago'] = Helper::formatTime($conv['last_time']);
            $conv['is_online'] = !empty($conv['last_activity']) && (time() - $conv['last_activity']) < 300;
            $conv['avatar'] = !empty($conv['avatar']) ? Helper::uploadUrl($conv['avatar']) : '';
        }

        return $conversations;
    }

    public function getMessages($userId, $partnerId, $page = 1, $pageSize = 20)
    {
        $offset = ($page - 1) * $pageSize;

        $sql = "SELECT m.*, u.username, u.avatar
                FROM __PREFIX__messages m
                INNER JOIN __PREFIX__users u ON m.sender_id = u.id
                WHERE (m.sender_id = ? AND m.receiver_id = ?) OR (m.sender_id = ? AND m.receiver_id = ?)
                ORDER BY m.created_at ASC
                LIMIT {$offset}, {$pageSize}";

        $messages = $this->db->fetchAll($sql, [$userId, $partnerId, $partnerId, $userId]);

        foreach ($messages as &$msg) {
            $msg['time_ago'] = Helper::formatTime($msg['created_at']);
            $msg['avatar'] = !empty($msg['avatar']) ? Helper::uploadUrl($msg['avatar']) : '';
            $msg['is_me'] = $msg['sender_id'] == $userId;
        }

        $this->markAsRead($userId, $partnerId);

        return $messages;
    }

    public function markAsRead($userId, $partnerId)
    {
        return $this->db->query(
            "UPDATE __PREFIX__messages SET is_read = 1 
             WHERE receiver_id = ? AND sender_id = ? AND is_read = 0",
            [$userId, $partnerId]
        );
    }

    public function getUnreadCount($userId)
    {
        $sql = "SELECT COUNT(*) FROM __PREFIX__messages 
                WHERE receiver_id = ? AND is_read = 0";
        return (int)$this->db->fetchColumn($sql, [$userId]);
    }

    public function getConversationUnreadCount($userId, $partnerId)
    {
        $sql = "SELECT COUNT(*) FROM __PREFIX__messages 
                WHERE receiver_id = ? AND sender_id = ? AND is_read = 0";
        return (int)$this->db->fetchColumn($sql, [$userId, $partnerId]);
    }

    public function deleteConversation($userId, $partnerId)
    {
        return $this->db->query(
            "DELETE FROM __PREFIX__messages 
             WHERE (sender_id = ? AND receiver_id = ?) OR (sender_id = ? AND receiver_id = ?)",
            [$userId, $partnerId, $partnerId, $userId]
        );
    }

    /**
     * 删除单条消息（双向删除 - 删除后双方都看不到）
     * @param int $messageId 消息ID
     * @param int $userId 当前用户ID
     * @return bool
     */
    public function deleteMessage($messageId, $userId)
    {
        $message = $this->findById($messageId);
        if (!$message) {
            return false;
        }

        // 只有发送者或接收者才能删除
        if ($message['sender_id'] != $userId && $message['receiver_id'] != $userId) {
            return false;
        }

        return $this->db->query("DELETE FROM __PREFIX__messages WHERE id = ?", [$messageId]);
    }

    /**
     * 撤回消息（仅发送者可以撤回，且有时间限制）
     * @param int $messageId 消息ID
     * @param int $userId 当前用户ID
     * @param int $timeLimit 撤回时间限制（秒），默认120秒（2分钟）
     * @return array ['success' => bool, 'message' => string]
     */
    public function recall($messageId, $userId, $timeLimit = 120)
    {
        $message = $this->findById($messageId);
        if (!$message) {
            return ['success' => false, 'message' => '消息不存在'];
        }

        // 检查是否是发送者
        if ($message['sender_id'] != $userId) {
            return ['success' => false, 'message' => '只能撤回自己发送的消息'];
        }

        // 检查是否超过撤回时间限制
        $elapsed = time() - $message['created_at'];
        if ($elapsed > $timeLimit) {
            return ['success' => false, 'message' => '消息已发送超过' . round($timeLimit / 60) . '分钟，无法撤回'];
        }

        // 将消息内容替换为撤回提示
        $result = $this->db->query(
            "UPDATE __PREFIX__messages SET content = '此消息已被撤回', type = 'recall' WHERE id = ?",
            [$messageId]
        );

        if ($result) {
            return ['success' => true, 'message' => '撤回成功'];
        }
        return ['success' => false, 'message' => '撤回失败'];
    }

    /**
     * 根据ID获取单条消息
     * @param int $messageId
     * @return array|null
     */
    public function findById($messageId)
    {
        return $this->db->fetch(
            "SELECT * FROM __PREFIX__messages WHERE id = ?",
            [$messageId]
        );
    }

    /**
     * 获取消息详情（带发送者信息）
     * @param int $messageId
     * @param int $userId 当前用户（用于权限验证）
     * @return array|null
     */
    public function getMessageDetail($messageId, $userId)
    {
        $sql = "SELECT m.*, u.username, u.avatar
                FROM __PREFIX__messages m
                INNER JOIN __PREFIX__users u ON m.sender_id = u.id
                WHERE m.id = ? AND (m.sender_id = ? OR m.receiver_id = ?)";
        return $this->db->fetch($sql, [$messageId, $userId, $userId]);
    }

    // ==================== 通话相关方法 ====================

    /**
     * 创建通话请求
     */
    public function createCall($callId, $callerId, $callerName, $callerAvatar, $calleeId, $type = 'voice')
    {
        $now = time();
        $this->db->insert('call_requests', [
            'call_id' => $callId,
            'caller_id' => $callerId,
            'caller_name' => $callerName,
            'caller_avatar' => $callerAvatar,
            'callee_id' => $calleeId,
            'type' => $type,
            'status' => 'pending',
            'created_at' => $now,
            'updated_at' => $now
        ]);
        return $this->db->lastInsertId();
    }

    /**
     * 获取通话请求
     */
    public function getCall($callId)
    {
        return $this->db->fetch("SELECT * FROM __PREFIX__call_requests WHERE call_id = ?", [$callId]);
    }

    /**
     * 获取用户的待处理来电
     */
    public function getPendingCallForUser($userId)
    {
        $sql = "SELECT cr.*, u.username as caller_name, u.avatar as caller_avatar
                FROM __PREFIX__call_requests cr
                INNER JOIN __PREFIX__users u ON cr.caller_id = u.id
                WHERE cr.callee_id = ? AND cr.status = 'pending' AND cr.updated_at > ?
                ORDER BY cr.created_at DESC
                LIMIT 1";
        return $this->db->fetch($sql, [$userId, time() - 60]); // 60秒内的待处理来电
    }

    /**
     * 更新通话状态
     */
    public function updateCallStatus($callId, $status)
    {
        return $this->db->query(
            "UPDATE __PREFIX__call_requests SET status = ?, updated_at = ? WHERE call_id = ?",
            [$status, time(), $callId]
        );
    }

    /**
     * 获取用户发起的通话
     */
    public function getOutgoingCall($userId)
    {
        $sql = "SELECT * FROM __PREFIX__call_requests 
                WHERE caller_id = ? AND status IN ('pending', 'accepted') 
                ORDER BY created_at DESC LIMIT 1";
        return $this->db->fetch($sql, [$userId]);
    }

    /**
     * 清理过期的通话记录（超过5分钟的）
     */
    public function cleanupExpiredCalls()
    {
        $this->db->query(
            "DELETE FROM __PREFIX__call_requests WHERE updated_at < ?",
            [time() - 300]
        );
    }
}
