<?php
declare(strict_types=1);

header("Content-Type: application/json; charset=UTF-8");

if ($_SERVER["REQUEST_METHOD"] !== "POST") {
    http_response_code(405);
    echo json_encode([
        "ok" => false,
        "message" => "Метод не поддерживается",
    ], JSON_UNESCAPED_UNICODE);
    exit;
}

function respondError(string $message, int $code = 400): void
{
    http_response_code($code);
    echo json_encode([
        "ok" => false,
        "message" => $message,
    ], JSON_UNESCAPED_UNICODE);
    exit;
}

function sanitizeInput(string $value): string
{
    $clean = trim($value);
    return preg_replace("/[\\x00-\\x1F\\x7F]/u", "", $clean) ?? "";
}

function respondSuccess(): void
{
    echo json_encode([
        "ok" => true,
    ], JSON_UNESCAPED_UNICODE);
    exit;
}

function loadRateLimitState(string $filePath): array
{
    if (!is_file($filePath)) {
        return [];
    }
    $raw = file_get_contents($filePath);
    if ($raw === false || $raw === "") {
        return [];
    }
    $data = json_decode($raw, true);
    return is_array($data) ? $data : [];
}

function storeRateLimitState(string $filePath, array $state): void
{
    $encoded = json_encode($state, JSON_UNESCAPED_UNICODE);
    if ($encoded === false) {
        return;
    }
    @file_put_contents($filePath, $encoded, LOCK_EX);
}

function isRateLimited(string $ip, int $nowTs): bool
{
    $limitWindowSeconds = 10 * 60; // 10 минут
    $limitAttempts = 8;
    $rateFile = rtrim(sys_get_temp_dir(), DIRECTORY_SEPARATOR) . DIRECTORY_SEPARATOR . "frieze_spb_rate_limit.json";

    $state = loadRateLimitState($rateFile);
    $freshState = [];

    foreach ($state as $storedIp => $timestamps) {
        if (!is_array($timestamps)) {
            continue;
        }
        $validTs = [];
        foreach ($timestamps as $ts) {
            $intTs = (int)$ts;
            if ($intTs >= $nowTs - $limitWindowSeconds) {
                $validTs[] = $intTs;
            }
        }
        if ($validTs) {
            $freshState[$storedIp] = $validTs;
        }
    }

    $currentIpHits = $freshState[$ip] ?? [];
    if (count($currentIpHits) >= $limitAttempts) {
        storeRateLimitState($rateFile, $freshState);
        return true;
    }

    $currentIpHits[] = $nowTs;
    $freshState[$ip] = $currentIpHits;
    storeRateLimitState($rateFile, $freshState);
    return false;
}

$name = sanitizeInput((string)($_POST["name"] ?? ""));
$phoneRaw = sanitizeInput((string)($_POST["phone"] ?? ""));
$consent = (string)($_POST["consent"] ?? "");
$honeypot = sanitizeInput((string)($_POST["contact_fax"] ?? ($_POST["website"] ?? "")));
$startedAtRaw = sanitizeInput((string)($_POST["started_at"] ?? ""));

if ($honeypot !== "") {
    respondError("Не удалось отправить заявку. Пожалуйста, попробуйте еще раз.", 400);
}

$nowTs = time();
$formMinFillSeconds = 0.4;
$startedAtMs = (int)$startedAtRaw;
if ($startedAtMs > 0) {
    $elapsedSeconds = ((int)floor(microtime(true) * 1000) - $startedAtMs) / 1000;
    if ($elapsedSeconds < $formMinFillSeconds) {
        respondError("Слишком быстрая отправка формы. Попробуйте еще раз.", 429);
    }
}

$clientIp = (string)($_SERVER["REMOTE_ADDR"] ?? "unknown");
if (isRateLimited($clientIp, $nowTs)) {
    respondError("Слишком много заявок за короткое время. Повторите попытку позже.", 429);
}

if ($name === "") {
    respondError("Укажите имя");
}

// Нормализуем имя: убираем лишние пробелы внутри.
$name = preg_replace("/\\s+/u", " ", $name) ?? $name;

if (mb_strlen($name) < 2 || mb_strlen($name) > 80) {
    respondError("Имя должно быть от 2 до 80 символов");
}

if (!preg_match("/^[\\p{L}\\s-]+$/u", $name)) {
    respondError("Имя может содержать только буквы, пробелы и дефис");
}

$phoneDigits = preg_replace("/\\D+/", "", $phoneRaw) ?? "";
if (strlen($phoneDigits) !== 11 || strpos($phoneDigits, "7") !== 0) {
    respondError("Укажите корректный телефон");
}

if ($consent !== "1") {
    respondError("Необходимо согласие на обработку данных");
}

// Укажите email в файле submit-config.php (предпочтительно для REG.RU)
// или в переменной окружения FORM_RECIPIENT_EMAIL.
$recipientEmail = "";
$senderEmail = "";
$configFile = __DIR__ . "/submit-config.php";
if (is_file($configFile)) {
    require $configFile;
}

if ($recipientEmail === "") {
    $recipientEmail = getenv("FORM_RECIPIENT_EMAIL") ?: "you@example.com";
}

if (substr($recipientEmail, -11) === "@example.com") {
    respondError("Не настроен email получателя заявок. Укажите адрес в submit-config.php.", 500);
}

$host = strtolower((string)($_SERVER["HTTP_HOST"] ?? "frieze-spb.ru"));
$host = preg_replace("/:\\d+$/", "", $host) ?? "frieze-spb.ru";
$host = preg_replace("/[^a-z0-9\\.-]/", "", $host) ?? "frieze-spb.ru";
if ($host === "") {
    $host = "frieze-spb.ru";
}
$defaultSenderEmail = "noreply@" . $host;
$fromEmail = $senderEmail !== "" ? $senderEmail : $defaultSenderEmail;
if (!filter_var($fromEmail, FILTER_VALIDATE_EMAIL)) {
    $fromEmail = $defaultSenderEmail;
}

$subject = "Новая заявка с сайта frieze-spb.ru";
$encodedSubject = "=?UTF-8?B?" . base64_encode($subject) . "?=";

$messageLines = [
    "Новая заявка с сайта",
    "",
    "Имя: " . $name,
    "Телефон: " . $phoneRaw,
    "Телефон (цифры): +" . $phoneDigits,
    "Дата/время: " . date("d.m.Y H:i:s"),
    "IP: " . (string)($_SERVER["REMOTE_ADDR"] ?? "не определен"),
    "User-Agent: " . (string)($_SERVER["HTTP_USER_AGENT"] ?? "не определен"),
];

$body = implode("\r\n", $messageLines);

$headers = [
    "MIME-Version: 1.0",
    "Content-Type: text/plain; charset=UTF-8",
    "From: Frieze Site <" . $fromEmail . ">",
    "Reply-To: " . $recipientEmail,
    "X-Mailer: PHP/" . PHP_VERSION,
];

$sent = mail($recipientEmail, $encodedSubject, $body, implode("\r\n", $headers), "-f" . $fromEmail);

if (!$sent) {
    respondError("Не удалось отправить заявку. Попробуйте позже или позвоните по телефону.", 500);
}

respondSuccess();
