<?php
require_once dirname(dirname(dirname(__DIR__))) . '/core/lib/common.php';
require_once dirname(dirname(dirname(__DIR__))) . '/core/lib/session.php';
require_once dirname(dirname(dirname(__DIR__))) . '/core/db/db.php';
require_once dirname(dirname(dirname(__DIR__))) . '/core/lib/rbac.php';

cmsStartSession();

header('Content-Type: application/json; charset=utf-8');

$action = isset($_GET['action']) ? trim($_GET['action']) : 'config';
$configPath = __DIR__ . '/config.json';
$configRaw = file_exists($configPath) ? file_get_contents($configPath) : '{}';
$configRaw = preg_replace('!/\*.*?\*/!s', '', $configRaw);
$config = json_decode($configRaw, true);
if (!is_array($config)) {
    $config = [];
}

function ue_out($arr)
{
    echo json_encode($arr, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
    exit;
}

function ue_detect_mime($path)
{
    $finfo = finfo_open(FILEINFO_MIME_TYPE);
    if (!$finfo) {
        return '';
    }
    $mime = (string) finfo_file($finfo, $path);
    finfo_close($finfo);
    return strtolower($mime);
}

if ($action === 'config') {
    ue_out($config);
}

if (!cmsValidateAdminSession() || empty($_SESSION['admin_id'])) {
    http_response_code(401);
    ue_out(['state' => '请先登录后台后再上传']);
}

$ueDb = \Core\Db\DB::getInstance();
if (!cmsAdminCan(cmsLoadCurrentAdminAccess($ueDb), 'upload')) {
    http_response_code(403);
    ue_out(['state' => '当前角色没有内容上传权限']);
}

if ($_SERVER['REQUEST_METHOD'] === 'POST' && !verifyAdminCsrfToken()) {
    http_response_code(403);
    ue_out(['state' => '上传请求校验失败，请刷新页面后重试']);
}

$map = [
    'uploadimage' => ['field' => $config['imageFieldName'] ?? 'upfile', 'dir' => '/uploads/' . date('Ymd') . '/', 'types' => ['png', 'jpg', 'jpeg', 'gif', 'bmp', 'webp', 'ico'], 'max' => 10 * 1024 * 1024],
    'uploadscrawl' => ['field' => $config['scrawlFieldName'] ?? 'upfile', 'dir' => '/uploads/' . date('Ymd') . '/', 'types' => ['png'], 'max' => 10 * 1024 * 1024],
    'uploadvideo' => ['field' => $config['videoFieldName'] ?? 'upfile', 'dir' => '/uploads/video/' . date('Ym') . '/', 'types' => ['mkv', 'avi', 'mpeg', 'mpg', 'ogg', 'ogv', 'mov', 'wmv', 'mp4', 'webm', 'mp3', 'wav'], 'max' => 100 * 1024 * 1024],
    'uploadfile' => ['field' => $config['fileFieldName'] ?? 'upfile', 'dir' => '/uploads/file/' . date('Ym') . '/', 'types' => ['png', 'jpg', 'jpeg', 'gif', 'bmp', 'ico', 'webp', 'mkv', 'avi', 'mpeg', 'mpg', 'ogg', 'ogv', 'mov', 'wmv', 'mp4', 'webm', 'mp3', 'wav', 'rar', 'zip', 'tar', 'gz', '7z', 'bz2', 'doc', 'docx', 'xls', 'xlsx', 'ppt', 'pptx', 'pdf', 'txt', 'md'], 'max' => 50 * 1024 * 1024],
];

if ($action === 'listimage' || $action === 'listfile') {
    $isImage = $action === 'listimage';
    $baseRel = $isImage ? '/uploads/' : '/uploads/file/';
    $baseAbs = dirname(dirname(dirname(__DIR__))) . $baseRel;
    $allow = $isImage
        ? ['png', 'jpg', 'jpeg', 'gif', 'bmp', 'ico', 'webp']
        : ['png', 'jpg', 'jpeg', 'gif', 'bmp', 'ico', 'webp', 'mkv', 'avi', 'mpeg', 'mpg', 'ogg', 'ogv', 'mov', 'wmv', 'mp4', 'webm', 'mp3', 'wav', 'rar', 'zip', 'tar', 'gz', '7z', 'bz2', 'doc', 'docx', 'xls', 'xlsx', 'ppt', 'pptx', 'pdf', 'txt', 'md'];
    $files = [];
    if (is_dir($baseAbs)) {
        $it = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($baseAbs, FilesystemIterator::SKIP_DOTS));
        foreach ($it as $f) {
            if (!$f->isFile()) {
                continue;
            }
            $ext = strtolower(pathinfo($f->getFilename(), PATHINFO_EXTENSION));
            if (!in_array($ext, $allow, true)) {
                continue;
            }
            $full = str_replace('\\', '/', $f->getPathname());
            $root = str_replace('\\', '/', dirname(dirname(dirname(__DIR__))));
            $url = str_replace($root, '', $full);
            $files[] = ['url' => $url, 'mtime' => $f->getMTime()];
        }
    }
    usort($files, function ($a, $b) {
        return $b['mtime'] - $a['mtime'];
    });
    ue_out(['state' => 'SUCCESS', 'list' => $files, 'start' => 0, 'total' => count($files)]);
}

if (!isset($map[$action])) {
    ue_out(['state' => '请求地址出错']);
}

$rule = $map[$action];
$field = $rule['field'];

if ($action === 'uploadscrawl' && !empty($_POST[$field])) {
    $img = $_POST[$field];
    $img = preg_replace('#^data:image/\w+;base64,#i', '', $img);
    $binary = base64_decode($img, true);
    if (!$binary || strlen($binary) > $rule['max'] || @getimagesizefromstring($binary) === false) {
        ue_out(['state' => '涂鸦内容为空']);
    }
    $dirRel = $rule['dir'];
    $dirAbs = dirname(dirname(dirname(__DIR__))) . $dirRel;
    if (!is_dir($dirAbs)) {
        mkdir($dirAbs, 0755, true);
    }
    $name = uniqid() . '_' . time() . '.png';
    $path = $dirAbs . $name;
    file_put_contents($path, $binary);
    ue_out(['state' => 'SUCCESS', 'url' => $dirRel . $name, 'title' => $name, 'original' => 'scrawl.png']);
}

if (empty($_FILES[$field])) {
    ue_out(['state' => '没有上传文件']);
}

$file = $_FILES[$field];
if ($file['error'] !== UPLOAD_ERR_OK) {
    ue_out(['state' => '上传失败']);
}
if ($file['size'] > $rule['max']) {
    ue_out(['state' => '文件大小超限']);
}

$ext = strtolower(pathinfo($file['name'], PATHINFO_EXTENSION));
if (!in_array($ext, $rule['types'], true)) {
    ue_out(['state' => '文件格式不允许']);
}

$mime = ue_detect_mime($file['tmp_name']);
$imageMimes = ['image/jpeg', 'image/png', 'image/gif', 'image/webp', 'image/bmp', 'image/x-ms-bmp', 'image/x-icon', 'image/vnd.microsoft.icon'];
$videoMimes = ['video/x-matroska', 'video/x-msvideo', 'video/mpeg', 'video/ogg', 'video/quicktime', 'video/x-ms-wmv', 'video/mp4', 'video/webm', 'audio/mpeg', 'audio/wav', 'audio/x-wav', 'audio/ogg'];
$documentMimes = [
    'application/pdf', 'text/plain', 'text/markdown', 'application/zip', 'application/x-zip-compressed',
    'application/x-rar', 'application/vnd.rar', 'application/x-7z-compressed', 'application/gzip',
    'application/x-gzip', 'application/x-tar', 'application/msword',
    'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
    'application/vnd.ms-excel', 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
    'application/vnd.ms-powerpoint', 'application/vnd.openxmlformats-officedocument.presentationml.presentation',
];
if (($action === 'uploadimage' && !in_array($mime, $imageMimes, true))
    || ($action === 'uploadvideo' && !in_array($mime, $videoMimes, true))
    || ($action === 'uploadfile' && !in_array($mime, array_merge($imageMimes, $videoMimes, $documentMimes), true))) {
    ue_out(['state' => '文件内容与格式不匹配']);
}

$dirRel = $rule['dir'];
$dirAbs = dirname(dirname(dirname(__DIR__))) . $dirRel;
if (!is_dir($dirAbs)) {
    mkdir($dirAbs, 0755, true);
}

if ($action === 'uploadimage') {
    $saveResult = cmsStoreUploadedImage($file['tmp_name'], $file['name'], rtrim($dirAbs, '/\\'), 'ueditor', ['apply_watermark' => true]);
    if (!$saveResult['success']) {
        ue_out(['state' => '保存文件失败']);
    }
    $name = $saveResult['filename'];
} else {
    $name = uniqid() . '_' . time() . '.' . $ext;
    $dest = $dirAbs . $name;
    if (!move_uploaded_file($file['tmp_name'], $dest)) {
        ue_out(['state' => '保存文件失败']);
    }
}

ue_out(['state' => 'SUCCESS', 'url' => $dirRel . $name, 'title' => $name, 'original' => $file['name']]);
