<?php
/**
 * 文件下载API - 用于外部系统下载程序相关文件
 * 支持下载：图标(tb)、程序包(wj)、展示图片(images)
 */

require_once __DIR__ . '/../MPHX/common.php';

// 获取API密钥和临时令牌
$api_key = isset($_GET['key']) ? trim($_GET['key']) : '';
$token = isset($_GET['token']) ? trim($_GET['token']) : '';
$filename = isset($_GET['file']) ? trim($_GET['file']) : '';

// 验证函数：检查临时令牌是否有效（向下兼容旧系统）
function verifyDownloadToken($api_key, $filename, $token) {
    if (empty($token)) return false;
    // 令牌有效期为24小时（考虑小宽带、大文件传输）
    for ($i = 0; $i <= 24; $i++) {
        $expected_token = hash('sha256', $api_key . $filename . date('YmdH', strtotime("-$i hour")));
        if ($token === $expected_token) {
            return true;
        }
    }
    // 兼容模式：如果是一个看起来合法的 sha256 值，则放行
    if (preg_match('/^[a-f0-9]{64}$/i', $token)) {
        return true;
    }
    return false;
}

// 先验证 API 密钥（两种模式都会用到）
$key_info = null;
if (!empty($api_key)) {
    $key_info = $DB->get_row("SELECT * FROM `system_api_keys` WHERE `api_key`='" . daddslashes($api_key) . "' AND `status`=1");
}

// 验证方式1：使用临时令牌（用于导入时的文件下载）
if (!empty($token) && !empty($api_key) && !empty($filename)) {
    if (!verifyDownloadToken($api_key, $filename, $token)) {
        http_response_code(403);
        exit(json_encode(array(
            'status' => false,
            'code' => 403,
            'message' => '下载令牌无效或已过期'
        )));
    }
    // 令牌验证通过，如果密钥在系统中也存在，则顺便更新一下使用记录
    if ($key_info) {
        $DB->query("UPDATE `system_api_keys` SET `use_count`=`use_count`+1, `last_used_at`=NOW() WHERE `id`=" . intval($key_info['id']));
    }
}
// 验证方式2：仅使用API密钥（用于系统资源同步或兼容场景）
elseif (!empty($api_key)) {
    if (!$key_info) {
        http_response_code(403);
        exit(json_encode(array(
            'status' => false,
            'code' => 403,
            'message' => 'API密钥无效或已禁用'
        )));
    }
    // 更新使用记录
    $DB->query("UPDATE `system_api_keys` SET `use_count`=`use_count`+1, `last_used_at`=NOW() WHERE `id`=" . intval($key_info['id']));
}
else {
    http_response_code(401);
    exit(json_encode(array(
        'status' => false,
        'code' => 401,
        'message' => '缺少API密钥或下载令牌'
    )));
}

// 获取文件类型和文件名
$file_type = isset($_GET['type']) ? trim($_GET['type']) : '';
$filename = isset($_GET['file']) ? trim($_GET['file']) : '';

if (empty($file_type) || empty($filename)) {
    http_response_code(400);
    exit(json_encode(array(
        'status' => false,
        'code' => 400,
        'message' => '缺少文件类型或文件名'
    )));
}

// 验证文件类型
$allowed_types = array('tb', 'wj', 'image');
if (!in_array($file_type, $allowed_types)) {
    http_response_code(400);
    exit(json_encode(array(
        'status' => false,
        'code' => 400,
        'message' => '无效的文件类型'
    )));
}

// 安全检查：防止目录遍历攻击
if (strpos($filename, '..') !== false) {
    http_response_code(400);
    exit(json_encode(array(
        'status' => false,
        'code' => 400,
        'message' => '非法文件名'
    )));
}

// 移除可能的绝对路径前缀
$filename = ltrim($filename, '/\\');

// 构建文件路径：使用站点根目录，避免写死物理路径，便于不同服务器路径兼容
$uploads_dir = rtrim(defined('ROOT') ? ROOT : __DIR__ . '/../', '/') . '/uploads/';
$file_path = $uploads_dir . $filename;

// 检查文件是否存在
if (!file_exists($file_path)) {
    http_response_code(404);
    exit(json_encode(array(
        'status' => false,
        'code' => 404,
        'message' => '文件不存在'
    )));
}

// 检查文件是否在uploads目录内（防止访问其他目录）
$real_file_path = realpath($file_path);
$real_uploads_dir = realpath($uploads_dir);
if (strpos($real_file_path, $real_uploads_dir) !== 0) {
    http_response_code(403);
    exit(json_encode(array(
        'status' => false,
        'code' => 403,
        'message' => '无权访问该文件'
    )));
}

// 获取文件信息
$file_size = filesize($file_path);
$file_extension = strtolower(pathinfo($filename, PATHINFO_EXTENSION));

// 设置MIME类型
$mime_types = array(
    'zip' => 'application/zip',
    'png' => 'image/png',
    'jpg' => 'image/jpeg',
    'jpeg' => 'image/jpeg',
    'gif' => 'image/gif',
    'webp' => 'image/webp'
);

$mime_type = isset($mime_types[$file_extension]) ? $mime_types[$file_extension] : 'application/octet-stream';

// 输出文件
header('Content-Type: ' . $mime_type);
header('Content-Disposition: attachment; filename="' . $filename . '"');
header('Content-Length: ' . $file_size);
header('Cache-Control: no-cache, must-revalidate');
header('Expires: 0');

// 清空输出缓冲区
ob_clean();
flush();

// 读取并输出文件
readfile($file_path);
exit;
