<?php
// =========================================================================
// Drop 站点 — 纯留言 API (v4.0: 已移除文件上传功能)
// =========================================================================
ini_set('session.cookie_httponly', 1);
ini_set('session.cookie_secure', 1);
ini_set('session.cookie_samesite', 'Strict');
ini_set('session.use_strict_mode', 1);

session_start();

// --- 统一配置区 ---
$COMMENT_LOG_FILE   = '/home/picatria_uploads/comments.org';
$MAX_COMMENT_LENGTH = 500;

// --- 留言速率限制 ---
$RL_COMMENT_LOG    = '/home/picatria_uploads/rl_comment.log';
$RL_COMMENT_WINDOW = 300;
$RL_COMMENT_MAX    = 10;
$RL_COMMENT_DAILY  = 50;

// --- 验证码速率限制（防刷 Session）---
$RL_CAPTCHA_LOG    = '/home/picatria_uploads/rl_captcha.log';
$RL_CAPTCHA_WINDOW = 60;
$RL_CAPTCHA_MAX    = 30;
$RL_CAPTCHA_DAILY  = 200;

// --- POST body 上限（留言只需 ~300 字节，2KB 足够）---
$MAX_POST_BODY = 2048;

// =========================================================================
// --- 通用安全响应头 ---
// =========================================================================
function send_common_security_headers(): void {
    header('X-Content-Type-Options: nosniff');
    header('X-Frame-Options: DENY');
    header('Referrer-Policy: strict-origin-when-cross-origin');
    header('Permissions-Policy: geolocation=(), camera=(), microphone=()');
}

// =========================================================================
// --- 通用速率限制检查器 ---
// =========================================================================
function check_rate_limit(
    string $logFile,
    int    $window,
    int    $maxRequests,
    int    $dailyMax
): array {
    $ip    = $_SERVER['REMOTE_ADDR'];
    $now   = time();
    $today = date('Y-m-d');
    $reqInWindow = 0;
    $reqToday    = 0;

    if (!file_exists($logFile)) {
        touch($logFile);
    }

    $fp = fopen($logFile, 'c+');
    if (!$fp || !flock($fp, LOCK_EX)) {
        return ['allowed' => false, 'msg' => 'Server Busy'];
    }

    $lines = [];
    while (($line = fgets($fp)) !== false) {
        $parts = explode('|', trim($line));
        if (count($parts) !== 3) continue;
        [$entry_ip, $entry_time, $entry_date] = $parts;
        if (($now - $entry_time) < $window || $entry_date === $today) {
            $lines[] = $line;
            if ($entry_ip === $ip) {
                if (($now - $entry_time) < $window) $reqInWindow++;
                if ($entry_date === $today) $reqToday++;
            }
        }
    }

    if ($reqInWindow >= $maxRequests) {
        flock($fp, LOCK_UN);
        fclose($fp);
        return ['allowed' => false, 'msg' => "操作过于频繁，请等待 " . ceil($window / 60) . " 分钟"];
    }
    if ($reqToday >= $dailyMax) {
        flock($fp, LOCK_UN);
        fclose($fp);
        return ['allowed' => false, 'msg' => '今日操作次数已达上限'];
    }

    $lines[] = "$ip|$now|$today\n";
    ftruncate($fp, 0);
    rewind($fp);
    foreach ($lines as $l) fwrite($fp, $l);
    flock($fp, LOCK_UN);
    fclose($fp);

    return ['allowed' => true];
}

// =========================================================================
// --- CORS ---
// =========================================================================
$ALLOWED_ORIGINS = [
    'https://picatria.cn',
    'https://www.picatria.cn',
    'https://drop.picatria.cn',
    'http://localhost',
    'http://localhost:3000',
];

$origin = $_SERVER['HTTP_ORIGIN'] ?? '';
if (in_array($origin, $ALLOWED_ORIGINS, true)) {
    header("Access-Control-Allow-Origin: $origin");
    header('Access-Control-Allow-Credentials: true');
    header('Access-Control-Allow-Headers: Content-Type');
    header('Access-Control-Allow-Methods: GET, POST, OPTIONS');
}

if ($_SERVER['REQUEST_METHOD'] === 'OPTIONS') {
    send_common_security_headers();
    http_response_code(204);
    exit;
}

// =========================================================================
// --- [GET] 验证码 ---
// =========================================================================
if ($_SERVER['REQUEST_METHOD'] === 'GET'
    && ($_GET['action'] ?? '') === 'get_captcha'
) {
    send_common_security_headers();
    header('Content-Type: application/json; charset=utf-8');
    header('Cache-Control: no-store');

    // 验证码速率限制：防止恶意刷 Session
    $limit = check_rate_limit($RL_CAPTCHA_LOG, $RL_CAPTCHA_WINDOW, $RL_CAPTCHA_MAX, $RL_CAPTCHA_DAILY);
    if (!$limit['allowed']) {
        echo json_encode(['status' => 'error', 'msg' => '⛔ ' . $limit['msg'], 'delay' => 30]);
        exit;
    }

    $num1 = random_int(1, 10);
    $num2 = random_int(1, 10);
    $_SESSION['captcha_answer'] = $num1 + $num2;
    $_SESSION['captcha_time']   = time();
    echo json_encode(['question' => "$num1 + $num2 = ?"]);
    exit;
}

// =========================================================================
// --- [POST] 留言 ---
// =========================================================================
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
    send_common_security_headers();
    header('Content-Type: application/json; charset=utf-8');
    header('Cache-Control: no-store');

    // 拒绝超大 payload，仅允许小文本留言
    $contentLength = (int)($_SERVER['CONTENT_LENGTH'] ?? 0);
    if ($contentLength > $MAX_POST_BODY) {
        echo json_encode(['status' => 'error', 'msg' => '❌ 请求体过大', 'delay' => 10]);
        exit;
    }

    $rawBody   = file_get_contents('php://input', false, null, 0, $MAX_POST_BODY + 1);
    $jsonInput = json_decode($rawBody, true) ?: [];
    $action    = $_POST['action'] ?? $jsonInput['action'] ?? '';

    if ($action === 'comment') {
        $limit = check_rate_limit($RL_COMMENT_LOG, $RL_COMMENT_WINDOW, $RL_COMMENT_MAX, $RL_COMMENT_DAILY);
        if (!$limit['allowed']) {
            echo json_encode(['status' => 'error', 'msg' => '⛔ ' . $limit['msg'], 'delay' => 60]);
            exit;
        }

        $message     = $jsonInput['message'] ?? '';
        $userCaptcha = $jsonInput['captcha'] ?? null;

        $raw_url = $jsonInput['pageUrl'] ?? '';
        // 支持完整 URL 和纯路径（如 "test_math_intro/"）
        $url = filter_var($raw_url, FILTER_VALIDATE_URL);
        if ($url && in_array(parse_url($url, PHP_URL_SCHEME), ['http', 'https'], true)) {
            $pageUrl = mb_substr(str_replace(["\n", "\r"], '', $url), 0, 200);
        } else {
            $pageUrl = mb_substr(preg_replace('/[^\w\/\._\-]/', '', str_replace(["\n", "\r"], '', $raw_url)), 0, 200);
            if ($pageUrl === '') {
                $pageUrl = 'N/A';
            }
        }

        $expectedAnswer = $_SESSION['captcha_answer'] ?? null;
        $captchaTime    = $_SESSION['captcha_time']   ?? 0;
        unset($_SESSION['captcha_answer'], $_SESSION['captcha_time']);

        if (empty($message)) {
            $resp = ['msg' => '❌ 留言内容不能为空', 'delay' => 3];
        } elseif (mb_strlen($message, 'UTF-8') > $MAX_COMMENT_LENGTH) {
            $resp = ['msg' => '❌ 留言内容超过限制', 'delay' => 3];
        } elseif ($expectedAnswer === null || (time() - $captchaTime) > 600) {
            $resp = ['msg' => '❌ 验证码已过期', 'delay' => 3];
        } elseif ((int)$userCaptcha !== $expectedAnswer) {
            $resp = ['msg' => '❌ 计算错误', 'delay' => 5];
        } else {
            $date_str      = date('Y-m-d D H:i');
            $ip_address    = $_SERVER['REMOTE_ADDR'];
            $clean_message = trim($message);
            $clean_message = preg_replace('/^(\*+|\s*#\+)/m', '/$1', $clean_message);

            $org_entry  = "* [{$date_str}] 来自 {$ip_address} 的留言\n";
            $org_entry .= ":PROPERTIES:\n";
            $org_entry .= ":IP: {$ip_address}\n";
            $org_entry .= ":URL: {$pageUrl}\n";
            $org_entry .= ":END:\n";
            $org_entry .= "#+begin_quote\n{$clean_message}\n#+end_quote\n\n";

            $resp = file_put_contents($COMMENT_LOG_FILE, $org_entry, FILE_APPEND | LOCK_EX) !== false
                ? ['status' => 'success', 'msg' => '✅ 留言成功']
                : ['msg' => '❌ 内部存储错误', 'delay' => 5];
        }

        echo json_encode($resp ?? ['status' => 'error', 'msg' => '未知错误']);
        exit;
    }

    // 未知 action（包括已移除的 upload）
    echo json_encode(['status' => 'error', 'msg' => 'Invalid Action']);
    exit;
}

// =========================================================================
// --- 其他 GET 请求：返回简洁状态页 ---
// =========================================================================
send_common_security_headers();
header('Content-Type: text/plain; charset=utf-8');
header('Cache-Control: no-store');
echo "Drop API v4.0 — Comment endpoint only.\n";
