<?php
/**
 * Big Breathe — contact form handler.
 * POST JSON to /api/contact — rate-limited, honeypot-checked.
 */

declare(strict_types=1);

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

$SEND_FROM_EMAIL  = getenv('SEND_FROM_EMAIL')  ?: 'noreply@bigbreathe.com';
$SEND_TO_EMAIL    = getenv('SEND_TO_EMAIL')    ?: '';
$SEND_FROM_DOMAIN = getenv('SEND_FROM_DOMAIN') ?: 'bigbreathe.com';
$RESEND_API_KEY   = getenv('RESEND_API_KEY')   ?: '';
$RECAPTCHA_SECRET = getenv('RECAPTCHA_SECRET_KEY') ?: '';
$RATE_LIMIT       = (int)(getenv('RATE_LIMIT_PER_IP_PER_10MIN') ?: 5);
$SCORE_PASS       = (float)(getenv('SCORE_PASS') ?: 0.7);
$SCORE_REVIEW     = (float)(getenv('SCORE_REVIEW') ?: 0.4);
$TIME_MIN_SECONDS = (int)(getenv('TIME_MIN_SECONDS') ?: 3);
$FROM_HEADER      = sprintf('Big Breathe <%s>', $SEND_FROM_EMAIL);

function send_json(array $data, int $status = 200): void {
    http_response_code($status);
    echo json_encode($data, JSON_UNESCAPED_SLASHES);
    exit;
}
function fail(string $msg, int $status = 200): void { send_json(['ok' => false, 'error' => $msg], $status); }

function client_ip(): string {
    $trust = (getenv('TRUST_PROXY') === '1');
    if ($trust) { $fwd = $_SERVER['HTTP_X_FORWARDED_FOR'] ?? ''; if ($fwd) return trim(explode(',', $fwd)[0]); }
    return $_SERVER['REMOTE_ADDR'] ?? 'unknown';
}

function rate_limit_check(string $ip, int $max, int $window): bool {
    $dir = sys_get_temp_dir() . '/bb-rl';
    if (!is_dir($dir)) @mkdir($dir, 0700, true);
    $file = $dir . '/' . preg_replace('/[^a-zA-Z0-9._:-]/', '_', $ip);
    $now = time();
    $events = [];
    if (is_file($file)) {
        $raw = @file_get_contents($file);
        $events = $raw ? array_filter(array_map('intval', explode("\n", $raw))) : [];
        $events = array_filter($events, fn($t) => $now - $t <= $window);
    }
    if (count($events) >= $max) return false;
    $events[] = $now;
    @file_put_contents($file, implode("\n", $events), LOCK_EX);
    return true;
}

function http_post_json(string $url, array $headers, array $body, int $timeout = 15): array {
    $ch = curl_init($url);
    curl_setopt_array($ch, [
        CURLOPT_RETURNTRANSFER => true, CURLOPT_POST => true,
        CURLOPT_POSTFIELDS => json_encode($body, JSON_UNESCAPED_SLASHES),
        CURLOPT_HTTPHEADER => array_merge(['Content-Type: application/json'], $headers),
        CURLOPT_CONNECTTIMEOUT => 5, CURLOPT_TIMEOUT => $timeout,
    ]);
    $resp = curl_exec($ch); $code = curl_getinfo($ch, CURLINFO_HTTP_CODE); curl_close($ch);
    return ['status' => $code, 'body' => $resp];
}

function http_post_form(string $url, array $fields, int $timeout = 10): array {
    $ch = curl_init($url);
    curl_setopt_array($ch, [
        CURLOPT_RETURNTRANSFER => true, CURLOPT_POST => true,
        CURLOPT_POSTFIELDS => http_build_query($fields),
        CURLOPT_CONNECTTIMEOUT => 5, CURLOPT_TIMEOUT => $timeout,
    ]);
    $resp = curl_exec($ch); $code = curl_getinfo($ch, CURLINFO_HTTP_CODE); curl_close($ch);
    return ['status' => $code, 'body' => $resp];
}

if (($_SERVER['REQUEST_METHOD'] ?? 'GET') !== 'POST') fail('Method Not Allowed', 405);

$raw = ''; $in = fopen('php://input', 'rb');
if ($in) { $raw = stream_get_contents($in, 32769); fclose($in); }
if (strlen($raw) > 32768) fail('Payload too large.', 413);
$body = json_decode($raw, true);
if (!is_array($body)) fail('Invalid request payload.');

$request_id = bin2hex(random_bytes(6));
$ip = client_ip();

if (!rate_limit_check($ip, $RATE_LIMIT, 600)) {
    error_log("[bb.form] rate_limited request_id=$request_id ip=$ip");
    fail('Too many requests. Please wait a few minutes.', 429);
}

$name            = trim((string)($body['name']    ?? ''));
$email           = trim((string)($body['email']   ?? ''));
$reason          = trim((string)($body['reason']  ?? ''));
$message         = trim((string)($body['message'] ?? ''));
$website         = trim((string)($body['website'] ?? ''));
$form_loaded_at  = trim((string)($body['form_loaded_at'] ?? ''));
$recaptcha_token = trim((string)($body['recaptcha_token'] ?? ''));

$errors = [];
if (mb_strlen($name) < 2 || mb_strlen($name) > 80)      $errors[] = 'name';
if (!filter_var($email, FILTER_VALIDATE_EMAIL))          $errors[] = 'email';
if (mb_strlen($reason) < 1)                              $errors[] = 'reason';
if (mb_strlen($message) > 1000)                          $errors[] = 'message';
if ($errors) fail('Please check the form fields and try again.');

if ($website !== '') {
    error_log("[bb.form] honeypot_triggered request_id=$request_id ip=$ip");
    send_json(['ok' => true, 'ref' => $request_id]);
}

$flagged_review = false;
if ($form_loaded_at !== '' && ctype_digit(ltrim($form_loaded_at, '-'))) {
    $elapsed = (microtime(true) * 1000 - (int)$form_loaded_at) / 1000.0;
    if ($elapsed < $TIME_MIN_SECONDS) $flagged_review = true;
}

$score = 1.0;
if ($recaptcha_token !== '' && $RECAPTCHA_SECRET !== '') {
    $r = http_post_form('https://www.google.com/recaptcha/api/siteverify', ['secret' => $RECAPTCHA_SECRET, 'response' => $recaptcha_token]);
    $rj = json_decode($r['body'] ?? '', true) ?: [];
    if (empty($rj['success'])) fail('Could not verify the form. Please try again.');
    $score = (float)($rj['score'] ?? 0);
    if ($score < $SCORE_REVIEW) fail('Could not verify the form. Please try again.');
    if ($score < $SCORE_PASS) $flagged_review = true;
} else {
    $flagged_review = true;
}

$subject_name = preg_replace('/[\x00-\x1F\x7F]/u', ' ', $name);
$subject_prefix = $flagged_review ? '[REVIEW] ' : '';
$subject = "{$subject_prefix}New inquiry from {$subject_name}";
$text_body =
    "New inquiry from bigbreathe.com\n\n" .
    "Name: {$name}\nEmail: {$email}\nService: {$reason}\n\n" .
    "Message:\n" . ($message ?: '(none)') . "\n\n" .
    "reCAPTCHA score: {$score}\n" .
    "Submitted: " . gmdate('Y-m-d\TH:i:s\Z') . "\n" .
    "Request ID: {$request_id}\n";
$html_body = nl2br(htmlspecialchars($text_body, ENT_QUOTES, 'UTF-8'));

if ($RESEND_API_KEY !== '' && $SEND_TO_EMAIL !== '') {
    $r = http_post_json(
        'https://api.resend.com/emails',
        ["Authorization: Bearer {$RESEND_API_KEY}"],
        ['from' => $FROM_HEADER, 'to' => [$SEND_TO_EMAIL], 'reply_to' => $email, 'subject' => $subject, 'text' => $text_body, 'html' => $html_body]
    );
    if ($r['status'] >= 300) {
        error_log("[bb.form] resend_failed request_id=$request_id status={$r['status']}");
        fail('Could not send the message. Please email us directly.');
    }
    error_log("[bb.form] sent ok request_id=$request_id score=$score");

    http_post_json(
        'https://api.resend.com/emails',
        ["Authorization: Bearer {$RESEND_API_KEY}"],
        ['from' => $FROM_HEADER, 'to' => [$email], 'subject' => 'Your message reached Big Breathe',
         'text' => "Thank you for reaching out. We will be in touch within one to two business days.\n\nBig Breathe Yoga & Wellness\nbigbreathe.com",
         'html' => "<p>Thank you for reaching out. We will be in touch within one to two business days.</p><p>Big Breathe Yoga &amp; Wellness<br>bigbreathe.com</p>"]
    );
} else {
    error_log("[bb.form] no_key request_id=$request_id\nSubject: $subject\n$text_body");
}

send_json(['ok' => true, 'ref' => $request_id]);
