<?php
/**
 * HuSNS - 一款免费开源的社交平台
 * 
 * @author  HYR
 * @QQ      281900864
 * @website https://huyourui.com
 * @license MIT
 * @声明    严禁用于违法违规用途
 */

/**
 * 移动端API控制器
 * 
 * 提供移动端专用的RESTful API接口
 * 所有接口返回JSON格式数据
 */
class MobileApiController extends Controller
{
    private $postModel;
    private $userModel;
    private $notificationModel;
    private $favoriteModel;

    public function __construct()
    {
        parent::__construct();
        $this->postModel = new PostModel();
        $this->userModel = new UserModel();
        $this->notificationModel = new NotificationModel();
        $this->favoriteModel = new FavoriteModel();
        
        header('Content-Type: application/json; charset=utf-8');
        header('Access-Control-Allow-Origin: *');
        header('Access-Control-Allow-Methods: GET, POST, DELETE, OPTIONS');
        header('Access-Control-Allow-Headers: Content-Type, X-Requested-With');
        
        if ($_SERVER['REQUEST_METHOD'] === 'OPTIONS') {
            http_response_code(200);
            exit;
        }
    }

    protected function requireLogin()
    {
        if (!isset($_SESSION['user_id']) || empty($_SESSION['user_id'])) {
            $this->error('请先登录', 401);
        }
        return $_SESSION['user_id'];
    }

    protected function success($data = null, $message = '操作成功')
    {
        echo json_encode([
            'code' => 0,
            'message' => $message,
            'data' => $data,
            'timestamp' => time()
        ], JSON_UNESCAPED_UNICODE);
        exit;
    }

    protected function error($message = '操作失败', $code = 1)
    {
        // 设置HTTP状态码
        if ($code === 401) {
            http_response_code(401);
        } elseif ($code === 403) {
            http_response_code(403);
        } elseif ($code === 404) {
            http_response_code(404);
        } else {
            http_response_code(200);
        }
        
        echo json_encode([
            'code' => $code,
            'message' => $message,
            'data' => null,
            'timestamp' => time()
        ], JSON_UNESCAPED_UNICODE);
        exit;
    }

    protected function paginate($items, $total, $page, $pageSize, $hasMore = null)
    {
        if ($hasMore === null) {
            $hasMore = count($items) >= $pageSize;
        }
        $this->success([
            'items' => $items,
            'pagination' => [
                'total' => $total,
                'page' => $page,
                'page_size' => $pageSize,
                'has_more' => $hasMore
            ]
        ]);
    }

    protected function input($key, $default = null)
    {
        if (isset($_GET[$key])) {
            return $_GET[$key];
        }
        if (isset($_POST[$key])) {
            return $_POST[$key];
        }
        $input = file_get_contents('php://input');
        $data = json_decode($input, true);
        if (is_array($data) && isset($data[$key])) {
            return $data[$key];
        }
        return $default;
    }

    private function formatPost($post, $userId = null)
    {
        $post['images'] = is_array($post['images']) ? $post['images'] : 
            ($post['images'] ? json_decode($post['images'], true) : []);
        $post['videos'] = is_array($post['videos']) ? $post['videos'] : 
            ($post['videos'] ? json_decode($post['videos'], true) : []);
        $post['attachments'] = is_array($post['attachments']) ? $post['attachments'] : 
            ($post['attachments'] ? json_decode($post['attachments'], true) : []);
        
        // 将图片路径转换为完整URL
        $post['images'] = array_map(function($img) {
            return Helper::uploadUrl($img);
        }, $post['images']);
        
        // 将视频路径转换为完整URL（支持对象格式和字符串格式）
        $post['videos'] = array_map(function($video) {
            if (is_array($video) && isset($video['path'])) {
                return Helper::uploadUrl($video['path']);
            }
            return Helper::uploadUrl($video);
        }, $post['videos']);
        
        $post['time_ago'] = Helper::formatTime($post['created_at']);
        // 使用移动端的话题和用户链接格式
        $topicUrl = Helper::url('mobile/topic?keyword=$1');
        $userUrl = Helper::url('mobile/user?username=$1');
        $post['content'] = Helper::parseContent($post['content'], $topicUrl, $userUrl);
        
        $post['is_liked'] = false;
        $post['is_favorited'] = false;
        $post['is_following'] = false;
        
        // 处理匿名发布
        $post['is_anonymous'] = !empty($post['is_anonymous']);
        if ($post['is_anonymous']) {
            // 匿名发布：隐藏真实用户信息
            $post['username'] = '匿名用户';
            $post['avatar'] = ''; // 不显示头像
            $post['user_id'] = 0; // 前端无法获取真实用户ID
            $post['is_online'] = false; // 匿名用户不显示在线状态
        } else {
            // 判断用户是否在线（5分钟内活跃视为在线）
            $post['is_online'] = false;
            if (!empty($post['last_activity'])) {
                $post['is_online'] = (time() - $post['last_activity']) < 300;
            }
        }
        
        if ($userId) {
            $post['is_liked'] = $this->postModel->isLiked($post['id'], $userId);
            $favoriteModel = new FavoriteModel();
            $post['is_favorited'] = $favoriteModel->isFavorited($post['id'], $userId);
            if ($post['user_id'] != $userId) {
                $post['is_following'] = $this->userModel->isFollowing($userId, $post['user_id']);
            }
        }
        
        // 直接返回本地头像URL，不使用首字符头像
        $post['avatar'] = !empty($post['avatar']) ? Helper::uploadUrl($post['avatar']) : '';
        
        // 处理IP地址，转换为地理位置
        if (!empty($post['ip'])) {
            require_once ROOT_PATH . 'core/IpLocation.php';
            $location = IpLocation::getLocation($post['ip']);
            if (!empty($location)) {
                $post['ip'] = $location;
            }
        }
        
        // 返回位置信息（用于显示地图卡片）
        if (!empty($post['location_lat']) && !empty($post['location_lng'])) {
            $post['location'] = [
                'lat' => $post['location_lat'],
                'lng' => $post['location_lng'],
                'name' => $post['location_name'] ?? ''
            ];
        } else if (!empty($post['location_name'])) {
            $post['location'] = [
                'lat' => '',
                'lng' => '',
                'name' => $post['location_name']
            ];
        }
        
        // 处理转发动态的原文
        $post['is_repost'] = false;
        if (!empty($post['repost_id'])) {
            if (!empty($post['original_post']) && is_array($post['original_post']) && !isset($post['original_post']['deleted'])) {
                $post['is_repost'] = true;
                $post['original_post'] = $this->formatOriginalPost($post['original_post']);
            }
        }
        
        return $post;
    }
    
    private function formatOriginalPost($post)
    {
        $post['images'] = is_array($post['images']) ? $post['images'] : 
            ($post['images'] ? json_decode($post['images'], true) : []);
        $post['videos'] = is_array($post['videos']) ? $post['videos'] : 
            ($post['videos'] ? json_decode($post['videos'], true) : []);
        $post['time_ago'] = Helper::formatTime($post['created_at']);
        // 使用移动端的话题和用户链接格式
        $topicUrl = Helper::url('mobile/topic?keyword=$1');
        $userUrl = Helper::url('mobile/user?username=$1');
        $post['content'] = Helper::parseContent($post['content'], $topicUrl, $userUrl);
        
        // 处理匿名发布
        $post['is_anonymous'] = !empty($post['is_anonymous']);
        if ($post['is_anonymous']) {
            $post['username'] = '匿名用户';
            $post['avatar'] = '';
            $post['user_id'] = 0;
            $post['is_online'] = false;
        } else {
            // 判断用户是否在线（5分钟内活跃视为在线）
            $post['is_online'] = false;
            if (!empty($post['last_activity'])) {
                $post['is_online'] = (time() - $post['last_activity']) < 300;
            }
        }
        
        // 直接返回本地头像URL，不使用首字符头像
        $post['avatar'] = !empty($post['avatar']) ? Helper::uploadUrl($post['avatar']) : '';
        
        // 处理IP地址，转换为地理位置
        if (!empty($post['ip'])) {
            require_once ROOT_PATH . 'core/IpLocation.php';
            $location = IpLocation::getLocation($post['ip']);
            if (!empty($location)) {
                $post['ip'] = $location;
            }
        }
        
        // 返回位置信息（用于显示地图卡片）
        if (!empty($post['location_lat']) && !empty($post['location_lng'])) {
            $post['location'] = [
                'lat' => $post['location_lat'],
                'lng' => $post['location_lng'],
                'name' => $post['location_name'] ?? ''
            ];
        } else if (!empty($post['location_name'])) {
            $post['location'] = [
                'lat' => '',
                'lng' => '',
                'name' => $post['location_name']
            ];
        }
        
        return $post;
    }

    private function formatUser($user, $currentUserId = null)
    {
        // 头像URL处理：优先检测文件是否存在，不存在则返回空字符串让前端处理
        $avatarUrl = '';
        if (!empty($user['avatar'])) {
            $filePath = UPLOAD_PATH . $user['avatar'];
            if (file_exists($filePath)) {
                $avatarUrl = Helper::uploadUrl($user['avatar']);
            }
        }
        
        // 判断用户是否在线（5分钟内活跃视为在线）
        $isOnline = false;
        if (!empty($user['last_activity'])) {
            $isOnline = (time() - $user['last_activity']) < 300;
        }
        
        // 背景图片URL处理
        $backgroundUrl = '';
        if (!empty($user['background'])) {
            // $user['background'] 存储的是 /uploads/background/xxx.jpg 格式
            $backgroundUrl = Helper::getBaseUrl() . $user['background'];
        }
        
        $result = [
            'id' => $user['id'],
            'username' => $user['username'],
            'avatar' => $avatarUrl,
            'background' => $backgroundUrl,
            'bio' => $user['bio'] ?? '',
            'created_at' => $user['created_at'] ?? 0,
            'is_vip' => !empty($user['is_vip']),
            'is_online' => $isOnline
        ];
        
        if ($currentUserId && $user['id'] != $currentUserId) {
            $result['is_following'] = $this->userModel->isFollowing($currentUserId, $user['id']) ? 1 : 0;
        }
        
        return $result;
    }

    private function formatNotification($notification)
    {
        // 格式化通知数据，确保返回前端需要的字段
        $avatarUrl = '';
        $avatar = $notification['sender_avatar'] ?? $notification['avatar'] ?? null;
        if ($avatar) {
            $avatarUrl = Helper::uploadUrl($avatar);
        }
        
        $senderId = $notification['sender_id'] ?? $notification['user_id'] ?? 0;
        
        // 检查当前用户是否已关注发送者
        $isFollowing = false;
        try {
            $userId = isset($_SESSION['user_id']) ? $_SESSION['user_id'] : null;
            if ($userId && $senderId) {
                $isFollowing = $this->userModel->isFollowing($userId, $senderId);
            }
        } catch (\Exception $e) {
            // 忽略错误
        }
        
        $notificationType = $notification['type'] ?? 'system';
        $postId = 0;
        if ($notificationType !== 'message') {
            $postId = $notification['target_id'] ?? $notification['post_id'] ?? 0;
        }
        
        $formatted = [
            'id' => $notification['id'] ?? 0,
            'type' => $notificationType,
            'user_id' => $senderId,
            'username' => $notification['sender_name'] ?? $notification['username'] ?? '系统',
            'avatar' => $avatarUrl,
            'content' => $notification['content'] ?? '',
            'post_content' => $notification['extra'] ?? $notification['post_content'] ?? '',
            'post_id' => $postId,
            'is_read' => !empty($notification['is_read']),
            'is_following' => $isFollowing,
            'created_at' => $notification['created_at'] ?? time(),
            'time_ago' => Helper::formatTime($notification['created_at'] ?? time())
        ];
        return $formatted;
    }

    public function login()
    {
        if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
            $this->error('请求方法错误');
        }

        $username = trim($this->input('username'));
        $password = $this->input('password');

        if (empty($username) || empty($password)) {
            $this->error('请填写用户名和密码');
        }

        $user = $this->userModel->login($username, $password);

        if ($user) {
            $_SESSION['user_id'] = $user['id'];
            $_SESSION['username'] = $user['username'];
            $_SESSION['is_admin'] = $user['is_admin'];
            session_regenerate_id(true);
            
            // 更新用户最后活跃时间
            $this->userModel->updateLastActivity($user['id']);

            $this->success([
                'user' => $this->formatUser($user, $user['id'])
            ], '登录成功');
        } else {
            $this->error('用户名或密码错误');
        }
    }

    public function register()
    {
        if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
            $this->error('请求方法错误');
        }

        if (!Setting::isRegistrationOpen()) {
            $this->error('注册功能已关闭');
        }

        $username = trim($this->input('username') ?? '');
        $password = $this->input('password') ?? '';
        $confirmPassword = $this->input('confirm_password') ?? '';
        $email = trim($this->input('email') ?? '');
        $emailCode = trim($this->input('email_code') ?? '');
        $inviteCode = trim($this->input('invite_code') ?? '');

        $errors = [];

        $minLength = Setting::getUsernameMinLength();
        $maxLength = Setting::getUsernameMaxLength();
        $usernameLength = mb_strlen($username, 'UTF-8');

        if ($usernameLength < $minLength) {
            $errors[] = '用户名至少需要' . $minLength . '个字符';
        } elseif ($usernameLength > $maxLength) {
            $errors[] = '用户名最多允许' . $maxLength . '个字符';
        } elseif (!preg_match('/^[a-zA-Z0-9_\x{4e00}-\x{9fa5}]+$/u', $username)) {
            $errors[] = '用户名只能包含字母、数字、下划线和中文';
        }

        if ($this->userModel->findByUsername($username)) {
            $errors[] = '用户名已存在';
        }

        if (strlen($password) < 6) {
            $errors[] = '密码长度至少6位';
        }

        // 只有当确认密码不为空时才验证密码一致性（移动端可能只有一个密码输入框）
        if (!empty($confirmPassword) && $password !== $confirmPassword) {
            $errors[] = '两次密码输入不一致';
        }

        $emailVerifyEnabled = Setting::isRegistrationEmailVerifyEnabled();
        $requireInviteCode = (int)Setting::get('require_invite_code', 0) === 1;

        if ($emailVerifyEnabled || !empty($email)) {
            if (!Security::validateEmail($email)) {
                $errors[] = '邮箱格式不正确';
            } else {
                $allowedSuffixes = Setting::getAllowedEmailSuffixes();
                if (!empty($allowedSuffixes)) {
                    $emailSuffix = substr($email, strrpos($email, '@') + 1);
                    if (!in_array($emailSuffix, $allowedSuffixes)) {
                        $errors[] = '只允许使用以下邮箱后缀注册：' . implode(', ', $allowedSuffixes);
                    }
                }
                if ($this->userModel->findByEmail($email)) {
                    $errors[] = '邮箱已被注册';
                }
            }
        }

        if ($emailVerifyEnabled) {
            if (empty($emailCode)) {
                $errors[] = '请输入邮箱验证码';
            } elseif (!Mailer::verifyCode($email, $emailCode, '注册')) {
                $errors[] = '验证码错误或已过期';
            }
        }

        if ($requireInviteCode) {
            if (empty($inviteCode)) {
                $errors[] = '请输入邀请码';
            } else {
                require_once ROOT_PATH . 'content/invite/InviteController.php';
                if (!InviteController::verifyCode($inviteCode)) {
                    $errors[] = '邀请码无效或已被使用';
                }
            }
        }

        if (!empty($errors)) {
            $this->error(implode('，', $errors));
        }

        $userId = $this->userModel->register([
            'username' => $username,
            'password' => $password,
            'email' => $email ?: ''
        ]);

        if ($userId) {
            if ($requireInviteCode && !empty($inviteCode)) {
                require_once ROOT_PATH . 'content/invite/InviteController.php';
                InviteController::useCode($inviteCode, $userId);
            }

            $_SESSION['user_id'] = $userId;
            $_SESSION['username'] = $username;
            $_SESSION['is_admin'] = 0;
            session_regenerate_id(true);

            $user = $this->userModel->find($userId);
            $this->success([
                'user' => $this->formatUser($user, $userId)
            ], '注册成功');
        } else {
            $this->error('注册失败');
        }
    }

    public function logout()
    {
        session_destroy();
        $this->success(null, '退出成功');
    }

    public function userInfo()
    {
        $currentUserId = isset($_SESSION['user_id']) ? $_SESSION['user_id'] : null;
        
        // 如果传入了 id 参数，获取指定用户的信息（用于查看其他用户资料）
        $targetUserId = $this->input('id', 0);
        $userId = $targetUserId ?: $currentUserId;
        
        if (!$userId) {
            $this->success(['logged_in' => false]);
        }

        $user = $this->userModel->find($userId);
        if (!$user) {
            if (!$currentUserId) {
                session_destroy();
                $this->success(['logged_in' => false]);
            } else {
                $this->error('用户不存在');
            }
        }

        $postCount = $this->postModel->count('user_id = ? AND status = 1', [$userId]);
        $followCount = $this->userModel->getFollowCount($userId);
        
        // 只有获取当前登录用户信息时才返回未读数量
        $notificationUnreadCount = 0;
        $favoriteCount = 0;
        $messageUnreadCount = 0;
        $totalUnreadCount = 0;
        
        if (!$targetUserId || $targetUserId == $currentUserId) {
            $notificationUnreadCount = $this->notificationModel->getUnreadCount($userId);
            $favoriteCount = $this->favoriteModel->countUserFavorites($userId);
            
            // 获取私信未读数量
            require_once ROOT_PATH . 'templates/mobile/MessageModel.php';
            $messageModel = new MessageModel();
            $messageUnreadCount = $messageModel->getUnreadCount($userId);
            
            // 计算总未读数量（通知 + 私信）
            $totalUnreadCount = $notificationUnreadCount + $messageUnreadCount;
        }

        $this->success([
            'logged_in' => (bool)$currentUserId,
            'user' => $this->formatUser($user, $currentUserId),
            'stats' => [
                'post_count' => $postCount,
                'following' => $followCount['following'] ?? 0,
                'followers' => $followCount['followers'] ?? 0,
                'favorites' => $favoriteCount,
                'unread_count' => $totalUnreadCount,
                'notification_unread' => $notificationUnreadCount,
                'message_unread' => $messageUnreadCount
            ]
        ]);
    }

    public function posts()
    {
        $userId = isset($_SESSION['user_id']) ? $_SESSION['user_id'] : null;
        
        // 调试日志
        error_log('posts API called, userId: ' . ($userId ?: 'null'));
        error_log('GET params: ' . json_encode($_GET));
        
        if (!$userId && !Setting::isGuestAccessAllowed()) {
            error_log('posts API: guest access not allowed, returning 401');
            $this->error('请先登录', 401);
        }

        $page = (int)$this->input('page', 1);
        $tab = $this->input('tab', 'all');
        $pageSize = 15;
        
        error_log('posts API: page=' . $page . ', tab=' . $tab);

        $posts = $this->postModel->getTimeline($page, $pageSize, $userId, $tab, false);
        error_log('posts API: fetched ' . count($posts) . ' posts');
        
        // 调试：检查第一个转发动态的数据
        foreach ($posts as $i => $p) {
            if (!empty($p['repost_id'])) {
                error_log('posts API: post['.$i.'] repost_id=' . $p['repost_id'] . ', has original_post=' . (isset($p['original_post']) ? 'yes' : 'no'));
                if (isset($p['original_post'])) {
                    error_log('posts API: original_post keys=' . implode(',', array_keys($p['original_post'])));
                }
            }
        }
        
        $formattedPosts = [];
        foreach ($posts as $post) {
            $formattedPosts[] = $this->formatPost($post, $userId);
        }

        $total = $this->postModel->getTimelineCount($userId, $tab, false);
        error_log('posts API: total count=' . $total);
        
        $this->paginate($formattedPosts, $total, $page, $pageSize);
    }

    public function hotPosts()
    {
        $userId = isset($_SESSION['user_id']) ? $_SESSION['user_id'] : null;
        
        if (!$userId && !Setting::isGuestAccessAllowed()) {
            $this->error('请先登录', 401);
        }

        $page = max(1, (int)$this->input('page', 1));
        $pageSize = 15;
        $threshold = max(0, (int)Setting::getHotThreshold());
        $offset = ($page - 1) * $pageSize;
        
        // 获取时间类型参数
        $type = $this->input('type', 'day');
        
        // 根据时间类型计算时间范围
        $timeCondition = '';
        switch ($type) {
            case 'day':
                // 今日：从今天0点到现在
                $timeCondition = "AND p.created_at >= '" . date('Y-m-d 00:00:00') . "'";
                break;
            case 'week':
                // 本周：从周一0点到现在
                $weekStart = date('Y-m-d 00:00:00', strtotime('monday this week'));
                $timeCondition = "AND p.created_at >= '" . $weekStart . "'";
                break;
            case 'month':
                // 本月：从月初0点到现在
                $monthStart = date('Y-m-01 00:00:00');
                $timeCondition = "AND p.created_at >= '" . $monthStart . "'";
                break;
            default:
                // 默认显示今日
                $timeCondition = "AND p.created_at >= '" . date('Y-m-d 00:00:00') . "'";
        }

        $sql = "SELECT p.*, u.username, u.avatar, u.last_activity,
                    (
                        (SELECT COUNT(*) FROM __PREFIX__likes l WHERE l.post_id = p.id AND l.user_id != p.user_id) +
                        (SELECT COUNT(*) FROM __PREFIX__comments c WHERE c.post_id = p.id AND c.user_id != p.user_id AND c.status = 1) +
                        (SELECT COUNT(*) FROM __PREFIX__posts rp WHERE rp.repost_id = p.id AND rp.user_id != p.user_id AND rp.status = 1) +
                        (SELECT COUNT(*) FROM __PREFIX__favorites f WHERE f.post_id = p.id AND f.user_id != p.user_id)
                    ) as hot_score
                FROM __PREFIX__posts p 
                INNER JOIN __PREFIX__users u ON p.user_id = u.id 
                WHERE p.status = 1 
                {$timeCondition}
                HAVING hot_score >= ?
                ORDER BY hot_score DESC, p.created_at DESC 
                LIMIT {$offset}, {$pageSize}";

        $posts = $this->db->fetchAll($sql, [$threshold]);
        
        $formattedPosts = [];
        foreach ($posts as $post) {
            $formattedPosts[] = $this->formatPost($post, $userId);
        }

        $this->success([
            'items' => $formattedPosts,
            'pagination' => [
                'page' => $page,
                'page_size' => $pageSize,
                'has_more' => count($formattedPosts) >= $pageSize
            ]
        ]);
    }

    public function topicPosts()
    {
        $userId = isset($_SESSION['user_id']) ? $_SESSION['user_id'] : null;
        
        if (!$userId && !Setting::isGuestAccessAllowed()) {
            $this->error('请先登录', 401);
        }

        $keyword = trim($this->input('keyword'));
        if (empty($keyword)) {
            $this->error('话题不能为空');
        }

        $page = (int)$this->input('page', 1);
        $pageSize = 15;

        $posts = $this->postModel->getPostsByTopic($keyword, $page, $pageSize);
        
        $formattedPosts = [];
        foreach ($posts as $post) {
            $formattedPosts[] = $this->formatPost($post, $userId);
        }

        $total = $this->postModel->countPostsByTopic($keyword);
        $this->paginate($formattedPosts, $total, $page, $pageSize);
    }

    public function postDetail()
    {
        $userId = isset($_SESSION['user_id']) ? $_SESSION['user_id'] : null;
        
        if (!$userId && !Setting::isGuestAccessAllowed()) {
            $this->error('请先登录', 401);
        }

        $id = (int)$this->input('id');
        if (!$id) {
            $this->error('参数错误');
        }

        $post = $this->postModel->getPost($id, $userId ? $userId : 0);
        if (!$post || $post['status'] != 1) {
            $this->error('动态不存在');
        }

        $this->success([
            'post' => $this->formatPost($post, $userId)
        ]);
    }

    public function comments()
    {
        $userId = isset($_SESSION['user_id']) ? $_SESSION['user_id'] : null;
        
        if (!$userId && !Setting::isGuestAccessAllowed()) {
            $this->error('请先登录', 401);
        }

        $postId = (int)$this->input('post_id');
        $page = (int)$this->input('page', 1);
        $pageSize = 20;

        if (!$postId) {
            $this->error('参数错误');
        }

        $comments = $this->postModel->getComments($postId, $page, $pageSize);
        
        $formattedComments = [];
        foreach ($comments as $comment) {
            $comment['time_ago'] = Helper::formatTime($comment['created_at']);
            $comment['avatar'] = Helper::avatar($comment['avatar'] ?? null, $comment['username']);
            // 检查当前用户是否点赞过该评论
            $comment['is_liked'] = $userId ? $this->postModel->isCommentLiked($comment['id'], $userId) : false;
            // 使用移动端的话题和用户链接格式
            $topicUrl = Helper::url('mobile/topic?keyword=$1');
            $userUrl = Helper::url('mobile/user?username=$1');
            $comment['content'] = Helper::parseContent($comment['content'], $topicUrl, $userUrl);
            $formattedComments[] = $comment;
        }

        $this->success([
            'items' => $formattedComments,
            'pagination' => [
                'page' => $page,
                'page_size' => $pageSize,
                'has_more' => count($formattedComments) >= $pageSize
            ]
        ]);
    }

    /**
     * 获取用户加入的圈子列表
     */
    public function getUserCircles()
    {
        try {
            $userId = $this->requireLogin();
            
            require_once ROOT_PATH . 'content/circle/CircleModel.php';
            $circleModel = new CircleModel();
            
            // 获取所有公开圈子
            $circleResult = $circleModel->getCircles(1, 100, '', 1);
            $circles = isset($circleResult['items']) ? $circleResult['items'] : [];
            
            // 获取用户已加入的圈子ID列表
            $userCircles = $circleModel->getUserCircles($userId);
            $userCircleIds = array_column($userCircles, 'id');
            
            $result = [];
            foreach ($circles as $circle) {
                if (!is_array($circle) || !isset($circle['id'])) {
                    continue;
                }
                $result[] = [
                    'id' => $circle['id'],
                    'name' => isset($circle['name']) ? $circle['name'] : '',
                    'avatar' => !empty($circle['avatar']) ? Helper::uploadUrl($circle['avatar']) : null,
                    'joined' => in_array($circle['id'], $userCircleIds)
                ];
            }
            
            $this->success($result);
        } catch (Exception $e) {
            // 记录错误日志
            error_log('getUserCircles error: ' . $e->getMessage() . ' in ' . $e->getFile() . ' line ' . $e->getLine());
            $this->error('获取圈子列表失败: ' . $e->getMessage(), 500);
        }
    }

    public function getCirclesList()
    {
        try {
            $userId = isset($_SESSION['user_id']) ? $_SESSION['user_id'] : null;
            
            global $db;
            if (!isset($db)) {
                require_once ROOT_PATH . 'core/Database.php';
                $db = Database::getInstance();
            }
            
            $prefix = $db->getPrefix();
            $circles = $db->fetchAll("SELECT * FROM `" . $prefix . "circles` ORDER BY created_at DESC LIMIT 100");
            
            if ($circles === false) {
                $this->error('获取圈子列表失败');
                return;
            }
            
            $userCircleIds = [];
            if ($userId) {
                $userCircles = $db->fetchAll("SELECT circle_id FROM `" . $prefix . "circle_members` WHERE user_id = ?", [$userId]);
                $userCircleIds = array_column($userCircles, 'circle_id');
            }
            
            $result = [];
            foreach ($circles as $circle) {
                if (!is_array($circle) || !isset($circle['id'])) {
                    continue;
                }
                $result[] = [
                    'id' => $circle['id'],
                    'name' => isset($circle['name']) ? $circle['name'] : '',
                    'avatar' => !empty($circle['avatar']) ? Helper::uploadUrl($circle['avatar']) : null,
                    'cover' => !empty($circle['cover']) ? Helper::uploadUrl($circle['cover']) : (!empty($circle['banner']) ? Helper::uploadUrl($circle['banner']) : null),
                    'description' => isset($circle['description']) ? $circle['description'] : '',
                    'member_count' => isset($circle['member_count']) ? (int)$circle['member_count'] : 0,
                    'post_count' => isset($circle['post_count']) ? (int)$circle['post_count'] : 0,
                    'is_verified' => isset($circle['is_verified']) ? (bool)$circle['is_verified'] : false,
                    'verify_type' => isset($circle['verify_type']) ? (int)$circle['verify_type'] : 0,
                    'verify_info' => isset($circle['verify_info']) ? $circle['verify_info'] : '',
                    'joined' => in_array($circle['id'], $userCircleIds)
                ];
            }
            
            $this->success($result);
        } catch (Exception $e) {
            $this->error('获取圈子列表失败: ' . $e->getMessage());
        }
    }

    public function joinCircle()
    {
        $userId = $this->requireLogin();
        
        $circleId = (int)$this->input('circle_id');
        if (!$circleId) {
            $this->error('参数错误');
        }
        
        require_once ROOT_PATH . 'content/circle/CircleModel.php';
        $circleModel = new CircleModel();
        
        $circle = $circleModel->getCircle($circleId);
        if (!$circle) {
            $this->error('圈子不存在');
        }
        
        if ($circle['status'] != 1) {
            $this->error('圈子已禁用');
        }
        
        $userCircles = $circleModel->getUserCircles($userId);
        $userCircleIds = array_column($userCircles, 'id');
        if (in_array($circleId, $userCircleIds)) {
            $this->error('您已加入该圈子');
        }
        
        $result = $circleModel->joinCircle($circleId, $userId);
        if ($result) {
            $this->success('加入成功');
        } else {
            $this->error('加入失败');
        }
    }

    public function exitCircle()
    {
        $userId = $this->requireLogin();
        
        $circleId = (int)$this->input('circle_id');
        if (!$circleId) {
            $this->error('参数错误');
        }
        
        require_once ROOT_PATH . 'content/circle/CircleModel.php';
        $circleModel = new CircleModel();
        
        $circle = $circleModel->getCircle($circleId);
        if (!$circle) {
            $this->error('圈子不存在');
        }
        
        $userCircles = $circleModel->getUserCircles($userId);
        $userCircleIds = array_column($userCircles, 'id');
        if (!in_array($circleId, $userCircleIds)) {
            $this->error('您未加入该圈子');
        }
        
        $result = $circleModel->removeMember($circleId, $userId);
        if ($result) {
            $this->success('退出成功');
        } else {
            $this->error('退出失败');
        }
    }

    public function getCircleInfo()
    {
        $circleId = (int)$this->input('circle_id');
        if (!$circleId) {
            $this->error('参数错误');
        }
        
        $userId = isset($_SESSION['user_id']) ? $_SESSION['user_id'] : null;
        
        require_once ROOT_PATH . 'content/circle/CircleModel.php';
        $circleModel = new CircleModel();
        
        $circle = $circleModel->getCircle($circleId);
        if (!$circle) {
            $this->error('圈子不存在');
        }
        
        $joined = false;
        if ($userId) {
            $userCircles = $circleModel->getUserCircles($userId);
            $userCircleIds = array_column($userCircles, 'id');
            $joined = in_array($circleId, $userCircleIds);
        }
        
        $this->success([
            'id' => $circle['id'],
            'name' => $circle['name'],
            'description' => isset($circle['description']) ? $circle['description'] : '',
            'avatar' => !empty($circle['avatar']) ? Helper::uploadUrl($circle['avatar']) : null,
            'cover' => !empty($circle['cover']) ? Helper::uploadUrl($circle['cover']) : null,
            'member_count' => isset($circle['member_count']) ? (int)$circle['member_count'] : 0,
            'post_count' => isset($circle['post_count']) ? (int)$circle['post_count'] : 0,
            'is_verified' => isset($circle['is_verified']) ? (bool)$circle['is_verified'] : false,
            'verify_type' => isset($circle['verify_type']) ? (int)$circle['verify_type'] : 0,
            'verify_info' => isset($circle['verify_info']) ? $circle['verify_info'] : '',
            'joined' => $joined
        ]);
    }

    public function getCirclePosts()
    {
        $circleId = (int)$this->input('circle_id');
        if (!$circleId) {
            $this->error('参数错误');
        }
        
        $page = (int)$this->input('page', 1);
        $limit = 10;
        $offset = ($page - 1) * $limit;
        
        $userId = isset($_SESSION['user_id']) ? (int)$_SESSION['user_id'] : 0;
        
        require_once ROOT_PATH . 'content/post/PostModel.php';
        $postModel = new PostModel();
        
        $posts = $postModel->getPostsByCircle($circleId, $offset, $limit);
        
        $result = [];
        foreach ($posts as $post) {
            // 处理用户头像路径
            $userAvatar = !empty($post['user_avatar']) ? Helper::uploadUrl($post['user_avatar']) : '';
            
            // 处理图片路径
            $images = [];
            if (!empty($post['images'])) {
                $imagePaths = is_string($post['images']) ? json_decode($post['images'], true) : ($post['images'] ?? []);
                foreach ($imagePaths as $img) {
                    $images[] = Helper::uploadUrl($img);
                }
            }
            
            // 检查当前用户是否已点赞
            $liked = $userId > 0 ? $postModel->isLiked($post['id'], $userId) : false;
            
            $result[] = [
                'id' => $post['id'],
                'content' => $post['content'],
                'images' => $images,
                'user_id' => $post['user_id'],
                'user_name' => $post['user_name'],
                'user_avatar' => $userAvatar,
                'circle_id' => isset($post['circle_id']) ? (int)$post['circle_id'] : 0,
                'circle_name' => isset($post['circle_name']) ? $post['circle_name'] : '',
                'likes' => isset($post['likes']) ? (int)$post['likes'] : 0,
                'comments' => isset($post['comments']) ? (int)$post['comments'] : 0,
                'reposts' => isset($post['reposts']) ? (int)$post['reposts'] : 0,
                'is_liked' => $liked,
                'created_at' => $post['created_at']
            ];
        }
        
        $this->success($result);
    }

    public function getCirclePostsList()
    {
        $page = (int)$this->input('page', 1);
        $limit = 10;
        $offset = ($page - 1) * $limit;
        
        $userId = isset($_SESSION['user_id']) ? (int)$_SESSION['user_id'] : 0;
        
        require_once ROOT_PATH . 'content/post/PostModel.php';
        $postModel = new PostModel();
        
        $sql = "SELECT p.*, u.username as user_name, u.avatar as user_avatar,
                       c.id as circle_id, c.name as circle_name, c.is_verified as circle_verified
                FROM __PREFIX__circle_posts cp
                INNER JOIN __PREFIX__posts p ON cp.post_id = p.id
                INNER JOIN __PREFIX__users u ON p.user_id = u.id
                INNER JOIN __PREFIX__circles c ON cp.circle_id = c.id
                WHERE p.status = 1
                AND c.status = 1
                AND (u.ban_type = 0 OR u.ban_type = 1 OR u.ban_type IS NULL OR (u.ban_type = 1 AND u.ban_until > ?))
                ORDER BY p.created_at DESC
                LIMIT {$offset}, {$limit}";
        
        $posts = $this->db->fetchAll($sql, [time()]);
        
        $result = [];
        foreach ($posts as $post) {
            // 处理用户头像路径
            $userAvatar = !empty($post['user_avatar']) ? Helper::uploadUrl($post['user_avatar']) : '';
            
            // 处理图片路径
            $images = [];
            if (!empty($post['images'])) {
                $imagePaths = is_string($post['images']) ? json_decode($post['images'], true) : ($post['images'] ?? []);
                foreach ($imagePaths as $img) {
                    $images[] = Helper::uploadUrl($img);
                }
            }
            
            // 检查当前用户是否已点赞
            $liked = $userId > 0 ? $postModel->isLiked($post['id'], $userId) : false;
            
            $result[] = [
                'id' => $post['id'],
                'content' => $post['content'],
                'images' => $images,
                'user_id' => $post['user_id'],
                'user_name' => $post['user_name'],
                'user_avatar' => $userAvatar,
                'circle_id' => (int)$post['circle_id'],
                'circle_name' => $post['circle_name'],
                'circle_verified' => isset($post['circle_verified']) ? (bool)$post['circle_verified'] : false,
                'likes' => isset($post['likes']) ? (int)$post['likes'] : 0,
                'comments' => isset($post['comments']) ? (int)$post['comments'] : 0,
                'reposts' => isset($post['reposts']) ? (int)$post['reposts'] : 0,
                'is_liked' => $liked,
                'created_at' => $post['created_at']
            ];
        }
        
        $this->success($result);
    }

    public function publish()
    {
        $userId = $this->requireLogin();

        $banInfo = $this->userModel->getBanInfo($userId);
        if ($banInfo) {
            $this->error('您已被' . $banInfo['type_text'] . '，无法发布内容');
        }

        $content = trim($this->input('content'));
        
        // 允许空内容但必须有图片或视频
        $hasMedia = (!empty($_FILES['images']) && is_array($_FILES['images']['name'])) || 
                    (!empty($_FILES['video']) && $_FILES['video']['error'] === UPLOAD_ERR_OK);
        
        if (empty($content) && !$hasMedia) {
            $this->error('内容不能为空');
        }

        if (!empty($content) && mb_strlen($content, 'UTF-8') > Setting::getMaxPostLength()) {
            $this->error('内容不能超过' . Setting::getMaxPostLength() . '字');
        }

        $content = Security::xssClean($content);

        $images = [];
        if (!empty($_FILES['images']) && is_array($_FILES['images']['name'])) {
            $images = $this->uploadImages();
        } elseif (!empty($_POST['images']) && is_array($_POST['images'])) {
            $images = array_values(array_filter($_POST['images'], function($path) {
                return !empty($path) && is_string($path) && preg_match('/^[a-zA-Z0-9_\-\/\.]+$/', $path);
            }));
        }

        // 处理视频上传
        $videos = [];
        if (!empty($_FILES['video']) && $_FILES['video']['error'] === UPLOAD_ERR_OK) {
            $video = $this->uploadVideo();
            if (!empty($video)) {
                $videos = [$video];
            }
        }

        // 获取匿名发布状态
        $isAnonymous = !empty($_POST['is_anonymous']) ? 1 : 0;
        
        // 获取位置信息
        $locationLatLng = !empty($_POST['location_latlng']) ? trim($_POST['location_latlng']) : '';
        
        // 获取圈子信息
        $circleId = (int)$this->input('circle_id', 0);
        $circleName = trim($this->input('circle_name', ''));

        $postId = $this->postModel->publish([
            'user_id' => $userId,
            'content' => $content,
            'images' => $images,
            'videos' => $videos,
            'is_anonymous' => $isAnonymous,
            'location_latlng' => $locationLatLng,
            'circle_id' => $circleId,
            'circle_name' => $circleName
        ]);

        if ($postId) {
            Point::change($userId, 'publish_post', 'post', $postId);
            
            try {
                $this->sendMentionNotifications($content, $postId, $userId, null);
            } catch (Exception $e) {}

            $post = $this->postModel->getPost($postId, $userId);
            $this->success([
                'post' => $this->formatPost($post, $userId)
            ], '发布成功');
        }

        $this->error('发布失败');
    }

    public function like()
    {
        $userId = $this->requireLogin();

        $banInfo = $this->userModel->getBanInfo($userId);
        if ($banInfo) {
            $this->error('您已被' . $banInfo['type_text'] . '，无法点赞');
        }

        $id = (int)$this->input('id');
        $result = $this->postModel->like($id, $userId);

        if ($result) {
            Point::change($userId, 'like_post', 'post', $id);
            
            $post = $this->postModel->getPost($id, $userId);
            if ($post && isset($post['user_id']) && $post['user_id'] != $userId) {
                $this->sendLikeNotification($post['user_id'], $id);
            }

            $this->success(['likes' => $post['likes'] ?? 0]);
        } else {
            $this->error('已点赞过');
        }
    }

    public function unlike()
    {
        $userId = $this->requireLogin();

        $id = (int)$this->input('id');
        $result = $this->postModel->unlike($id, $userId);

        if ($result) {
            $post = $this->postModel->getPost($id, $userId);
            $this->success(['likes' => $post['likes'] ?? 0]);
        } else {
            $this->error('取消点赞失败');
        }
    }

    /**
     * 评论点赞
     */
    public function likeComment()
    {
        $userId = $this->requireLogin();

        $banInfo = $this->userModel->getBanInfo($userId);
        if ($banInfo) {
            $this->error('您已被' . $banInfo['type_text'] . '，无法点赞');
        }

        $commentId = (int)$this->input('comment_id');
        if (!$commentId) {
            $this->error('评论ID不能为空');
        }

        $result = $this->postModel->likeComment($commentId, $userId);

        if ($result) {
            $likes = $this->postModel->getCommentLikes($commentId);
            $this->success(['likes' => $likes]);
        } else {
            $this->error('已点赞过');
        }
    }

    /**
     * 取消评论点赞
     */
    public function unlikeComment()
    {
        $userId = $this->requireLogin();

        $commentId = (int)$this->input('comment_id');
        if (!$commentId) {
            $this->error('评论ID不能为空');
        }

        $result = $this->postModel->unlikeComment($commentId, $userId);

        if ($result) {
            $likes = $this->postModel->getCommentLikes($commentId);
            $this->success(['likes' => $likes]);
        } else {
            $this->error('取消点赞失败');
        }
    }

    public function favorite()
    {
        $userId = $this->requireLogin();

        $id = (int)$this->input('id');
        $post = $this->postModel->find($id);

        if (!$post || $post['status'] != 1) {
            $this->error('动态不存在');
        }

        if ($post['user_id'] == $userId) {
            $this->error('不能收藏自己的动态');
        }

        $favoriteModel = new FavoriteModel();
        $result = $favoriteModel->add($id, $userId);

        if ($result) {
            $this->sendFavoriteNotification($post['user_id'], $id);
            $this->success(null, '收藏成功');
        } else {
            $this->error('已收藏过');
        }
    }

    public function unfavorite()
    {
        $userId = $this->requireLogin();

        $id = (int)$this->input('id');
        $favoriteModel = new FavoriteModel();
        $result = $favoriteModel->remove($id, $userId);

        if ($result) {
            $this->success(null, '取消收藏成功');
        } else {
            $this->error('取消收藏失败');
        }
    }

    public function comment()
    {
        $userId = $this->requireLogin();

        $banInfo = $this->userModel->getBanInfo($userId);
        if ($banInfo) {
            $this->error('您已被' . $banInfo['type_text'] . '，无法发表评论');
        }

        $postId = (int)$this->input('post_id');
        $content = trim($this->input('content'));
        $parentId = (int)$this->input('parent_id', 0);
        $replyToUserId = (int)$this->input('reply_to_user_id', 0);

        if (empty($content)) {
            $this->error('评论内容不能为空');
        }

        if (mb_strlen($content, 'UTF-8') > Setting::getMaxCommentLength()) {
            $this->error('评论内容不能超过' . Setting::getMaxCommentLength() . '字');
        }

        $content = Security::xssClean($content);

        $db = Database::getInstance();
        $db->insert('comments', [
            'post_id' => $postId,
            'user_id' => $userId,
            'content' => $content,
            'parent_id' => $parentId,
            'reply_to_user_id' => $replyToUserId,
            'status' => 1,
            'ip' => Helper::getIp(),
            'created_at' => time()
        ]);

        $commentId = $db->lastInsertId();

        if ($commentId) {
            Point::change($userId, 'publish_comment', 'comment', $commentId);
            
            $db->query(
                "UPDATE __PREFIX__posts SET comments = comments + 1 WHERE id = ?",
                [$postId]
            );

            try {
                $post = $this->postModel->getPost($postId, $userId);
                if ($post && $post['user_id'] != $userId) {
                    $sender = $this->userModel->find($userId);
                    if ($sender) {
                        $this->notificationModel->sendCommentNotification(
                            $post['user_id'], $userId, $postId, $content, $sender['username']
                        );
                    }
                }

                if ($replyToUserId && $replyToUserId != $userId) {
                    $sender = $this->userModel->find($userId);
                    if ($sender) {
                        $this->notificationModel->send(
                            $replyToUserId,
                            NotificationModel::TYPE_COMMENT,
                            "{$sender['username']} 回复了你的评论",
                            mb_substr($content, 0, 50, 'UTF-8'),
                            [
                                'sender_id' => $userId,
                                'target_type' => NotificationModel::TARGET_POST,
                                'target_id' => $postId,
                                'data' => ['post_id' => $postId, 'comment_id' => $commentId]
                            ]
                        );
                    }
                }

                $this->sendMentionNotifications($content, $postId, $userId, $commentId);
            } catch (Exception $e) {}

            $comment = $db->fetch(
                "SELECT c.*, u.username, u.avatar, u.last_activity
                 FROM __PREFIX__comments c 
                 INNER JOIN __PREFIX__users u ON c.user_id = u.id 
                 WHERE c.id = ?",
                [$commentId]
            );

            if ($comment) {
                $comment['time_ago'] = Helper::formatTime($comment['created_at']);
                $comment['avatar'] = Helper::avatar($comment['avatar'] ?? null, $comment['username']);
                // 使用移动端的话题和用户链接格式
                $topicUrl = Helper::url('mobile/topic?keyword=$1');
                $userUrl = Helper::url('mobile/user?username=$1');
                $comment['content'] = Helper::parseContent($comment['content'], $topicUrl, $userUrl);
            }

            $this->success([
                'comment' => $comment
            ], '评论成功');
        }

        $this->error('评论失败');
    }

    public function deletePost()
    {
        $userId = $this->requireLogin();

        $id = (int)($this->input('post_id') ?? $this->input('id'));
        if (!$id) {
            $this->error('参数错误');
        }

        $post = $this->postModel->find($id);
        if (!$post) {
            $this->error('帖子不存在');
        }

        // 检查权限：只能删除自己的帖子或管理员
        if ($post['user_id'] != $userId && empty($_SESSION['is_admin'])) {
            $this->error('没有权限');
        }

        $result = $this->postModel->deletePost($id, $userId);

        if ($result) {
            Point::change($userId, 'delete_post', 'post', $id);
            $this->success(null, '删除成功');
        } else {
            $this->error('删除失败');
        }
    }

    // 置顶/取消置顶帖子
    public function setTop()
    {
        if (empty($_SESSION['is_admin'])) {
            $this->error('没有权限', 403);
        }

        $id = (int)($this->input('post_id') ?? $this->input('id'));
        if (!$id) {
            $this->error('参数错误');
        }

        $post = $this->postModel->find($id);
        if (!$post) {
            $this->error('帖子不存在');
        }

        $result = $this->postModel->togglePin($id);
        if ($result) {
            $newStatus = !empty($post['is_pinned']) ? 0 : 1;
            $this->success([
                'is_pinned' => $newStatus
            ], $newStatus ? '置顶成功' : '已取消置顶');
        } else {
            $this->error('操作失败');
        }
    }

    // 加精/取消加精帖子
    public function setEssence()
    {
        if (empty($_SESSION['is_admin'])) {
            $this->error('没有权限', 403);
        }

        $id = (int)($this->input('post_id') ?? $this->input('id'));
        if (!$id) {
            $this->error('参数错误');
        }

        $post = $this->postModel->find($id);
        if (!$post) {
            $this->error('帖子不存在');
        }

        $result = $this->postModel->toggleFeature($id);
        if ($result) {
            $newStatus = !empty($post['is_featured']) ? 0 : 1;
            $this->success([
                'is_featured' => $newStatus
            ], $newStatus ? '加精成功' : '已取消加精');
        } else {
            $this->error('操作失败');
        }
    }

    public function repost()
    {
        $userId = $this->requireLogin();

        $banInfo = $this->userModel->getBanInfo($userId);
        if ($banInfo) {
            $this->error('您已被' . $banInfo['type_text'] . '，无法转发动态');
        }

        $originalPostId = (int)$this->input('post_id');
        $content = trim($this->input('content'));
        $alsoComment = (int)$this->input('also_comment', 0);

        if (!$originalPostId) {
            $this->error('参数错误');
        }

        $originalPost = $this->postModel->getPost($originalPostId, $userId);
        if (!$originalPost || $originalPost['status'] != 1) {
            $this->error('原动态不存在');
        }

        if (mb_strlen($content, 'UTF-8') > Setting::getMaxPostLength()) {
            $this->error('转发内容不能超过' . Setting::getMaxPostLength() . '字');
        }

        $content = Security::xssClean($content);

        $postId = $this->postModel->repost($userId, $originalPostId, $content, $alsoComment);

        if ($postId) {
            Point::change($userId, 'repost', 'post', $postId);

            try {
                $sender = $this->userModel->find($userId);
                if ($sender && $originalPost['user_id'] != $userId) {
                    $this->notificationModel->send(
                        $originalPost['user_id'],
                        NotificationModel::TYPE_FOLLOW,
                        "{$sender['username']} 转发了你的动态",
                        mb_substr($content ?: $originalPost['content'], 0, 50, 'UTF-8'),
                        [
                            'sender_id' => $userId,
                            'target_type' => NotificationModel::TARGET_POST,
                            'target_id' => $originalPostId,
                            'data' => ['post_id' => $postId, 'original_post_id' => $originalPostId]
                        ]
                    );
                }

                if ($content) {
                    $this->sendMentionNotifications($content, $postId, $userId, null);
                }
            } catch (Exception $e) {}

            $post = $this->postModel->getPost($postId, $userId);
            $this->success([
                'post' => $this->formatPost($post, $userId)
            ], '转发成功');
        }

        $this->error('转发失败');
    }

    public function notifications()
    {
        $userId = $this->requireLogin();

        $page = (int)$this->input('page', 1);
        $pageSize = 20;
        $type = $this->input('type', 'all');

        // 调试信息
        error_log('notifications API called, userId: ' . $userId . ', type: ' . $type);

        $notifications = $this->notificationModel->getUserNotifications($userId, $page, $pageSize, $type);
        $notificationUnreadCount = $this->notificationModel->getUnreadCount($userId);
        $mentionCount = $this->notificationModel->getUnreadCount($userId, 'mention');
        $likeCount = $this->notificationModel->getUnreadCount($userId, 'like');
        $commentCount = $this->notificationModel->getUnreadCount($userId, 'comment');
        
        // 获取私信未读数量
        require_once ROOT_PATH . 'templates/mobile/MessageModel.php';
        $messageModel = new MessageModel();
        $messageUnreadCount = $messageModel->getUnreadCount($userId);
        
        // 计算总未读数量（通知 + 私信）
        $totalUnreadCount = $notificationUnreadCount + $messageUnreadCount;

        // 调试信息
        error_log('notifications count: ' . count($notifications));
        error_log('unread count: ' . $totalUnreadCount);

        $formattedNotifications = [];
        foreach ($notifications as $notification) {
            $formattedNotifications[] = $this->formatNotification($notification);
        }

        $this->success([
            'items' => $formattedNotifications,
            'unread_count' => $totalUnreadCount,
            'notification_unread' => $notificationUnreadCount,
            'message_unread' => $messageUnreadCount,
            'mention_count' => $mentionCount,
            'like_count' => $likeCount,
            'comment_count' => $commentCount,
            'pagination' => [
                'page' => $page,
                'page_size' => $pageSize,
                'has_more' => count($formattedNotifications) >= $pageSize
            ]
        ]);
    }

    public function markRead()
    {
        $userId = $this->requireLogin();

        $id = (int)$this->input('id');
        if (!$id) {
            $this->error('参数错误');
        }

        $result = $this->notificationModel->markAsRead($id, $userId);

        if ($result) {
            $unreadCount = $this->notificationModel->getUnreadCount($userId);
            $this->success(['unread_count' => $unreadCount]);
        } else {
            $this->error('操作失败');
        }
    }

    public function markAllRead()
    {
        $userId = $this->requireLogin();

        $result = $this->notificationModel->markAllAsRead($userId);

        if ($result !== false) {
            $this->success(null, '全部已读');
        } else {
            $this->error('操作失败');
        }
    }

    public function deleteNotification()
    {
        $userId = $this->requireLogin();

        $id = (int)$this->input('id');
        if (!$id) {
            $this->error('参数错误');
        }

        $result = $this->notificationModel->delete($id, $userId);

        if ($result) {
            $this->success(null, '删除成功');
        } else {
            $this->error('删除失败');
        }
    }

    public function markNotificationRead()
    {
        $userId = $this->requireLogin();

        $id = (int)$this->input('id');
        if (!$id) {
            $this->error('参数错误');
        }

        $result = $this->notificationModel->markAsRead($id, $userId);

        if ($result) {
            $unreadCount = $this->notificationModel->getUnreadCount($userId);
            $this->success(['unread_count' => $unreadCount]);
        } else {
            $this->error('操作失败');
        }
    }

    public function markAllNotificationsRead()
    {
        $userId = $this->requireLogin();

        $result = $this->notificationModel->markAllAsRead($userId);

        if ($result !== false) {
            $this->success(null, '全部已读');
        } else {
            $this->error('操作失败');
        }
    }

    public function userProfile()
    {
        $userId = isset($_SESSION['user_id']) ? $_SESSION['user_id'] : null;
        
        if (!$userId && !Setting::isGuestAccessAllowed()) {
            $this->error('请先登录', 401);
        }

        $username = $this->input('username');
        $targetId = (int)$this->input('id');

        if ($username) {
            $targetUser = $this->userModel->findByUsername($username);
        } elseif ($targetId) {
            $targetUser = $this->userModel->find($targetId);
        } else {
            $this->error('参数错误');
        }

        if (!$targetUser) {
            $this->error('用户不存在');
        }

        $postCount = $this->postModel->count('user_id = ? AND status = 1', [$targetUser['id']]);
        $followCount = $this->userModel->getFollowCount($targetUser['id']);

        $isFollowing = false;
        if ($userId) {
            $isFollowing = $this->userModel->isFollowing($userId, $targetUser['id']);
        }

        $this->success([
            'user' => $this->formatUser($targetUser, $userId),
            'stats' => [
                'post_count' => $postCount,
                'following' => $followCount['following'] ?? 0,
                'followers' => $followCount['followers'] ?? 0
            ],
            'is_following' => $isFollowing
        ]);
    }

    /**
     * 更新用户资料
     */
    public function updateProfile()
    {
        $userId = $this->requireLogin();
        
        $username = isset($_POST['username']) ? trim($_POST['username']) : '';
        $bio = isset($_POST['bio']) ? trim($_POST['bio']) : '';
        
        // 验证用户名
        if (empty($username)) {
            $this->error('用户名不能为空');
        }
        
        if (strlen($username) < 2 || strlen($username) > 20) {
            $this->error('用户名长度需在2-20个字符之间');
        }
        
        if (!preg_match('/^[a-zA-Z0-9_\x{4e00}-\x{9fa5}]+$/u', $username)) {
            $this->error('用户名只能包含字母、数字、下划线和中文');
        }
        
        // 检查用户名是否被占用
        $existingUser = $this->userModel->findByUsername($username);
        if ($existingUser && $existingUser['id'] != $userId) {
            $this->error('用户名已被使用');
        }
        
        // 检查禁用用户名
        $bannedUsernames = Setting::getBannedUsernames();
        if (!empty($bannedUsernames)) {
            $usernameLower = strtolower($username);
            foreach ($bannedUsernames as $banned) {
                if (strpos($usernameLower, strtolower($banned)) !== false) {
                    $this->error('用户名包含禁用字符');
                }
            }
        }
        
        // 验证简介长度
        if (strlen($bio) > 200) {
            $this->error('个人简介不能超过200个字符');
        }
        
        $data = [
            'username' => $username,
            'bio' => $bio
        ];
        
        // 处理头像上传
        if (isset($_FILES['avatar']) && !empty($_FILES['avatar']['tmp_name'])) {
            $avatarResult = $this->uploadAvatar($userId);
            if (!$avatarResult['success']) {
                $this->error('头像上传失败：' . $avatarResult['error']);
            }
            $data['avatar'] = $avatarResult['path'];
        }
        
        // 处理背景图片上传
        if (isset($_FILES['background']) && !empty($_FILES['background']['tmp_name'])) {
            $backgroundResult = $this->uploadBackground($userId);
            if (!$backgroundResult['success']) {
                $this->error('背景图片上传失败：' . $backgroundResult['error']);
            }
            $data['background'] = $backgroundResult['path'];
        }
        
        // 更新资料
        $result = $this->userModel->updateProfile($userId, $data);
        
        if ($result) {
            // 更新会话中的用户名
            if (isset($data['username'])) {
                $_SESSION['username'] = $data['username'];
            }
            
            // 获取更新后的用户信息
            $updatedUser = $this->userModel->find($userId);
            
            $this->success([
                'user' => $this->formatUser($updatedUser, $userId)
            ], '资料更新成功');
        } else {
            $this->error('资料更新失败');
        }
    }
    
    /**
     * 获取文件MIME类型（兼容没有fileinfo扩展的环境）
     */
    private function getFileMimeType($filePath)
    {
        // 优先使用finfo（如果可用）
        if (function_exists('finfo_open')) {
            $finfo = finfo_open(FILEINFO_MIME_TYPE);
            if ($finfo) {
                $mimeType = finfo_file($finfo, $filePath);
                finfo_close($finfo);
                return $mimeType;
            }
        }
        
        // 备选方案：使用getimagesize检测图片类型
        $imageInfo = getimagesize($filePath);
        if ($imageInfo && isset($imageInfo['mime'])) {
            return $imageInfo['mime'];
        }
        
        // 最后备选：使用路径扩展名推断类型
        $extension = strtolower(pathinfo($filePath, PATHINFO_EXTENSION));
        $mimeTypes = [
            'jpg' => 'image/jpeg',
            'jpeg' => 'image/jpeg',
            'png' => 'image/png',
            'gif' => 'image/gif',
            'webp' => 'image/webp'
        ];
        
        return isset($mimeTypes[$extension]) ? $mimeTypes[$extension] : 'application/octet-stream';
    }
    
    /**
     * 上传头像
     */
    private function uploadAvatar($userId)
    {
        if (!isset($_FILES['avatar']) || empty($_FILES['avatar']['tmp_name'])) {
            return ['success' => false, 'error' => '未选择图片'];
        }
        
        $file = $_FILES['avatar'];
        
        // 检查文件上传错误
        if ($file['error'] !== UPLOAD_ERR_OK) {
            $errorMessages = [
                UPLOAD_ERR_INI_SIZE => '文件超过了upload_max_filesize限制',
                UPLOAD_ERR_FORM_SIZE => '文件超过了表单限制',
                UPLOAD_ERR_PARTIAL => '文件只上传了部分',
                UPLOAD_ERR_NO_FILE => '没有上传文件',
                UPLOAD_ERR_NO_TMP_DIR => '缺少临时目录',
                UPLOAD_ERR_CANT_WRITE => '无法写入文件',
                UPLOAD_ERR_EXTENSION => '文件上传被扩展阻止'
            ];
            return ['success' => false, 'error' => $errorMessages[$file['error']] ?? '文件上传失败'];
        }
        
        // 验证文件类型
        $allowedTypes = ['image/jpeg', 'image/png', 'image/gif', 'image/webp'];
        $mimeType = $this->getFileMimeType($file['tmp_name']);
        
        if (!in_array($mimeType, $allowedTypes)) {
            return ['success' => false, 'error' => '只支持 JPG、PNG、GIF、WebP 格式'];
        }
        
        // 验证文件大小 (最大5MB)
        if ($file['size'] > 5 * 1024 * 1024) {
            return ['success' => false, 'error' => '图片大小不能超过5MB'];
        }
        
        // 创建上传目录
        $uploadDir = ROOT_PATH . '/uploads/avatar/';
        if (!is_dir($uploadDir)) {
            $oldUmask = umask(0);
            $created = mkdir($uploadDir, 0755, true);
            umask($oldUmask);
            if (!$created) {
                return ['success' => false, 'error' => '无法创建上传目录'];
            }
        }
        
        // 检查目录权限
        if (!is_writable($uploadDir)) {
            return ['success' => false, 'error' => '上传目录没有写入权限'];
        }
        
        // 生成文件名
        $extension = pathinfo($file['name'], PATHINFO_EXTENSION);
        $newFilename = $userId . '_' . time() . '.' . $extension;
        $uploadPath = $uploadDir . $newFilename;
        
        // 移动文件
        if (move_uploaded_file($file['tmp_name'], $uploadPath)) {
            // 返回相对路径
            $avatarPath = '/uploads/avatar/' . $newFilename;
            return ['success' => true, 'path' => $avatarPath];
        }
        
        return ['success' => false, 'error' => '文件上传失败: ' . error_get_last()['message'] ?? '未知错误'];
    }
    
    /**
     * 上传背景图片
     */
    private function uploadBackground($userId)
    {
        if (!isset($_FILES['background']) || empty($_FILES['background']['tmp_name'])) {
            return ['success' => false, 'error' => '未选择图片'];
        }
        
        $file = $_FILES['background'];
        
        // 检查文件上传错误
        if ($file['error'] !== UPLOAD_ERR_OK) {
            $errorMessages = [
                UPLOAD_ERR_INI_SIZE => '文件超过了upload_max_filesize限制',
                UPLOAD_ERR_FORM_SIZE => '文件超过了表单限制',
                UPLOAD_ERR_PARTIAL => '文件只上传了部分',
                UPLOAD_ERR_NO_FILE => '没有上传文件',
                UPLOAD_ERR_NO_TMP_DIR => '缺少临时目录',
                UPLOAD_ERR_CANT_WRITE => '无法写入文件',
                UPLOAD_ERR_EXTENSION => '文件上传被扩展阻止'
            ];
            return ['success' => false, 'error' => $errorMessages[$file['error']] ?? '文件上传失败'];
        }
        
        // 验证文件类型
        $allowedTypes = ['image/jpeg', 'image/png', 'image/gif', 'image/webp'];
        $mimeType = $this->getFileMimeType($file['tmp_name']);
        
        if (!in_array($mimeType, $allowedTypes)) {
            return ['success' => false, 'error' => '只支持 JPG、PNG、GIF、WebP 格式'];
        }
        
        // 验证文件大小 (最大5MB)
        if ($file['size'] > 5 * 1024 * 1024) {
            return ['success' => false, 'error' => '图片大小不能超过5MB'];
        }
        
        // 删除旧的背景图片
        $userModel = new UserModel();
        $oldUser = $userModel->find($userId);
        if (!empty($oldUser['background'])) {
            $oldFilePath = rtrim(ROOT_PATH, '/') . $oldUser['background'];
            if (file_exists($oldFilePath)) {
                @unlink($oldFilePath);
            }
        }
        
        // 创建上传目录
        $uploadDir = ROOT_PATH . '/uploads/background/';
        if (!is_dir($uploadDir)) {
            $oldUmask = umask(0);
            $created = mkdir($uploadDir, 0755, true);
            umask($oldUmask);
            if (!$created) {
                return ['success' => false, 'error' => '无法创建上传目录'];
            }
        }
        
        // 检查目录权限
        if (!is_writable($uploadDir)) {
            return ['success' => false, 'error' => '上传目录没有写入权限'];
        }
        
        // 生成文件名
        $extension = pathinfo($file['name'], PATHINFO_EXTENSION);
        $newFilename = $userId . '_' . time() . '.' . $extension;
        $uploadPath = $uploadDir . $newFilename;
        
        // 移动文件
        if (move_uploaded_file($file['tmp_name'], $uploadPath)) {
            // 返回相对路径
            $backgroundPath = '/uploads/background/' . $newFilename;
            return ['success' => true, 'path' => $backgroundPath];
        }
        
        return ['success' => false, 'error' => '文件上传失败: ' . error_get_last()['message'] ?? '未知错误'];
    }

    public function userPosts()
    {
        $userId = isset($_SESSION['user_id']) ? $_SESSION['user_id'] : null;
        
        if (!$userId && !Setting::isGuestAccessAllowed()) {
            $this->error('请先登录', 401);
        }

        $targetUserId = (int)$this->input('user_id');
        $page = (int)$this->input('page', 1);
        $pageSize = 15;

        if (!$targetUserId) {
            $this->error('参数错误');
        }

        $postsData = $this->postModel->getUserPosts($targetUserId, $page, $pageSize);
        $posts = $postsData['items'] ?? [];

        $formattedPosts = [];
        foreach ($posts as $post) {
            $formattedPosts[] = $this->formatPost($post, $userId);
        }

        $this->success([
            'items' => $formattedPosts,
            'pagination' => [
                'page' => $page,
                'page_size' => $pageSize,
                'has_more' => count($formattedPosts) >= $pageSize
            ]
        ]);
    }

    /**
     * 获取用户的评论列表
     */
    public function userComments()
    {
        $userId = isset($_SESSION['user_id']) ? $_SESSION['user_id'] : null;
        
        if (!$userId && !Setting::isGuestAccessAllowed()) {
            $this->error('请先登录', 401);
        }

        $targetUserId = (int)$this->input('user_id');
        $page = (int)$this->input('page', 1);
        $pageSize = 15;

        if (!$targetUserId) {
            $this->error('参数错误');
        }

        $db = Database::getInstance();
        $offset = ($page - 1) * $pageSize;
        
        // 获取用户的评论列表
        $sql = "SELECT c.*, p.content as post_content, p.id as post_id, p.user_id as post_user_id,
                       cu.username, cu.avatar, cu.last_activity,
                       pu.username as post_username, pu.avatar as post_avatar
                FROM __PREFIX__comments c
                LEFT JOIN __PREFIX__posts p ON c.post_id = p.id
                LEFT JOIN __PREFIX__users cu ON c.user_id = cu.id
                LEFT JOIN __PREFIX__users pu ON p.user_id = pu.id
                WHERE c.user_id = ? AND c.status = 1
                ORDER BY c.created_at DESC
                LIMIT {$offset}, {$pageSize}";
        
        $comments = $db->fetchAll($sql, [$targetUserId]);
        
        $formattedComments = [];
        foreach ($comments as $comment) {
            $comment['id'] = $comment['id'];
            $comment['content'] = Security::escape($comment['content']);
            $comment['post_content'] = $comment['post_content'] ? mb_substr(strip_tags($comment['post_content']), 0, 50) . '...' : '';
            $comment['time_ago'] = Helper::formatTime($comment['created_at']);
            $comment['username'] = $comment['username'] ?? '未知用户';
            $comment['avatar'] = $comment['avatar'] ? Helper::getFileUrl($comment['avatar']) : '';
            $comment['post_username'] = $comment['post_username'] ?? '未知用户';
            $comment['post_avatar'] = $comment['post_avatar'] ? Helper::getFileUrl($comment['post_avatar']) : '';
            
            // 计算用户是否在线
            $comment['is_online'] = false;
            if (!empty($comment['last_activity'])) {
                $comment['is_online'] = (time() - $comment['last_activity']) < 300;
            }
            
            $formattedComments[] = $comment;
        }

        $this->success([
            'items' => $formattedComments,
            'pagination' => [
                'page' => $page,
                'page_size' => $pageSize,
                'has_more' => count($formattedComments) >= $pageSize
            ]
        ]);
    }

    /**
     * 获取用户的收藏列表
     */
    public function userFavorites()
    {
        $userId = isset($_SESSION['user_id']) ? $_SESSION['user_id'] : null;
        
        if (!$userId && !Setting::isGuestAccessAllowed()) {
            $this->error('请先登录', 401);
        }

        $targetUserId = (int)$this->input('user_id');
        $page = (int)$this->input('page', 1);
        $pageSize = 15;

        if (!$targetUserId) {
            $this->error('参数错误');
        }

        $favoritesData = $this->favoriteModel->getUserFavorites($targetUserId, $page, $pageSize);
        $posts = $favoritesData['items'] ?? [];

        $formattedPosts = [];
        foreach ($posts as $post) {
            $post['is_favorited'] = true;
            $formattedPosts[] = $this->formatPost($post, $userId);
        }

        $this->success([
            'items' => $formattedPosts,
            'pagination' => [
                'page' => $favoritesData['page'] ?? $page,
                'page_size' => $favoritesData['page_size'] ?? $pageSize,
                'has_more' => $favoritesData['has_more'] ?? false
            ]
        ]);
    }

    public function follow()
    {
        $userId = $this->requireLogin();

        $targetId = (int)$this->input('user_id');
        if (!$targetId) {
            $this->error('参数错误');
        }

        if ($targetId == $userId) {
            $this->error('不能关注自己');
        }

        $targetUser = $this->userModel->find($targetId);
        if (!$targetUser) {
            $this->error('用户不存在');
        }

        $result = $this->userModel->follow($userId, $targetId);

        if ($result) {
            // 发送关注通知
            $currentUser = $this->userModel->find($userId);
            $this->notificationModel->sendFollowNotification($targetId, $userId, $currentUser['username']);
            
            $this->success(['is_following' => 1], '关注成功');
        } else {
            // 取消关注
            $this->userModel->unfollow($userId, $targetId);
            $this->success(['is_following' => 0], '已取消关注');
        }
    }

    public function unfollow()
    {
        $userId = $this->requireLogin();

        $targetId = (int)$this->input('user_id');
        if (!$targetId) {
            $this->error('参数错误');
        }

        $result = $this->userModel->unfollow($userId, $targetId);

        if ($result) {
            $this->success(null, '取消关注成功');
        } else {
            $this->error('取消关注失败');
        }
    }

    /**
     * 获取当前用户的关注列表
     */
    public function following()
    {
        $userId = $this->requireLogin();

        $page = (int)$this->input('page', 1);
        $pageSize = 20;
        $offset = ($page - 1) * $pageSize;

        $db = Database::getInstance();
        
        // 获取关注列表 (follows表中的follow_id是被关注者的ID)
        $sql = "SELECT u.*, f.created_at as follow_time 
                FROM __PREFIX__follows f 
                INNER JOIN __PREFIX__users u ON f.follow_id = u.id 
                WHERE f.user_id = ? 
                ORDER BY f.created_at DESC 
                LIMIT {$offset}, {$pageSize}";
        
        $users = $db->fetchAll($sql, [$userId]);
        
        $formattedUsers = [];
        foreach ($users as $user) {
            $formattedUsers[] = $this->formatUser($user, $userId);
        }

        $this->success([
            'items' => $formattedUsers,
            'pagination' => [
                'page' => $page,
                'page_size' => $pageSize,
                'has_more' => count($formattedUsers) >= $pageSize
            ]
        ]);
    }

    /**
     * 获取当前用户的粉丝列表
     */
    public function followers()
    {
        $userId = $this->requireLogin();

        $page = (int)$this->input('page', 1);
        $pageSize = 20;
        $offset = ($page - 1) * $pageSize;

        $db = Database::getInstance();
        
        // 获取粉丝列表 (follows表中user_id是粉丝, follow_id是被关注者)
        $sql = "SELECT u.*, f.created_at as follow_time 
                FROM __PREFIX__follows f 
                INNER JOIN __PREFIX__users u ON f.user_id = u.id 
                WHERE f.follow_id = ? 
                ORDER BY f.created_at DESC 
                LIMIT {$offset}, {$pageSize}";
        
        $users = $db->fetchAll($sql, [$userId]);
        
        $formattedUsers = [];
        foreach ($users as $user) {
            $formattedUsers[] = $this->formatUser($user, $userId);
        }

        $this->success([
            'items' => $formattedUsers,
            'pagination' => [
                'page' => $page,
                'page_size' => $pageSize,
                'has_more' => count($formattedUsers) >= $pageSize
            ]
        ]);
    }

    /**
     * 获取好友列表（关注的人）- 用于@用户功能
     */
    public function getFriends()
    {
        $userId = $this->requireLogin();
        
        // 获取用户关注的人作为好友列表
        $page = (int)$this->input('page', 1);
        $pageSize = 50;
        $offset = ($page - 1) * $pageSize;

        $db = Database::getInstance();
        
        // 获取关注列表
        $sql = "SELECT u.*, f.created_at as follow_time 
                FROM __PREFIX__follows f 
                INNER JOIN __PREFIX__users u ON f.follow_id = u.id 
                WHERE f.user_id = ? 
                ORDER BY f.created_at DESC 
                LIMIT {$offset}, {$pageSize}";
        
        $friends = $db->fetchAll($sql, [$userId]);
        
        $formattedFriends = [];
        foreach ($friends as $friend) {
            $formattedFriends[] = $this->formatUser($friend, $userId);
        }
        
        $this->success(['items' => $formattedFriends]);
    }

    public function uploadImage()
    {
        $userId = $this->requireLogin();

        if (empty($_FILES['image'])) {
            $this->error('没有上传文件');
        }

        $file = $_FILES['image'];

        if ($file['error'] !== UPLOAD_ERR_OK) {
            $errorMsg = '上传失败';
            switch ($file['error']) {
                case UPLOAD_ERR_INI_SIZE:
                case UPLOAD_ERR_FORM_SIZE:
                    $errorMsg = '文件大小超过限制';
                    break;
                case UPLOAD_ERR_PARTIAL:
                    $errorMsg = '文件上传不完整';
                    break;
            }
            $this->error($errorMsg);
        }

        $allowedExts = ['jpg', 'jpeg', 'png', 'gif', 'webp'];
        $ext = strtolower(pathinfo($file['name'], PATHINFO_EXTENSION));
        
        if (!in_array($ext, $allowedExts)) {
            $this->error('只允许上传图片文件');
        }

        if (function_exists('finfo_open')) {
            $finfo = finfo_open(FILEINFO_MIME_TYPE);
            $mimeType = finfo_file($finfo, $file['tmp_name']);
            finfo_close($finfo);

            $allowedTypes = ['image/jpeg', 'image/png', 'image/gif', 'image/webp'];
            if (!in_array($mimeType, $allowedTypes)) {
                $this->error('文件类型不正确');
            }
        }

        $maxSize = Setting::getMaxImageSize() * 1024 * 1024;
        if ($file['size'] > $maxSize) {
            $this->error('文件大小超过' . Setting::getMaxImageSize() . 'MB限制');
        }

        $filename = 'images/' . date('Ymd') . '/' . uniqid() . '.' . $ext;
        $filepath = UPLOAD_PATH . $filename;

        $dir = dirname($filepath);
        if (!is_dir($dir)) {
            mkdir($dir, 0755, true);
        }

        if (move_uploaded_file($file['tmp_name'], $filepath)) {
            chmod($filepath, 0644);
            $this->success([
                'path' => $filename,
                'url' => Helper::uploadUrl($filename)
            ], '上传成功');
        } else {
            $this->error('文件保存失败');
        }
    }
    
    /**
     * 上传聊天图片
     */
    public function uploadChatImage()
    {
        $userId = $this->requireLogin();

        if (empty($_FILES['image'])) {
            $this->error('没有上传文件');
        }

        $file = $_FILES['image'];

        if ($file['error'] !== UPLOAD_ERR_OK) {
            $errorMsg = '上传失败';
            switch ($file['error']) {
                case UPLOAD_ERR_INI_SIZE:
                case UPLOAD_ERR_FORM_SIZE:
                    $errorMsg = '文件大小超过限制';
                    break;
                case UPLOAD_ERR_PARTIAL:
                    $errorMsg = '文件上传不完整';
                    break;
            }
            $this->error($errorMsg);
        }

        $allowedExts = ['jpg', 'jpeg', 'png', 'gif', 'webp'];
        $ext = strtolower(pathinfo($file['name'], PATHINFO_EXTENSION));
        
        if (!in_array($ext, $allowedExts)) {
            $this->error('只允许上传图片文件');
        }

        if (function_exists('finfo_open')) {
            $finfo = finfo_open(FILEINFO_MIME_TYPE);
            $mimeType = finfo_file($finfo, $file['tmp_name']);
            finfo_close($finfo);

            $allowedTypes = ['image/jpeg', 'image/png', 'image/gif', 'image/webp'];
            if (!in_array($mimeType, $allowedTypes)) {
                $this->error('文件类型不正确');
            }
        }

        // 聊天图片限制为5MB
        $maxSize = 5 * 1024 * 1024;
        if ($file['size'] > $maxSize) {
            $this->error('文件大小超过5MB限制');
        }

        $filename = 'chat/' . date('Ymd') . '/' . uniqid() . '.' . $ext;
        $filepath = UPLOAD_PATH . $filename;

        $dir = dirname($filepath);
        if (!is_dir($dir)) {
            mkdir($dir, 0755, true);
        }

        if (move_uploaded_file($file['tmp_name'], $filepath)) {
            chmod($filepath, 0644);
            $this->success([
                'path' => $filename,
                'url' => Helper::uploadUrl($filename)
            ], '上传成功');
        } else {
            $this->error('文件保存失败');
        }
    }
    
    /**
     * 上传聊天视频
     */
    public function uploadChatVideo()
    {
        $userId = $this->requireLogin();

        if (empty($_FILES['video'])) {
            $this->error('没有上传文件');
        }

        $file = $_FILES['video'];

        if ($file['error'] !== UPLOAD_ERR_OK) {
            $errorMsg = '上传失败';
            switch ($file['error']) {
                case UPLOAD_ERR_INI_SIZE:
                case UPLOAD_ERR_FORM_SIZE:
                    $errorMsg = '文件大小超过限制';
                    break;
                case UPLOAD_ERR_PARTIAL:
                    $errorMsg = '文件上传不完整';
                    break;
            }
            $this->error($errorMsg);
        }

        $allowedExts = ['mp4', 'mov', 'avi', 'mkv', 'webm'];
        $ext = strtolower(pathinfo($file['name'], PATHINFO_EXTENSION));
        
        if (!in_array($ext, $allowedExts)) {
            $this->error('只允许上传视频文件（mp4, mov, avi, mkv, webm）');
        }

        // 视频限制为50MB
        $maxSize = 50 * 1024 * 1024;
        if ($file['size'] > $maxSize) {
            $this->error('文件大小超过50MB限制');
        }

        $filename = 'chat/video/' . date('Ymd') . '/' . uniqid() . '.' . $ext;
        $filepath = UPLOAD_PATH . $filename;

        $dir = dirname($filepath);
        if (!is_dir($dir)) {
            mkdir($dir, 0755, true);
        }

        if (move_uploaded_file($file['tmp_name'], $filepath)) {
            chmod($filepath, 0644);
            
            // 生成缩略图
            $thumbnailPath = $this->generateVideoThumbnail($filepath, $filename);
            
            $this->success([
                'path' => $filename,
                'url' => Helper::uploadUrl($filename),
                'thumbnail' => $thumbnailPath ? Helper::uploadUrl($thumbnailPath) : null
            ], '上传成功');
        } else {
            $this->error('文件保存失败');
        }
    }
    
    /**
     * 生成视频缩略图
     */
    private function generateVideoThumbnail($videoPath, $videoFilename)
    {
        // 检查是否安装了FFmpeg
        $ffmpegPath = 'ffmpeg';
        
        // 尝试查找ffmpeg路径
        if (strtoupper(substr(PHP_OS, 0, 3)) === 'WIN') {
            $possiblePaths = [
                'C:/ffmpeg/bin/ffmpeg.exe',
                'D:/ffmpeg/bin/ffmpeg.exe',
                'ffmpeg.exe'
            ];
            foreach ($possiblePaths as $path) {
                if (file_exists($path)) {
                    $ffmpegPath = $path;
                    break;
                }
            }
        }
        
        // 提取目录和文件名
        $dir = dirname($videoFilename);
        $name = pathinfo($videoFilename, PATHINFO_FILENAME);
        $thumbnailFilename = $dir . '/' . $name . '_thumb.jpg';
        $thumbnailPath = UPLOAD_PATH . $thumbnailFilename;
        
        // 使用ffmpeg生成缩略图
        $command = escapeshellarg($ffmpegPath) . ' -i ' . escapeshellarg($videoPath) . ' -ss 00:00:01 -vframes 1 -q:v 2 ' . escapeshellarg($thumbnailPath);
        
        // 执行命令
        exec($command, $output, $returnCode);
        
        if ($returnCode === 0 && file_exists($thumbnailPath)) {
            return $thumbnailFilename;
        }
        
        return null;
    }

    public function searchUsers()
    {
        $userId = isset($_SESSION['user_id']) ? $_SESSION['user_id'] : null;
        
        $keyword = trim($this->input('keyword'));
        if (empty($keyword)) {
            $this->success(['items' => []]);
        }

        $users = $this->userModel->searchUsers($keyword, 10);
        
        $formattedUsers = [];
        foreach ($users as $user) {
            $formattedUsers[] = $this->formatUser($user, $userId);
        }

        $this->success(['items' => $formattedUsers]);
    }

    public function hotTopics()
    {
        $topics = $this->postModel->getHotTopics(10);
        $this->success(['items' => $topics]);
    }

    public function siteConfig()
    {
        $config = [
            'site_name' => Setting::getSiteName(),
            'subtitle' => Setting::getSubtitle(),
            'max_post_length' => Setting::getMaxPostLength(),
            'max_comment_length' => Setting::getMaxCommentLength(),
            'registration_open' => Setting::isRegistrationOpen(),
            'email_verify_enabled' => Setting::isRegistrationEmailVerifyEnabled(),
            'require_invite_code' => (int)Setting::get('require_invite_code', 0) === 1,
            'guest_access' => Setting::isGuestAccessAllowed()
        ];

        $this->success($config);
    }

    public function sendEmailCode()
    {
        if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
            $this->error('请求方法错误');
        }

        $email = trim($this->input('email'));
        if (empty($email)) {
            $this->error('请输入邮箱地址');
        }

        if (!Security::validateEmail($email)) {
            $this->error('邮箱格式不正确');
        }

        $allowedSuffixes = Setting::getAllowedEmailSuffixes();
        if (!empty($allowedSuffixes)) {
            $emailSuffix = substr($email, strrpos($email, '@') + 1);
            if (!in_array($emailSuffix, $allowedSuffixes)) {
                $this->error('只允许使用以下邮箱后缀：' . implode(', ', $allowedSuffixes));
            }
        }

        $code = rand(100000, 999999);
        
        $mailer = new Mailer();
        $result = $mailer->sendTemplate($email, '注册验证码', 'register_code', [
            'code' => $code,
            'site_name' => Setting::getSiteName()
        ]);

        if ($result) {
            $db = Database::getInstance();
            $db->insert('email_codes', [
                'email' => $email,
                'code' => $code,
                'type' => '注册',
                'created_at' => time(),
                'expires_at' => time() + 600
            ]);
            $this->success(null, '验证码已发送');
        } else {
            $this->error('验证码发送失败');
        }
    }

    private function uploadImages()
    {
        $images = [];
        $files = $_FILES['images'];
        $count = count($files['name']);
        $maxSize = Setting::getMaxImageSize() * 1024 * 1024;

        for ($i = 0; $i < $count && $i < 9; $i++) {
            if ($files['error'][$i] !== UPLOAD_ERR_OK) {
                continue;
            }

            if ($files['size'][$i] > $maxSize) {
                continue;
            }

            $file = [
                'name' => $files['name'][$i],
                'type' => $files['type'][$i],
                'tmp_name' => $files['tmp_name'][$i],
                'error' => $files['error'][$i],
                'size' => $files['size'][$i]
            ];

            $ext = strtolower(pathinfo($file['name'], PATHINFO_EXTENSION));
            if (empty($ext) || !in_array($ext, ['jpg', 'jpeg', 'png', 'gif', 'webp'])) {
                if (function_exists('finfo_open')) {
                    $finfo = finfo_open(FILEINFO_MIME_TYPE);
                    $mimeType = finfo_file($finfo, $file['tmp_name']);
                    finfo_close($finfo);
                    
                    $mimeToExt = [
                        'image/jpeg' => 'jpg',
                        'image/png' => 'png',
                        'image/gif' => 'gif',
                        'image/webp' => 'webp'
                    ];
                    
                    if (isset($mimeToExt[$mimeType])) {
                        $ext = $mimeToExt[$mimeType];
                        $file['name'] = 'paste_' . time() . '.' . $ext;
                    } else {
                        continue;
                    }
                } else {
                    continue;
                }
            }

            $filename = 'images/' . date('Ymd') . '/' . uniqid() . '.' . $ext;
            $savePath = UPLOAD_PATH . $filename;

            $dir = dirname($savePath);
            if (!is_dir($dir)) {
                mkdir($dir, 0755, true);
            }

            if (move_uploaded_file($file['tmp_name'], $savePath)) {
                chmod($savePath, 0644);
                $images[] = $filename;
            }
        }

        return $images;
    }

    private function uploadVideo()
    {
        $file = $_FILES['video'];
        
        if ($file['error'] !== UPLOAD_ERR_OK) {
            return '';
        }

        // 限制视频大小为100MB
        $maxSize = 100 * 1024 * 1024;
        if ($file['size'] > $maxSize) {
            return '';
        }

        $ext = strtolower(pathinfo($file['name'], PATHINFO_EXTENSION));
        
        // 如果没有扩展名或扩展名不在允许列表中，尝试通过MIME类型检测
        if (empty($ext) || !in_array($ext, ['mp4', 'mov', 'avi', 'wmv', 'flv', 'webm'])) {
            if (function_exists('finfo_open')) {
                $finfo = finfo_open(FILEINFO_MIME_TYPE);
                $mimeType = finfo_file($finfo, $file['tmp_name']);
                finfo_close($finfo);
                
                $mimeToExt = [
                    'video/mp4' => 'mp4',
                    'video/quicktime' => 'mov',
                    'video/x-msvideo' => 'avi',
                    'video/x-ms-wmv' => 'wmv',
                    'video/x-flv' => 'flv',
                    'video/webm' => 'webm'
                ];
                
                if (isset($mimeToExt[$mimeType])) {
                    $ext = $mimeToExt[$mimeType];
                } else {
                    return '';
                }
            } else {
                return '';
            }
        }

        $filename = 'videos/' . date('Ymd') . '/' . uniqid() . '.' . $ext;
        $savePath = UPLOAD_PATH . $filename;

        $dir = dirname($savePath);
        if (!is_dir($dir)) {
            mkdir($dir, 0755, true);
        }

        if (move_uploaded_file($file['tmp_name'], $savePath)) {
            chmod($savePath, 0644);
            // 返回与PC端兼容的视频对象格式
            return [
                'path' => $filename,
                'ext' => $ext,
                'name' => $file['name'],
                'size' => $file['size']
            ];
        }

        return '';
    }

    private function sendMentionNotifications($content, $postId, $senderId, $commentId = null)
    {
        $usernames = Helper::extractMentions($content);
        if (empty($usernames)) {
            return;
        }

        $sender = $this->userModel->find($senderId);
        if (!$sender) {
            return;
        }

        $senderName = $sender['username'];

        foreach ($usernames as $username) {
            try {
                $mentionedUser = $this->userModel->findByUsername($username);
                if ($mentionedUser && $mentionedUser['id'] != $senderId) {
                    $this->notificationModel->sendMentionNotification(
                        $mentionedUser['id'],
                        $senderId,
                        $postId,
                        $senderName,
                        $commentId
                    );
                }
            } catch (Exception $e) {}
        }
    }

    private function sendLikeNotification($postUserId, $postId)
    {
        try {
            $sender = $this->userModel->find($_SESSION['user_id']);
            if (!$sender) {
                return;
            }

            $this->notificationModel->sendLikeNotification(
                $postUserId, 
                $_SESSION['user_id'], 
                $postId, 
                $sender['username']
            );
        } catch (\Exception $e) {}
    }

    private function sendFavoriteNotification($postUserId, $postId)
    {
        try {
            $sender = $this->userModel->find($_SESSION['user_id']);
            if (!$sender) {
                return;
            }

            $this->notificationModel->sendFavoriteNotification(
                $postUserId, 
                $_SESSION['user_id'], 
                $postId, 
                $sender['username']
            );
        } catch (\Exception $e) {}
    }

    public function sendMessage()
    {
        if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
            $this->error('请求方法错误');
        }

        $userId = $this->requireLogin();
        $receiverId = (int)$this->input('user_id');
        $content = trim($this->input('content', ''));

        if (!$receiverId) {
            $this->error('请选择接收者');
        }

        if ($receiverId == $userId) {
            $this->error('不能给自己发私信');
        }

        if (empty($content)) {
            $this->error('请输入私信内容');
        }

        if (mb_strlen($content) > 1000) {
            $this->error('私信内容不能超过1000字符');
        }

        try {
            require_once ROOT_PATH . 'templates/mobile/MessageModel.php';
            $messageModel = new MessageModel();
            $result = $messageModel->send($userId, $receiverId, $content);
            if ($result) {
                $this->success(null, '发送成功');
            } else {
                $this->error('发送失败');
            }
        } catch (\Exception $e) {
            $this->error('发送失败：' . $e->getMessage());
        }
    }

    /**
     * 获取对话列表
     */
    public function getConversations()
    {
        $userId = $this->requireLogin();
        $page = (int)$this->input('page', 1);
        $pageSize = 20;

        require_once ROOT_PATH . 'templates/mobile/MessageModel.php';
        $messageModel = new MessageModel();
        $conversations = $messageModel->getConversations($userId, $page, $pageSize);

        $this->success([
            'items' => $conversations,
            'pagination' => [
                'page' => $page,
                'page_size' => $pageSize,
                'has_more' => count($conversations) >= $pageSize
            ]
        ]);
    }

    /**
     * 获取消息列表
     */
    public function getMessages()
    {
        $userId = $this->requireLogin();
        $partnerId = (int)$this->input('user_id');
        $page = (int)$this->input('page', 1);
        $pageSize = 20;

        if (!$partnerId) {
            $this->error('参数错误');
        }

        require_once ROOT_PATH . 'templates/mobile/MessageModel.php';
        $messageModel = new MessageModel();
        $messages = $messageModel->getMessages($userId, $partnerId, $page, $pageSize);

        $this->success([
            'items' => $messages,
            'pagination' => [
                'page' => $page,
                'page_size' => $pageSize,
                'has_more' => count($messages) >= $pageSize
            ]
        ]);
    }

    /**
     * 获取未读消息数量
     */
    public function getMessageUnreadCount()
    {
        $userId = $this->requireLogin();

        require_once ROOT_PATH . 'templates/mobile/MessageModel.php';
        $messageModel = new MessageModel();
        $count = $messageModel->getUnreadCount($userId);

        $this->success(['unread_count' => $count]);
    }

    /**
     * 标记消息为已读
     */
    public function markMessagesRead()
    {
        $userId = $this->requireLogin();
        $partnerId = (int)$this->input('user_id');

        if (!$partnerId) {
            $this->error('参数错误');
        }

        require_once ROOT_PATH . 'templates/mobile/MessageModel.php';
        $messageModel = new MessageModel();
        $messageModel->markAsRead($userId, $partnerId);

        $this->success(null, '已读成功');
    }

    /**
     * 获取举报列表（管理员专用）
     */
    public function getReports()
    {
        // 检查是否为管理员
        if (empty($_SESSION['is_admin'])) {
            $this->error('没有权限', 403);
        }

        $page = (int)$this->input('page', 1);
        $pageSize = (int)$this->input('page_size', 20);
        $status = (int)$this->input('status', -1);

        require_once ROOT_PATH . 'content/report/ReportModel.php';
        $reportModel = new ReportModel();
        $result = $reportModel->getReports($page, $pageSize, $status);

        // 获取帖子详情
        foreach ($result['items'] as &$report) {
            if (!empty($report['post_id'])) {
                $post = $this->postModel->getPost($report['post_id']);
                if ($post) {
                    $report['post'] = [
                        'id' => $post['id'],
                        'content' => $post['content'],
                        'username' => $post['username']
                    ];
                }
            }
            $report['reporter_username'] = $report['reporter_name'];
        }

        $this->success([
            'items' => $result['items'],
            'pagination' => [
                'page' => $page,
                'page_size' => $pageSize,
                'has_more' => $page < $result['totalPages']
            ]
        ]);
    }

    /**
     * 处理举报（管理员专用）
     */
    public function handleReport()
    {
        if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
            $this->error('请求方法错误');
        }

        // 检查是否为管理员
        if (empty($_SESSION['is_admin'])) {
            $this->error('没有权限', 403);
        }

        $reportId = (int)$this->input('report_id');
        $status = (int)$this->input('status');
        $handleResult = $this->input('handle_result', '');

        if (!$reportId) {
            $this->error('举报ID不能为空');
        }

        if (!in_array($status, [1, 2])) {
            $this->error('无效的处理状态');
        }

        $handlerId = $_SESSION['user_id'];

        require_once ROOT_PATH . 'content/report/ReportModel.php';
        $reportModel = new ReportModel();
        $result = $reportModel->handleReport($reportId, $status, $handlerId, $handleResult);

        if ($result) {
            $this->success(null, $status == 1 ? '处理成功' : '驳回成功');
        } else {
            $this->error('操作失败');
        }
    }

    /**
     * 删除单条消息（双向删除）
     */
    public function deleteMessage()
    {
        if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
            $this->error('请求方法错误');
        }

        $userId = $this->requireLogin();
        $messageId = (int)$this->input('id');

        if (!$messageId) {
            $this->error('消息ID不能为空');
        }

        require_once ROOT_PATH . 'templates/mobile/MessageModel.php';
        $messageModel = new MessageModel();

        // 检查消息是否存在以及权限
        $message = $messageModel->findById($messageId);
        if (!$message) {
            $this->error('消息不存在或已被删除');
        }

        // 验证权限：只有发送者或接收者才能删除
        if ($message['sender_id'] != $userId && $message['receiver_id'] != $userId) {
            $this->error('无权删除此消息');
        }

        $result = $messageModel->deleteMessage($messageId, $userId);
        if ($result) {
            $this->success(null, '删除成功');
        } else {
            $this->error('删除失败');
        }
    }

    /**
     * 撤回消息（仅发送者可撤回，有2分钟时间限制）
     */
    public function recallMessage()
    {
        if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
            $this->error('请求方法错误');
        }

        $userId = $this->requireLogin();
        $messageId = (int)$this->input('id');
        $timeLimit = (int)$this->input('time_limit', 120); // 默认2分钟

        if (!$messageId) {
            $this->error('消息ID不能为空');
        }

        require_once ROOT_PATH . 'templates/mobile/MessageModel.php';
        $messageModel = new MessageModel();

        $result = $messageModel->recall($messageId, $userId, $timeLimit);
        if ($result['success']) {
            $this->success(null, $result['message']);
        } else {
            $this->error($result['message']);
        }
    }

    /**
     * 获取消息详情
     */
    public function getMessageDetail()
    {
        $userId = $this->requireLogin();
        $messageId = (int)$this->input('id');

        if (!$messageId) {
            $this->error('消息ID不能为空');
        }

        require_once ROOT_PATH . 'templates/mobile/MessageModel.php';
        $messageModel = new MessageModel();

        $message = $messageModel->getMessageDetail($messageId, $userId);
        if ($message) {
            $message['time_ago'] = Helper::formatTime($message['created_at']);
            $message['avatar'] = !empty($message['avatar']) ? Helper::uploadUrl($message['avatar']) : '';
            $message['is_me'] = $message['sender_id'] == $userId;
            $this->success(['item' => $message]);
        } else {
            $this->error('消息不存在或无权访问');
        }
    }

    /**
     * 获取推荐用户列表
     */
    public function getRecommendedUsers()
    {
        $userId = $this->requireLogin();
        $limit = (int)$this->input('limit', 10);

        $users = $this->userModel->getRecommendedUsers($userId, $limit);
        
        foreach ($users as &$user) {
            $user['avatar'] = $user['avatar'] ? Helper::uploadUrl($user['avatar']) : null;
            $user['is_following'] = $this->userModel->isFollowing($userId, $user['id']);
        }
        unset($user);

        $this->success(['items' => $users]);
    }

    /**
     * 获取热门话题列表
     */
    public function getHotTopics()
    {
        $limit = (int)$this->input('limit', 20);

        require_once ROOT_PATH . 'repository/PostRepository.php';
        $postRepository = new PostRepository();
        $topics = $postRepository->getHotTopics($limit);

        foreach ($topics as &$topic) {
            $topic['url'] = Helper::url('mobile/topic?keyword=' . urlencode($topic['name']));
        }
        unset($topic);

        $this->success(['items' => $topics]);
    }

    /**
     * 举报帖子
     */
    public function reportPost()
    {
        if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
            $this->error('请求方法错误');
        }

        $userId = $this->requireLogin();
        $postId = (int)$this->input('post_id');
        $reason = trim($this->input('reason', ''));
        $detail = trim($this->input('detail', ''));

        if (!$postId) {
            $this->error('请选择要举报的内容');
        }

        $validReasons = ['spam', 'porn', 'violence', 'fraud', 'harassment', 'privacy', 'copyright', 'other'];
        if (!in_array($reason, $validReasons)) {
            $this->error('请选择有效的举报原因');
        }

        $db = Database::getInstance();

        $exists = $db->fetch("SELECT id FROM __PREFIX__reports WHERE user_id = ? AND post_id = ?", [$userId, $postId]);
        if ($exists) {
            $this->error('您已经举报过该内容');
        }

        $result = $db->insert('reports', [
            'user_id' => $userId,
            'post_id' => $postId,
            'reason' => $reason,
            'detail' => $detail,
            'status' => 0,
            'created_at' => time()
        ]);

        if ($result) {
            $this->success(null, '举报成功，感谢您的反馈');
        } else {
            $this->error('举报失败');
        }
    }

    /**
     * 获取用户积分和等级信息
     */
    public function getUserPoints()
    {
        $userId = $this->requireLogin();

        $user = $this->userModel->find($userId);
        if (!$user) {
            $this->error('用户不存在');
        }

        require_once ROOT_PATH . 'content/point/PointModel.php';
        $pointModel = new PointModel();
        
        $points = $user['points'] ?? 0;
        $progress = $pointModel->getLevelProgress($points);

        $this->success([
            'points' => $points,
            'level' => $progress['current_level'],
            'next_level' => $progress['next_level'],
            'progress' => $progress['progress'],
            'points_to_next' => $progress['points_to_next']
        ]);
    }

    /**
     * 获取积分日志
     */
    public function getPointLogs()
    {
        $userId = $this->requireLogin();
        $page = (int)$this->input('page', 1);
        $pageSize = (int)$this->input('pageSize', 20);

        require_once ROOT_PATH . 'content/point/PointModel.php';
        $pointModel = new PointModel();
        
        $result = $pointModel->getUserLogs($userId, $page, $pageSize);

        foreach ($result['items'] as &$log) {
            $log['created_at'] = date('Y-m-d H:i', $log['created_at']);
        }
        unset($log);

        $this->success($result);
    }

    /**
     * 获取等级配置列表
     */
    public function getLevelConfig()
    {
        require_once ROOT_PATH . 'content/point/PointModel.php';
        $pointModel = new PointModel();
        
        $levels = $pointModel->getLevelConfig();

        $this->success(['items' => $levels]);
    }

    /**
     * 获取我的举报列表
     */
    public function getMyReports()
    {
        $userId = $this->requireLogin();
        $page = (int)$this->input('page', 1);
        $pageSize = (int)$this->input('pageSize', 20);
        $status = $this->input('status');

        $db = Database::getInstance();
        $where = 'r.user_id = ?';
        $params = [$userId];

        if ($status !== null && $status !== '') {
            $where .= ' AND r.status = ?';
            $params[] = (int)$status;
        }

        $offset = ($page - 1) * $pageSize;

        $sql = "SELECT r.*, p.content as post_content, p.user_id as post_user_id
                FROM __PREFIX__reports r
                LEFT JOIN __PREFIX__posts p ON r.post_id = p.id
                WHERE {$where}
                ORDER BY r.created_at DESC
                LIMIT {$offset}, {$pageSize}";

        $reports = $db->fetchAll($sql, $params);

        $countSql = "SELECT COUNT(*) as total FROM __PREFIX__reports r WHERE {$where}";
        $total = $db->fetch($countSql, $params)['total'];

        foreach ($reports as &$report) {
            if ($report['post_id']) {
                $report['post'] = [
                    'id' => $report['post_id'],
                    'content' => $report['post_content'],
                    'user_id' => $report['post_user_id']
                ];
                $postUser = $db->fetch("SELECT username FROM __PREFIX__users WHERE id = ?", [$report['post_user_id']]);
                if ($postUser) {
                    $report['post']['username'] = $postUser['username'];
                }
            }
        }
        unset($report);

        $this->success([
            'items' => $reports,
            'pagination' => [
                'total' => $total,
                'page' => $page,
                'page_size' => $pageSize,
                'has_more' => count($reports) >= $pageSize
            ]
        ]);
    }

    /**
     * 获取黑名单列表
     */
    public function getBlacklist()
    {
        $userId = $this->requireLogin();
        
        $db = Database::getInstance();
        $prefix = $db->getPrefix();
        
        $sql = "SELECT b.blacklist_user_id as user_id, u.username, u.avatar, b.created_at as add_time
                FROM `" . $prefix . "user_blacklist` b
                LEFT JOIN `" . $prefix . "users` u ON b.blacklist_user_id = u.id
                WHERE b.user_id = ?
                ORDER BY b.created_at DESC";
        
        $list = $db->fetchAll($sql, [$userId]);
        
        foreach ($list as &$item) {
            $item['avatar'] = !empty($item['avatar']) ? Helper::uploadUrl($item['avatar']) : '';
            $item['add_time'] = !empty($item['add_time']) ? date('Y-m-d H:i', $item['add_time']) : '';
        }
        unset($item);
        
        $this->success(['list' => $list]);
    }

    /**
     * 添加到黑名单
     */
    public function addBlacklist()
    {
        if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
            $this->error('请求方法错误');
        }
        
        $userId = $this->requireLogin();
        $username = trim($this->input('username'));
        
        if (!$username) {
            $this->error('请输入用户名');
        }
        
        $db = Database::getInstance();
        $prefix = $db->getPrefix();
        
        // 查找用户ID
        $targetUser = $db->fetch("SELECT id FROM `" . $prefix . "users` WHERE username = ?", [$username]);
        if (!$targetUser) {
            $this->error('用户不存在');
        }
        
        $targetId = $targetUser['id'];
        
        // 不能拉黑自己
        if ($targetId == $userId) {
            $this->error('不能拉黑自己');
        }
        
        // 检查是否已在黑名单中
        $exists = $db->fetch("SELECT id FROM `" . $prefix . "user_blacklist` WHERE user_id = ? AND blacklist_user_id = ?", [$userId, $targetId]);
        if ($exists) {
            $this->error('该用户已在黑名单中');
        }
        
        $result = $db->insert($prefix . 'user_blacklist', [
            'user_id' => $userId,
            'blacklist_user_id' => $targetId,
            'created_at' => time()
        ]);
        
        if ($result) {
            $this->success(null, '添加成功');
        } else {
            $this->error('添加失败');
        }
    }

    /**
     * 从黑名单移除
     */
    public function removeBlacklist()
    {
        if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
            $this->error('请求方法错误');
        }
        
        $userId = $this->requireLogin();
        $targetId = (int)$this->input('user_id');
        
        if (!$targetId) {
            $this->error('参数错误');
        }
        
        $db = Database::getInstance();
        $prefix = $db->getPrefix();
        
        $result = $db->delete($prefix . 'user_blacklist', ['user_id' => $userId, 'blacklist_user_id' => $targetId]);
        
        if ($result) {
            $this->success(null, '移除成功');
        } else {
            $this->error('移除失败');
        }
    }

    /**
     * 修改密码
     */
    public function changePassword()
    {
        if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
            $this->error('请求方法错误');
        }
        
        $userId = $this->requireLogin();
        
        $oldPassword = $this->input('old_password');
        $newPassword = $this->input('new_password');
        
        if (!$oldPassword) {
            $this->error('请输入当前密码');
        }
        
        if (!$newPassword || strlen($newPassword) < 6) {
            $this->error('新密码至少需要6位');
        }
        
        $user = $this->userModel->find($userId);
        if (!$user) {
            $this->error('用户不存在');
        }
        
        // 验证旧密码
        if (!password_verify($oldPassword, $user['password'])) {
            $this->error('当前密码错误');
        }
        
        $result = $this->userModel->updatePassword($userId, $newPassword);
        
        if ($result) {
            $this->success(null, '密码修改成功');
        } else {
            $this->error('修改失败');
        }
    }

    /**
     * 获取登录设备列表
     */
    public function getDevices()
    {
        $userId = $this->requireLogin();
        
        $db = Database::getInstance();
        $prefix = $db->getPrefix();
        
        $sql = "SELECT id, device_name, ip_address, login_time 
                FROM `" . $prefix . "user_sessions` 
                WHERE user_id = ? 
                ORDER BY login_time DESC";
        
        $list = $db->fetchAll($sql, [$userId]);
        
        foreach ($list as &$item) {
            $item['login_time'] = !empty($item['login_time']) ? date('Y-m-d H:i', $item['login_time']) : '';
        }
        unset($item);
        
        $this->success(['list' => $list]);
    }

    /**
     * 退出指定设备登录
     */
    public function logoutDevice()
    {
        if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
            $this->error('请求方法错误');
        }
        
        $userId = $this->requireLogin();
        $deviceId = (int)$this->input('device_id');
        
        if (!$deviceId) {
            $this->error('参数错误');
        }
        
        $db = Database::getInstance();
        $prefix = $db->getPrefix();
        
        $result = $db->delete($prefix . 'user_sessions', ['id' => $deviceId, 'user_id' => $userId]);
        
        if ($result) {
            $this->success(null, '已退出该设备');
        } else {
            $this->error('操作失败');
        }
    }

    /**
     * 导出数据
     */
    public function exportData()
    {
        $userId = $this->requireLogin();
        $type = $this->input('type', 'all');
        
        $db = Database::getInstance();
        $prefix = $db->getPrefix();
        
        $data = [];
        
        if ($type === 'all' || $type === 'posts') {
            $posts = $db->fetchAll("SELECT * FROM `" . $prefix . "posts` WHERE user_id = ? ORDER BY created_at DESC", [$userId]);
            $data['posts'] = $posts;
        }
        
        if ($type === 'all' || $type === 'comments') {
            $comments = $db->fetchAll("SELECT * FROM `" . $prefix . "comments` WHERE user_id = ? ORDER BY created_at DESC", [$userId]);
            $data['comments'] = $comments;
        }
        
        if ($type === 'all') {
            $favorites = $db->fetchAll("SELECT * FROM `" . $prefix . "favorites` WHERE user_id = ? ORDER BY created_at DESC", [$userId]);
            $data['favorites'] = $favorites;
            
            $likes = $db->fetchAll("SELECT * FROM `" . $prefix . "likes` WHERE user_id = ? ORDER BY created_at DESC", [$userId]);
            $data['likes'] = $likes;
        }
        
        $this->success($data);
    }

    /**
     * 删除账号
     */
    public function deleteAccount()
    {
        if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
            $this->error('请求方法错误');
        }
        
        $userId = $this->requireLogin();
        $password = $this->input('password');
        
        if (!$password) {
            $this->error('请输入密码');
        }
        
        $user = $this->userModel->find($userId);
        if (!$user) {
            $this->error('用户不存在');
        }
        
        if (!password_verify($password, $user['password'])) {
            $this->error('密码错误');
        }
        
        $db = Database::getInstance();
        $prefix = $db->getPrefix();
        
        // 开启事务
        $db->beginTransaction();
        
        try {
            // 删除用户相关数据
            $db->delete($prefix . 'posts', ['user_id' => $userId]);
            $db->delete($prefix . 'comments', ['user_id' => $userId]);
            $db->delete($prefix . 'favorites', ['user_id' => $userId]);
            $db->delete($prefix . 'likes', ['user_id' => $userId]);
            $db->delete($prefix . 'followers', ['user_id' => $userId]);
            $db->delete($prefix . 'followers', ['follow_id' => $userId]);
            $db->delete($prefix . 'user_blacklist', ['user_id' => $userId]);
            $db->delete($prefix . 'user_blacklist', ['target_id' => $userId]);
            $db->delete($prefix . 'reports', ['user_id' => $userId]);
            $db->delete($prefix . 'user_sessions', ['user_id' => $userId]);
            $db->delete($prefix . 'users', ['id' => $userId]);
            
            $db->commit();
            $this->success(null, '账号已删除');
        } catch (Exception $e) {
            $db->rollback();
            $this->error('删除失败: ' . $e->getMessage());
        }
    }
    
    /**
     * 获取隐私设置
     */
    public function getPrivacySettings()
    {
        $userId = isset($_SESSION['user_id']) ? $_SESSION['user_id'] : null;
        
        if (!$userId) {
            $this->error('请先登录');
        }
        
        $db = Database::getInstance();
        $prefix = $db->getPrefix();
        
        // 从settings表获取隐私设置（键格式：user_privacy_{userId}_{setting_key}）
        $settings = [];
        $settingKeys = [
            'profile_visibility',
            'show_online_status',
            'allow_stranger_messages',
            'comment_visibility',
            'repost_visibility',
            'allow_search',
            'notify_likes',
            'notify_comments',
            'notify_follows',
            'notify_system'
        ];
        
        foreach ($settingKeys as $key) {
            $dbKey = "user_privacy_{$userId}_{$key}";
            $row = $db->fetch("SELECT value FROM `{$prefix}settings` WHERE `key` = ?", [$dbKey]);
            if ($row) {
                $settings[$key] = $row['value'];
            } else {
                // 设置默认值
                $settings[$key] = in_array($key, ['profile_visibility', 'comment_visibility', 'repost_visibility']) ? 'public' : '1';
            }
        }
        
        $this->success([
            'settings' => $settings
        ]);
    }
    
    /**
     * 保存隐私设置
     */
    public function savePrivacySettings()
    {
        if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
            $this->error('请求方法错误');
        }
        
        $userId = $this->requireLogin();
        
        $db = Database::getInstance();
        $prefix = $db->getPrefix();
        
        // 要保存的设置项
        $settingKeys = [
            'profile_visibility',
            'show_online_status',
            'allow_stranger_messages',
            'comment_visibility',
            'repost_visibility',
            'allow_search',
            'notify_likes',
            'notify_comments',
            'notify_follows',
            'notify_system'
        ];
        
        $now = time();
        $savedCount = 0;
        
        foreach ($settingKeys as $key) {
            $value = $this->input($key);
            if ($value !== null) {
                $dbKey = "user_privacy_{$userId}_{$key}";
                
                // 检查是否已存在
                $existing = $db->fetch("SELECT id FROM `{$prefix}settings` WHERE `key` = ?", [$dbKey]);
                
                if ($existing) {
                    // 更新
                    $db->update('settings', [
                        'value' => $value,
                        'updated_at' => $now
                    ], '`key` = ?', [$dbKey]);
                } else {
                    // 新增
                    $db->insert('settings', [
                        'key' => $dbKey,
                        'value' => $value,
                        'created_at' => $now,
                        'updated_at' => $now
                    ]);
                }
                $savedCount++;
            }
        }
        
        if ($savedCount > 0) {
            $this->success(['saved' => $savedCount], '保存成功');
        } else {
            $this->error('没有要保存的设置');
        }
    }

    /**
     * 发起通话请求
     */
    public function startCall()
    {
        if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
            $this->error('请求方法错误');
        }

        $userId = $this->requireLogin();
        $targetUserId = (int)$this->input('user_id');
        $callType = $this->input('type', 'voice'); // voice 或 video

        if (!$targetUserId) {
            $this->error('参数错误');
        }

        if ($targetUserId == $userId) {
            $this->error('不能呼叫自己');
        }

        // 检查目标用户是否存在
        $targetUser = $this->userModel->find($targetUserId);
        if (!$targetUser) {
            $this->error('用户不存在');
        }

        // 清理过期的通话记录
        require_once ROOT_PATH . 'templates/mobile/MessageModel.php';
        $messageModel = new MessageModel();
        $messageModel->cleanupExpiredCalls();

        // 生成通话ID
        $callId = uniqid('call_') . '_' . time();

        // 存储通话状态到数据库
        // 获取当前用户信息
        $currentUser = $this->userModel->find($userId);
        $callerName = $currentUser ? $currentUser['username'] : '';
        $callerAvatar = $currentUser ? $currentUser['avatar'] : '';
        
        $messageModel->createCall($callId, $userId, $callerName, $callerAvatar, $targetUserId, $callType);

        $this->success([
            'call_id' => $callId,
            'status' => 'pending',
            'caller_id' => $userId,
            'callee_id' => $targetUserId,
            'type' => $callType
        ], '呼叫已发起');
    }

    /**
     * 检查通话状态
     */
    public function checkCallStatus()
    {
        $userId = $this->requireLogin();
        $callId = $this->input('call_id');

        require_once ROOT_PATH . 'templates/mobile/MessageModel.php';
        $messageModel = new MessageModel();

        // 首先检查是否有新的来电
        $pendingCall = $messageModel->getPendingCallForUser($userId);
        if ($pendingCall) {
            $avatarUrl = !empty($pendingCall['caller_avatar']) ? Helper::uploadUrl($pendingCall['caller_avatar']) : '';
            $this->success([
                'has_call' => true,
                'call_id' => $pendingCall['call_id'],
                'caller_id' => $pendingCall['caller_id'],
                'caller_name' => $pendingCall['caller_name'],
                'caller_avatar' => $avatarUrl,
                'type' => $pendingCall['type'],
                'status' => 'incoming'
            ]);
        }

        // 如果传入了call_id，检查特定通话的状态
        if ($callId) {
            $call = $messageModel->getCall($callId);
            if ($call) {
                $this->success([
                    'has_call' => true,
                    'call_id' => $call['call_id'],
                    'caller_id' => $call['caller_id'],
                    'callee_id' => $call['callee_id'],
                    'type' => $call['type'],
                    'status' => $call['status']
                ]);
            }
        }

        // 检查用户是否有正在进行的通话
        $outgoingCall = $messageModel->getOutgoingCall($userId);
        if ($outgoingCall) {
            $this->success([
                'has_call' => true,
                'call_id' => $outgoingCall['call_id'],
                'caller_id' => $outgoingCall['caller_id'],
                'callee_id' => $outgoingCall['callee_id'],
                'type' => $outgoingCall['type'],
                'status' => $outgoingCall['status']
            ]);
        }

        $this->success([
            'has_call' => false,
            'status' => 'idle'
        ]);
    }

    /**
     * 接听通话
     */
    public function acceptCall()
    {
        if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
            $this->error('请求方法错误');
        }

        $userId = $this->requireLogin();
        $callId = $this->input('call_id');

        if (!$callId) {
            $this->error('参数错误');
        }

        require_once ROOT_PATH . 'templates/mobile/MessageModel.php';
        $messageModel = new MessageModel();

        // 验证通话是否存在且是给当前用户的
        $call = $messageModel->getCall($callId);
        if (!$call) {
            $this->error('通话不存在');
        }

        if ($call['callee_id'] != $userId) {
            $this->error('无权接听此通话');
        }

        if ($call['status'] !== 'pending') {
            $this->error('通话状态已变化');
        }

        // 更新通话状态为已接听
        $messageModel->updateCallStatus($callId, 'accepted');

        $this->success([
            'call_id' => $callId,
            'status' => 'accepted',
            'caller_id' => $call['caller_id'],
            'type' => $call['type']
        ], '已接听');
    }

    /**
     * 拒绝通话
     */
    public function rejectCall()
    {
        if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
            $this->error('请求方法错误');
        }

        $userId = $this->requireLogin();
        $callId = $this->input('call_id');

        if (!$callId) {
            $this->error('参数错误');
        }

        require_once ROOT_PATH . 'templates/mobile/MessageModel.php';
        $messageModel = new MessageModel();

        // 验证通话是否存在且是给当前用户的
        $call = $messageModel->getCall($callId);
        if (!$call) {
            $this->error('通话不存在');
        }

        if ($call['callee_id'] != $userId) {
            $this->error('无权拒绝此通话');
        }

        // 更新通话状态为已拒绝
        $messageModel->updateCallStatus($callId, 'rejected');

        $this->success([
            'call_id' => $callId,
            'status' => 'rejected'
        ], '已拒绝');
    }

    /**
     * 结束通话
     */
    public function endCall()
    {
        if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
            $this->error('请求方法错误');
        }

        $userId = $this->requireLogin();
        $callId = $this->input('call_id');

        if (!$callId) {
            $this->error('参数错误');
        }

        require_once ROOT_PATH . 'templates/mobile/MessageModel.php';
        $messageModel = new MessageModel();

        // 查找通话记录
        $call = $messageModel->getCall($callId);
        if (!$call) {
            $this->error('通话不存在');
        }

        // 验证用户是否有权结束通话（发起方或接收方都可以结束）
        if ($call['caller_id'] != $userId && $call['callee_id'] != $userId) {
            $this->error('无权结束此通话');
        }

        // 更新通话状态为已结束
        $messageModel->updateCallStatus($callId, 'ended');

        $this->success([
            'call_id' => $callId,
            'status' => 'ended'
        ], '通话已结束');
    }
}
