<?php
declare(strict_types=1);

/* ========= Session & Bootstrap ========= */
$secure = (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off');
session_set_cookie_params([
  'lifetime' => 0,
  'path' => '/',
  'secure' => $secure,
  'httponly' => true,
  'samesite' => 'Lax',
]);
session_name('WLISTSESSID');
session_start();
umask(0022); // neue Dateien: 0644, Ordner: 0755

require_once __DIR__ . '/config/config.php';

/* ===== Debug Toggle (wie item.php) ===== */
if (!empty($app_debug)) {
  ini_set('display_errors', '1');
  ini_set('display_startup_errors', '1');
  ini_set('log_errors', '1');
  if (!is_dir(__DIR__ . '/logs')) {
    @mkdir(__DIR__ . '/logs', 0750, true);
  }
  ini_set('error_log', __DIR__ . '/logs/php-error.log');
  error_reporting(E_ALL);
} else {
  ini_set('display_errors', '0');
  ini_set('display_startup_errors', '0');
  ini_set('log_errors', '1');
  if (!is_dir(__DIR__ . '/logs')) {
    @mkdir(__DIR__ . '/logs', 0750, true);
  }
  ini_set('error_log', __DIR__ . '/logs/php-error.log');
  error_reporting(E_ALL);
}

/* ============= Helpers ============= */
function fail(string $msg, int $code = 400): void
{
  http_response_code($code);
  // kleine Flash-Message für index.php
  $_SESSION['flash'] = ['msg' => $msg, 'type' => ($code >= 400 ? 'danger' : 'success')];
  safe_redirect_back();
}
function db(): mysqli
{
  global $servername, $username, $password, $db;
  $conn = new mysqli($servername, $username, $password, $db);
  if ($conn->connect_error)
    fail('Interner Fehler (DB)', 500);
  $conn->set_charset('utf8mb4');
  return $conn;
}
function require_csrf(): void
{
  $t = (string) ($_POST['csrf'] ?? '');
  if (empty($_SESSION['csrf']) || !hash_equals($_SESSION['csrf'], $t)) {
    fail('Ungültiges CSRF-Token', 403);
  }
}
function e(string $s): string
{
  return htmlspecialchars($s, ENT_QUOTES | ENT_SUBSTITUTE, 'UTF-8');
}
function safe_redirect_back(): void
{
  $ref = (string) ($_SERVER['HTTP_REFERER'] ?? '');
  if ($ref === '' || stripos($ref, 'http') !== 0) {
    $host = $_SERVER['HTTP_HOST'] ?? '';
    $scheme = (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off') ? 'https' : 'http';
    header('Location: ' . $scheme . '://' . $host . '/', true, 303);
  } else {
    header('Location: ' . $ref, true, 303);
  }
  exit;
}

/* ============= Controller ============= */

if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
  fail('Methode nicht erlaubt', 405);
}
require_csrf();

$wishId = (int) ($_POST['wishid'] ?? -1);
$pw = (string) ($_POST['WishPassword'] ?? '');
$reservedstat = (int) ($_POST['reservedstat'] ?? 0); // 0 = setzen, 1 = aufheben

if ($wishId <= 0)
  fail('Ungültige Wunsch-ID', 400);
if ($pw === '')
  fail('Passwort erforderlich', 400);

$conn = db();

/* --- qty des Wunsch + bestehende Reservierungen zählen --- */
$qty = 1;
$stmt = $conn->prepare('SELECT qty FROM wishes WHERE ID = ?');
$stmt->bind_param('i', $wishId);
$stmt->execute();
$res = $stmt->get_result();
if (!$res || !($row = $res->fetch_assoc())) {
  $stmt->close();
  $conn->close();
  fail('Wunsch nicht gefunden', 404);
}
$qty = max(1, (int) $row['qty']);
$stmt->close();

/* Existierende Reservierungen zählen */
$cnt = 0;
$stmt = $conn->prepare('SELECT COUNT(*) AS c FROM wishes_reservations WHERE wish_id = ?');
$stmt->bind_param('i', $wishId);
$stmt->execute();
$res = $stmt->get_result();
if ($res && ($row = $res->fetch_assoc()))
  $cnt = (int) $row['c'];
$stmt->close();

/* --- Operationen --- */
if ($reservedstat === 0) {
  // setzen
  if ($cnt >= $qty) {
    $conn->close();
    fail('Für diesen Wunsch sind bereits alle Exemplare reserviert.', 409);
  }
  $hash = password_hash($pw, PASSWORD_BCRYPT);
  $ins = $conn->prepare('INSERT INTO wishes_reservations (wish_id, pass_hash, created_at) VALUES (?, ?, NOW())');
  $ins->bind_param('is', $wishId, $hash);
  if (!$ins->execute()) {
    $ins->close();
    $conn->close();
    fail('Reservierung fehlgeschlagen', 500);
  }
  $ins->close();
  $conn->close();
  $_SESSION['flash'] = ['msg' => 'Reservierung eingetragen', 'type' => 'success'];
  safe_redirect_back();

} else {
  // aufheben: passenden Hash suchen und genau einen Eintrag löschen
  $sel = $conn->prepare('SELECT id, pass_hash FROM wishes_reservations WHERE wish_id = ?');
  $sel->bind_param('i', $wishId);
  $sel->execute();
  $res = $sel->get_result();

  $deleted = false;
  while ($row = $res->fetch_assoc()) {
    $rid = (int) $row['id'];
    $rhash = (string) $row['pass_hash'];
    if (password_verify($pw, $rhash)) {
      $del = $conn->prepare('DELETE FROM wishes_reservations WHERE id = ? LIMIT 1');
      $del->bind_param('i', $rid);
      $deleted = $del->execute();
      $del->close();
      break;
    }
  }
  $sel->close();
  $conn->close();

  if ($deleted) {
    $_SESSION['flash'] = ['msg' => 'Reservierung aufgehoben', 'type' => 'success'];
  } else {
    $_SESSION['flash'] = ['msg' => 'Kein passender Reservierungseintrag gefunden (Passwort korrekt?)', 'type' => 'warning'];
  }
  safe_redirect_back();
}
