<?php
session_start();

function sanitize_text(string $name, string $type) {
    $filters = array(
        'text' => FILTER_SANITIZE_SPECIAL_CHARS,
        'email' => FILTER_SANITIZE_EMAIL,
    );
    $text = filter_var(trim($_POST[$name]), $filters[$type]);
    $text = stripslashes($text);

    return $text;
}

function prepare_message_body(string $message, string $name) {
    // Replace HTML-Entities with actual carriage returns and line feeds
    $message = str_replace("&#13;", "\r", $message);
    $message = str_replace("&#10;", "\n", $message);

    // Ensure line breaks via carriage return + line feed
    $message = str_replace("\r\n", "\n", $message);
    $message = str_replace("\n", "\r\n", $message);

    $message = "Nachricht von: $name\r\n\r\n" . $message;
    $message = base64_encode($message);

    return $message;
}

/**
 *  Sending email
 *
 *  mail(): Braucht auf dem Server einen korrekt konfigurierten Mailserver
 *  phpmailer: Bibliothek, der per Composer installiert wird. Tut ganz gut mit SMTP.
 */
function send_message_to_office(string $subject, string $message, string $name, string $email) {
    $returnPath = filter_var(getenv('WTF_RETURN_PATH'), FILTER_VALIDATE_EMAIL);
    $to = filter_var(getenv('WTF_CONTACT_TO'), FILTER_VALIDATE_EMAIL);

    if (!$returnPath || !$to) {
        error_log('Address for "To" or "Return-Path" is invalid');
        return false;
    }

    return mail(
        $to,
        "=?UTF-8?B?" . base64_encode($subject) . "?=",
        prepare_message_body($message, $name),
        array(
            "From" => getenv('WTF_CONTACT_FROM'),
            "Reply-To" => $email,
            "Content-Type" => "text/plain; charset=utf-8",
            "Content-Transfer-Encoding" => "base64",
        ),
        "-f $returnPath"
    );
}

function send_response(array $response_data) {
    $json = json_encode($response_data);
    if ($json === false) {
        // Avoid echo of empty string (which is invalid JSON), and
        // JSONify the error message instead:
        $json = json_encode(["jsonError" => json_last_error_msg()]);
        if ($json === false) {
            // This should not happen, but …
            $json = '{"jsonError":"unknown"}';
        }
        // Set HTTP response status code to: 500 - Internal Server Error
        http_response_code(500);
    }
    header('Content-type: application/json');
    echo $json;
}

function prepare_response() {
    $response = array();

    if (empty($_POST['message'])) {
        $response['errors'][] = 'Sie haben keine Nachricht eingegeben.';
    }
    if (empty($_POST['email'])) {
        $response['errors'][] = 'Sie haben keine E-Mail-Adresse eingegeben.';
    }
    if (empty($_POST['name'])) {
        $response['errors'][] = 'Sie haben keinen Namen eingegeben.';
    }
    if (empty($_POST['subject'])) {
        $response['errors'][] = 'Sie haben keinen Betreff eingegeben.';
    }
    /**
     * Idee zur Bot-Erkennung:
     * 1. Ein Bot hat das Pseudocaptcha entweder leer abgeschickt, oder sich selbst etwas ausgedacht.
     * 2. Ein Bot schickt die Daten in unter 5s ab.
     * 3. Ein Mensch braucht nicht länger als 60min.
     */
    if (
        $_POST['captcha'] != 'Nudelsuppe' or
        time() - $_SESSION['start_time'] < 5 or
        time() - $_SESSION['start_time'] > 3600
    ) {
        $response['errors'][] = 'Wir glauben Sie sind ein Bot.';
    }
    if (!array_key_exists('errors', $response)) {
        $subject = sanitize_text('subject', 'text');
        $message = sanitize_text('message', 'text');
        $name = sanitize_text('name', 'text');
        $email = sanitize_text('email', 'email');

        if (!send_message_to_office($subject, $message, $name, $email)) {
            $response['errors'][] = 'Ihre Nachricht konnte nicht übermittelt werden.';
        } else {
            $response['status'] = 'ok';
        }
    }
    return $response;
}

if ($_SERVER["REQUEST_METHOD"] == "POST") {
    $response = array();

    if (empty($_POST['action'])){
        $response['errors'][] = 'Kann eigentlich nicht passieren :/';
    } else {
        if ($_POST['action'] == 'start_session') {
            $_SESSION['start_time'] = time();
            // $response['session_start_time'] = $_SESSION['start_time'];
            // $response['session_id_before'] = session_id();
        } elseif ($_POST['action'] == 'handle_form') {
            $response = prepare_response();
            session_destroy();
        } else {
            $response['errors'][] = 'Kann eigentlich auch nicht passieren :/';
        }
    }
    send_response($response);
} else {
    http_response_code(404);
}