<?php
/**
 * 全局函数库
 */

// 引入配置文件
require_once __DIR__ . '/../config/config.php';

// 引入 Database 类
require_once __DIR__ . '/Database.php';

/**
 * 获取数据库实例
 */
function db() {
    return Database::getInstance();
}

/**
 * 获取设置项
 */
function getSetting($key, $default = '') {
    static $settings = null;
    if ($settings === null) {
        $settings = [];
        try {
            $result = db()->query("SELECT setting_key, setting_value FROM settings");
            foreach ($result as $row) {
                $settings[$row['setting_key']] = $row['setting_value'];
            }
        } catch (Exception $e) {
            // 数据库未初始化时使用默认值
        }
    }
    return $settings[$key] ?? $default;
}

/**
 * 检查用户是否登录
 */
function isLoggedIn() {
    return isset($_SESSION['user_id']);
}

/**
 * 获取当前登录用户
 */
function getCurrentUser() {
    if (!isLoggedIn()) {
        return null;
    }
    
    static $user = null;
    if ($user === null) {
        $user = db()->queryOne("SELECT * FROM users WHERE id = ?", [$_SESSION['user_id']]);
    }
    return $user;
}

/**
 * 检查用户是否是管理员（包括超级管理员）
 */
function isAdmin() {
    $user = getCurrentUser();
    return $user && ($user['role'] == 1 || $user['role'] == 2);
}

/**
 * 检查用户是否是超级管理员
 */
function isSuperAdmin() {
    $user = getCurrentUser();
    return $user && $user['role'] == 2;
}

/**
 * 重定向到指定页面
 */
function redirect($url) {
    header("Location: " . $url);
    exit;
}

/**
 * 显示提示消息
 */
function setFlashMessage($type, $message) {
    $_SESSION['flash_message'] = ['type' => $type, 'message' => $message];
}

/**
 * 获取并清除提示消息
 */
function getFlashMessage() {
    if (isset($_SESSION['flash_message'])) {
        $message = $_SESSION['flash_message'];
        unset($_SESSION['flash_message']);
        return $message;
    }
    return null;
}

/**
 * 生成 CSRF Token
 */
function generateCsrfToken() {
    if (!isset($_SESSION['csrf_token'])) {
        $_SESSION['csrf_token'] = bin2hex(random_bytes(32));
    }
    return $_SESSION['csrf_token'];
}

/**
 * 验证 CSRF Token
 */
function validateCsrfToken($token) {
    return isset($_SESSION['csrf_token']) && hash_equals($_SESSION['csrf_token'], $token);
}

/**
 * 格式化时间
 */
function formatTime($time) {
    if (empty($time)) return '';
    $timestamp = strtotime($time);
    $now = time();
    $diff = $now - $timestamp;

    if ($diff < 60) {
        return '刚刚';
    } elseif ($diff < 3600) {
        return floor($diff / 60) . '分钟前';
    } elseif ($diff < 86400) {
        return floor($diff / 3600) . '小时前';
    } elseif ($diff < 604800) {
        return floor($diff / 86400) . '天前';
    } else {
        return date('Y-m-d H:i', $timestamp);
    }
}

/**
 * 截取字符串
 */
function truncate($string, $length = 100, $suffix = '...') {
    if (strlen($string) <= $length) {
        return $string;
    }
    return substr($string, 0, $length) . $suffix;
}

/**
 * 分页函数
 * @param string $url 基础URL，如果已包含?则用&连接参数
 */
function pagination($total, $page, $perPage, $url) {
    $totalPages = ceil($total / $perPage);
    $page = max(1, min($page, $totalPages));
    
    // 判断URL是否已包含参数
    $separator = (strpos($url, '?') !== false) ? '&' : '?';

    $html = '<div class="pagination">';

    // 上一页
    if ($page > 1) {
        $html .= '<a href="' . $url . $separator . 'page=' . ($page - 1) . '" class="page-link">上一页</a>';
    }

    // 页码
    $start = max(1, $page - 2);
    $end = min($totalPages, $page + 2);

    if ($start > 1) {
        $html .= '<a href="' . $url . $separator . 'page=1" class="page-link">1</a>';
        if ($start > 2) {
            $html .= '<span class="page-ellipsis">...</span>';
        }
    }

    for ($i = $start; $i <= $end; $i++) {
        if ($i == $page) {
            $html .= '<span class="page-link active">' . $i . '</span>';
        } else {
            $html .= '<a href="' . $url . $separator . 'page=' . $i . '" class="page-link">' . $i . '</a>';
        }
    }

    if ($end < $totalPages) {
        if ($end < $totalPages - 1) {
            $html .= '<span class="page-ellipsis">...</span>';
        }
        $html .= '<a href="' . $url . $separator . 'page=' . $totalPages . '" class="page-link">' . $totalPages . '</a>';
    }

    // 下一页
    if ($page < $totalPages) {
        $html .= '<a href="' . $url . $separator . 'page=' . ($page + 1) . '" class="page-link">下一页</a>';
    }

    $html .= '</div>';

    return $html;
}

/**
 * 获取客户端 IP
 */
function getClientIp() {
    $ipKeys = ['HTTP_CF_CONNECTING_IP', 'HTTP_CLIENT_IP', 'HTTP_X_FORWARDED_FOR', 'REMOTE_ADDR'];
    foreach ($ipKeys as $key) {
        if (!empty($_SERVER[$key])) {
            return $_SERVER[$key];
        }
    }
    return '0.0.0.0';
}

/**
 * HTML 转义
 */
function e($string) {
    if ($string === null) {
        return '';
    }
    return htmlspecialchars((string)$string, ENT_QUOTES, 'UTF-8');
}

/**
 * 获取未读通知数量
 */
function getUnreadNotificationCount($userId) {
    $result = db()->queryOne(
        "SELECT COUNT(*) as count FROM notifications WHERE user_id = ? AND is_read = 0",
        [$userId]
    );
    return $result ? intval($result['count']) : 0;
}

/**
 * 获取通知列表
 */
function getNotifications($userId, $page = 1, $perPage = 20) {
    $offset = ($page - 1) * $perPage;
    return db()->query(
        "SELECT n.id, n.user_id, n.sender_id, n.type, n.target_type, n.target_id, n.related_id, n.content, n.is_read, n.created_at, u.username as sender_name, u.avatar as sender_avatar
         FROM notifications n
         LEFT JOIN users u ON n.sender_id = u.id
         WHERE n.user_id = ?
         ORDER BY n.created_at DESC
         LIMIT ? OFFSET ?",
        [$userId, $perPage, $offset]
    );
}

/**
 * 按类型获取通知列表
 */
function getNotificationsByType($userId, $type, $page = 1, $perPage = 20) {
    $offset = ($page - 1) * $perPage;
    return db()->query(
        "SELECT n.id, n.user_id, n.sender_id, n.type, n.target_type, n.target_id, n.related_id, n.content, n.is_read, n.created_at, u.username as sender_name, u.avatar as sender_avatar
         FROM notifications n
         LEFT JOIN users u ON n.sender_id = u.id
         WHERE n.user_id = ? AND n.type = ?
         ORDER BY n.created_at DESC
         LIMIT ? OFFSET ?",
        [$userId, $type, $perPage, $offset]
    );
}

/**
 * 标记通知为已读
 */
function markNotificationAsRead($notificationId, $userId) {
    db()->execute(
        "UPDATE notifications SET is_read = 1 WHERE id = ? AND user_id = ?",
        [$notificationId, $userId]
    );
}

/**
 * 标记所有通知为已读
 */
function markAllNotificationsAsRead($userId) {
    db()->execute(
        "UPDATE notifications SET is_read = 1 WHERE user_id = ? AND is_read = 0",
        [$userId]
    );
}

/**
 * 获取通知类型文本
 */
function getNotificationTypeText($type) {
    $types = [
        'like' => '点赞',
        'favorite' => '收藏',
        'reply' => '回复',
        'follow' => '关注',
        'medal_unlock' => '勋章解锁',
        'medal_unlocked' => '解锁成功'
    ];
    return $types[$type] ?? $type;
}

/**
 * 发送通知
 */
function sendNotification($userId, $type, $relatedId = null, $senderId = null) {
    try {
        // 检查通知表是否有 related_id 字段
        $tableInfo = db()->query("SHOW COLUMNS FROM notifications LIKE 'related_id'");
        if (empty($tableInfo)) {
            // 添加 related_id 字段
            db()->execute("ALTER TABLE notifications ADD COLUMN related_id INT UNSIGNED DEFAULT NULL AFTER target_id");
            db()->execute("ALTER TABLE notifications ADD COLUMN sender_name VARCHAR(100) DEFAULT NULL AFTER sender_id");
            db()->execute("ALTER TABLE notifications ADD COLUMN sender_avatar VARCHAR(255) DEFAULT NULL AFTER sender_name");
        }
        
        // 修改 type 字段允许 medal_unlock 和 medal_unlocked
        db()->execute("ALTER TABLE notifications MODIFY COLUMN type VARCHAR(50) NOT NULL");
        
        // 插入通知
        db()->execute(
            "INSERT INTO notifications (user_id, sender_id, type, related_id, created_at) VALUES (?, ?, ?, ?, NOW())",
            [$userId, $senderId, $type, $relatedId]
        );
        return true;
    } catch (Exception $e) {
        error_log('发送通知失败: ' . $e->getMessage());
        return false;
    }
}

/**
 * 获取点赞数
 */
function getLikeCount($targetType, $targetId) {
    $result = db()->queryOne(
        "SELECT COUNT(*) as count FROM likes WHERE target_type = ? AND target_id = ?",
        [$targetType, $targetId]
    );
    return $result ? intval($result['count']) : 0;
}

/**
 * 获取收藏数
 */
function getFavoriteCount($targetType, $targetId) {
    $result = db()->queryOne(
        "SELECT COUNT(*) as count FROM favorites WHERE target_type = ? AND target_id = ?",
        [$targetType, $targetId]
    );
    return $result ? intval($result['count']) : 0;
}

/**
 * 检查用户是否已点赞
 */
function isLiked($userId, $targetType, $targetId) {
    $result = db()->queryOne(
        "SELECT id FROM likes WHERE user_id = ? AND target_type = ? AND target_id = ?",
        [$userId, $targetType, $targetId]
    );
    return !!$result;
}

/**
 * ==================== 勋章系统 ====================
 */

/**
 * 获取所有勋章列表
 */
function getAllMedals() {
    return db()->query(
        "SELECT * FROM medals WHERE status = 1 ORDER BY sort_order ASC, id ASC"
    );
}

/**
 * 获取用户的所有勋章
 */
function getUserMedals($userId) {
    return db()->query(
        "SELECT m.*, um.is_wearing, um.awarded_at 
         FROM medals m 
         INNER JOIN user_medals um ON m.id = um.medal_id 
         WHERE um.user_id = ? AND m.status = 1 
         ORDER BY um.awarded_at DESC",
        [$userId]
    );
}

/**
 * 获取用户佩戴的勋章
 */
function getUserWearingMedals($userId) {
    return db()->query(
        "SELECT m.* 
         FROM medals m 
         INNER JOIN user_medals um ON m.id = um.medal_id 
         WHERE um.user_id = ? AND um.is_wearing = 1 AND m.status = 1 
         ORDER BY m.sort_order ASC",
        [$userId]
    );
}

/**
 * 检查用户是否已获得某勋章
 */
function hasUserMedal($userId, $medalId) {
    $result = db()->queryOne(
        "SELECT id FROM user_medals WHERE user_id = ? AND medal_id = ?",
        [$userId, $medalId]
    );
    return !!$result;
}

/**
 * 颁发勋章给用户
 */
function awardMedalToUser($userId, $medalId) {
    // 检查是否已拥有
    if (hasUserMedal($userId, $medalId)) {
        return false;
    }
    
    try {
        db()->execute(
            "INSERT INTO user_medals (user_id, medal_id, is_wearing) VALUES (?, ?, 0)",
            [$userId, $medalId]
        );
        return true;
    } catch (Exception $e) {
        error_log('颁发勋章失败: ' . $e->getMessage());
        return false;
    }
}

/**
 * 佩戴/取消佩戴勋章
 */
function toggleWearMedal($userId, $medalId, $wear) {
    db()->execute(
        "UPDATE user_medals SET is_wearing = ? WHERE user_id = ? AND medal_id = ?",
        [$wear ? 1 : 0, $userId, $medalId]
    );
}

/**
 * 检查勋章解锁条件（返回可解锁的勋章列表，不自动颁发）
 */
function checkMedalUnlockConditions($userId) {
    // 获取所有启用的勋章
    $medals = getAllMedals();
    $unlockableMedals = [];
    
    foreach ($medals as $medal) {
        // 检查是否已拥有
        if (hasUserMedal($userId, $medal['id'])) {
            continue;
        }
        
        $canUnlock = false;
        
        switch ($medal['condition_type']) {
            case 'post_favorited':
                // 检查用户的帖子被收藏总数
                $count = db()->queryOne(
                    "SELECT COUNT(*) as count FROM favorites f 
                     INNER JOIN posts p ON f.target_id = p.id 
                     WHERE f.target_type = 'post' AND p.user_id = ?",
                    [$userId]
                );
                if ($count && intval($count['count']) >= $medal['condition_value']) {
                    $canUnlock = true;
                }
                break;
                
            case 'reply_count':
                // 检查用户的回复数
                $count = db()->queryOne(
                    "SELECT reply_count FROM users WHERE id = ?",
                    [$userId]
                );
                if ($count && intval($count['reply_count']) >= $medal['condition_value']) {
                    $canUnlock = true;
                }
                break;
                
            case 'post_liked':
                // 检查用户的帖子被点赞总数
                $count = db()->queryOne(
                    "SELECT COUNT(*) as count FROM likes l 
                     INNER JOIN posts p ON l.target_id = p.id 
                     WHERE l.target_type = 'post' AND p.user_id = ?",
                    [$userId]
                );
                if ($count && intval($count['count']) >= $medal['condition_value']) {
                    $canUnlock = true;
                }
                break;
        }
        
        if ($canUnlock) {
            $unlockableMedals[] = $medal;
        }
    }
    
    return $unlockableMedals;
}

/**
 * 检查并发送勋章解锁通知
 */
function checkAndNotifyMedalUnlock($userId) {
    $unlockableMedals = checkMedalUnlockConditions($userId);
    
    foreach ($unlockableMedals as $medal) {
        // 检查是否已经发送过通知
        $existing = db()->queryOne(
            "SELECT id FROM notifications 
             WHERE user_id = ? AND type = 'medal_unlock' AND related_id = ? AND is_read = 0",
            [$userId, $medal['id']]
        );
        
        if (!$existing) {
            // 发送系统通知
            sendNotification($userId, 'medal_unlock', $medal['id'], 0);
        }
    }
    
    return $unlockableMedals;
}

/**
 * 用户手动解锁勋章
 */
function unlockMedal($userId, $medalId) {
    // 检查是否满足条件
    $medal = db()->queryOne("SELECT * FROM medals WHERE id = ? AND status = 1", [$medalId]);
    if (!$medal) {
        return ['success' => false, 'message' => '勋章不存在或已禁用'];
    }
    
    // 检查是否已拥有
    if (hasUserMedal($userId, $medalId)) {
        return ['success' => false, 'message' => '您已拥有此勋章'];
    }
    
    // 检查是否满足解锁条件
    $canUnlock = false;
    
    switch ($medal['condition_type']) {
        case 'post_favorited':
            $count = db()->queryOne(
                "SELECT COUNT(*) as count FROM favorites f 
                 INNER JOIN posts p ON f.target_id = p.id 
                 WHERE f.target_type = 'post' AND p.user_id = ?",
                [$userId]
            );
            if ($count && intval($count['count']) >= $medal['condition_value']) {
                $canUnlock = true;
            }
            break;
            
        case 'reply_count':
            $count = db()->queryOne(
                "SELECT reply_count FROM users WHERE id = ?",
                [$userId]
            );
            if ($count && intval($count['reply_count']) >= $medal['condition_value']) {
                $canUnlock = true;
            }
            break;
            
        case 'post_liked':
            $count = db()->queryOne(
                "SELECT COUNT(*) as count FROM likes l 
                 INNER JOIN posts p ON l.target_id = p.id 
                 WHERE l.target_type = 'post' AND p.user_id = ?",
                [$userId]
            );
            if ($count && intval($count['count']) >= $medal['condition_value']) {
                $canUnlock = true;
            }
            break;
    }
    
    if (!$canUnlock) {
        return ['success' => false, 'message' => '尚未满足解锁条件'];
    }
    
    // 颁发勋章
    if (awardMedalToUser($userId, $medalId)) {
        // 标记通知为已读
        db()->execute(
            "UPDATE notifications SET is_read = 1 
             WHERE user_id = ? AND type = 'medal_unlock' AND related_id = ?",
            [$userId, $medalId]
        );
        
        // 发送解锁成功通知
        sendNotification($userId, 'medal_unlocked', $medalId, 0);
        
        return ['success' => true, 'message' => '恭喜您解锁了勋章：' . $medal['name']];
    }
    
    return ['success' => false, 'message' => '解锁失败，请稍后重试'];
}

/**
 * 为管理员自动解锁所有勋章
 */
function awardAllMedalsToAdmin($userId) {
    $medals = getAllMedals();
    foreach ($medals as $medal) {
        if (!hasUserMedal($userId, $medal['id'])) {
            awardMedalToUser($userId, $medal['id']);
        }
    }
}

/**
 * 获取勋章获得人数
 */
function getMedalUserCount($medalId) {
    $result = db()->queryOne(
        "SELECT COUNT(*) as count FROM user_medals WHERE medal_id = ?",
        [$medalId]
    );
    return $result ? intval($result['count']) : 0;
}

/**
 * 检查用户是否已收藏
 */
function isFavorited($userId, $targetType, $targetId) {
    $result = db()->queryOne(
        "SELECT id FROM favorites WHERE user_id = ? AND target_type = ? AND target_id = ?",
        [$userId, $targetType, $targetId]
    );
    return !!$result;
}
