<?php
/**
 * 编辑器图片上传端点（CKEditor 4 兼容）
 *
 * 支持两种上传方式：
 * - XHR 模式（filebrowserUploadMethod: 'xhr' + 拖拽/粘贴）：返回 JSON { uploaded, fileName, url }
 * - 经典表单模式（filebrowserUploadMethod: 'form' via CKEditorFuncNum）：返回 HTML script 回调
 *
 * 安全：
 * - 要求登录态
 * - 白名单扩展名 + MIME 校验
 * - 限制 5MB
 * - 随机化文件名，按月份分目录，防止目录穿越
 */
require __DIR__ . '/../../app/bootstrap.php';
require __DIR__ . '/../../app/database.php';
require_login();

$maxBytes = 5 * 1024 * 1024;
$allowedExt = array('jpg', 'jpeg', 'png', 'gif', 'webp');
$allowedMime = array(
    'image/jpeg' => array('jpg', 'jpeg'),
    'image/png' => array('png'),
    'image/gif' => array('gif'),
    'image/webp' => array('webp')
);

$funcNum = isset($_GET['CKEditorFuncNum']) ? (int)$_GET['CKEditorFuncNum'] : 0;
$isFormMode = $funcNum > 0;

function editor_upload_respond($isFormMode, $funcNum, $url, $message, $ok)
{
    if ($isFormMode) {
        header('Content-Type: text/html; charset=utf-8');
        $safeUrl = addslashes($url);
        $safeMsg = addslashes($message);
        echo '<script>window.parent.CKEDITOR.tools.callFunction(' . (int)$funcNum . ', "' . $safeUrl . '", "' . $safeMsg . '");</script>';
        exit;
    }
    header('Content-Type: application/json; charset=utf-8');
    header('Cache-Control: no-store');
    if ($ok) {
        echo json_encode(array(
            'uploaded' => 1,
            'fileName' => basename($url),
            'url' => $url
        ), JSON_UNESCAPED_UNICODE);
    } else {
        echo json_encode(array(
            'uploaded' => 0,
            'error' => array('message' => $message)
        ), JSON_UNESCAPED_UNICODE);
    }
    exit;
}

try {
    if (empty($_FILES) || (!isset($_FILES['upload']) && !isset($_FILES['file']))) {
        throw new Exception('未接收到图片文件。');
    }
    $file = isset($_FILES['upload']) ? $_FILES['upload'] : $_FILES['file'];

    if (!isset($file['error']) || $file['error'] !== UPLOAD_ERR_OK) {
        $errMsg = '文件上传失败（错误码：' . (isset($file['error']) ? (int)$file['error'] : -1) . '）';
        if (isset($file['error']) && $file['error'] === UPLOAD_ERR_INI_SIZE) {
            $errMsg = '图片过大，超出服务器 upload_max_filesize 限制。';
        }
        throw new Exception($errMsg);
    }
    if (!isset($file['size']) || (int)$file['size'] <= 0) {
        throw new Exception('文件内容为空。');
    }
    if ((int)$file['size'] > $maxBytes) {
        throw new Exception('图片大小超出 5MB 限制。');
    }
    if (!is_uploaded_file($file['tmp_name'])) {
        throw new Exception('非法的上传请求。');
    }

    $originalName = isset($file['name']) ? (string)$file['name'] : 'upload';
    $ext = strtolower(pathinfo($originalName, PATHINFO_EXTENSION));
    if (!in_array($ext, $allowedExt, true)) {
        throw new Exception('仅支持 jpg / jpeg / png / gif / webp 图片。');
    }

    // MIME 检测
    $detectedMime = '';
    if (function_exists('finfo_open')) {
        $finfo = finfo_open(FILEINFO_MIME_TYPE);
        if ($finfo) {
            $detectedMime = (string)finfo_file($finfo, $file['tmp_name']);
            finfo_close($finfo);
        }
    }
    if ($detectedMime === '' && function_exists('getimagesize')) {
        $imgInfo = @getimagesize($file['tmp_name']);
        if (is_array($imgInfo) && isset($imgInfo['mime'])) {
            $detectedMime = (string)$imgInfo['mime'];
        }
    }
    if ($detectedMime === '' || !isset($allowedMime[$detectedMime])) {
        throw new Exception('文件 MIME 类型不被允许。');
    }
    if (!in_array($ext, $allowedMime[$detectedMime], true)) {
        $ext = $allowedMime[$detectedMime][0];
    }

    // 解析目标域名（优先 GET/POST 参数 domain_id），将图片保存到该域名的 site_root/uploads
    $domainId = 0;
    if (isset($_GET['domain_id'])) { $domainId = (int)$_GET['domain_id']; }
    if (!$domainId && isset($_POST['domain_id'])) { $domainId = (int)$_POST['domain_id']; }

    $targetDomain = null;
    $targetSiteRoot = '';
    $targetHost = '';
    if ($domainId > 0) {
        $domainRow = find_domain_by_id($domainId);
        if ($domainRow && isset($domainRow['status']) && $domainRow['status'] === 'enabled') {
            $candidateRoot = domain_static_site_root($domainRow);
            if ($candidateRoot !== '' && is_dir($candidateRoot) && is_writable($candidateRoot)) {
                $targetDomain = $domainRow;
                $targetSiteRoot = $candidateRoot;
                $targetHost = isset($domainRow['domain']) ? trim((string)$domainRow['domain']) : '';
            }
        }
    }

    $relativeDir = 'uploads/' . date('Ym');
    if ($targetSiteRoot !== '') {
        $absoluteDir = $targetSiteRoot . '/' . $relativeDir;
    } else {
        $absoluteDir = dirname(__DIR__, 2) . '/' . $relativeDir;
    }
    if (!is_dir($absoluteDir)) {
        @mkdir($absoluteDir, 0755, true);
    }
    if (!is_dir($absoluteDir) || !is_writable($absoluteDir)) {
        throw new Exception('上传目录不可写，请检查目标域名 uploads 目录权限。');
    }

    $randomName = 'img-' . date('YmdHis') . '-' . bin2hex(random_bytes(4)) . '.' . $ext;
    $absolutePath = $absoluteDir . '/' . $randomName;
    if (!move_uploaded_file($file['tmp_name'], $absolutePath)) {
        throw new Exception('图片保存失败。');
    }

    $relativePath = $relativeDir . '/' . $randomName;
    if ($targetHost !== '') {
        $scheme = (stripos($targetHost, 'http') === 0) ? '' : 'https';
        $publicUrl = ($scheme === '' ? $targetHost : $scheme . '://' . $targetHost) . '/' . $relativePath;
    } else {
        $publicUrl = '/' . $relativePath;
    }
    editor_upload_respond($isFormMode, $funcNum, $publicUrl, '上传成功', true);
} catch (Exception $e) {
    editor_upload_respond($isFormMode, $funcNum, '', $e->getMessage(), false);
}
