<?php
declare(strict_types=1);

function h(?string $s): string {
  return htmlspecialchars((string)$s, ENT_QUOTES, 'UTF-8');
}

function money(float $n): string {
  return number_format($n, 2, '.', ',');
}

function json_out(array $payload, int $code=200): void {
  http_response_code($code);
  header('Content-Type: application/json');
  echo json_encode($payload);
  exit;
}

function is_ajax(): bool {
  return (isset($_SERVER['HTTP_X_REQUESTED_WITH']) && strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) === 'xmlhttprequest')
      || (isset($_GET['_partial']) && $_GET['_partial'] === '1');
}

function require_post(): void {
  if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
    http_response_code(405);
    exit;
  }
}

function next_number(PDO $db, string $sequence): string {
  // Simple sequence table approach
  $db->exec("INSERT IGNORE INTO sequences(name, current_value) VALUES (" . $db->quote($sequence) . ", 0)");
  $db->beginTransaction();
  $stmt = $db->prepare("UPDATE sequences SET current_value = LAST_INSERT_ID(current_value + 1) WHERE name=?");
  $stmt->execute([$sequence]);
  $stmt = $db->query("SELECT LAST_INSERT_ID() AS v");
  $v = (int)$stmt->fetch()['v'];
  $db->commit();
  return str_pad((string)$v, 6, '0', STR_PAD_LEFT);
}

function recaptcha_verify(string $secret, string $token, string $remoteIp): bool {
  if ($secret === 'PUT_YOUR_SECRET_KEY_HERE') return true; // dev convenience
  $ch = curl_init('https://www.google.com/recaptcha/api/siteverify');
  curl_setopt_array($ch, [
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_POST => true,
    CURLOPT_POSTFIELDS => http_build_query([
      'secret' => $secret,
      'response' => $token,
      'remoteip' => $remoteIp,
    ]),
    CURLOPT_TIMEOUT => 10,
  ]);
  $resp = curl_exec($ch);
  curl_close($ch);
  if (!$resp) return false;
  $data = json_decode($resp, true);
  return is_array($data) && !empty($data['success']);
}
