<?php
declare(strict_types=1);

function current_user(): ?array {
  return $_SESSION['user'] ?? null;
}

function is_logged_in(): bool {
  return current_user() !== null;
}

function require_login(): array {
  $u = current_user();
  if (!$u) {
    header('Location: index.php?route=login');
    exit;
  }
  return $u;
}

function require_admin(): array {
  $u = require_login();
  if (($u['role'] ?? 'user') !== 'admin') {
    http_response_code(403);
    echo "Prohibido";
    exit;
  }
  return $u;
}

function auth_refresh_session(PDO $db, int $userId): void {
  $stmt = $db->prepare("SELECT id, username, email, role, can_read, can_write FROM users WHERE id = ?");
  $stmt->execute([$userId]);
  $u = $stmt->fetch();
  if ($u) $_SESSION['user'] = $u;
}

function auth_register(PDO $db, string $username, string $email, string $password): array {
  $username = trim($username);
  $email = trim($email);
  if (strlen($username) < 3) throw new Exception("Usuario demasiado corto (mín 3).");
  if (!filter_var($email, FILTER_VALIDATE_EMAIL)) throw new Exception("Email inválido.");
  if (strlen($password) < 6) throw new Exception("Contraseña demasiado corta (mín 6).");

  $passHash = password_hash($password, PASSWORD_DEFAULT);
  $created = now_iso();

  // If this is the first user, make them admin
  $count = (int)$db->query("SELECT COUNT(*) AS c FROM users")->fetch()['c'];
  $role = ($count === 0) ? 'admin' : 'user';

  $stmt = $db->prepare("INSERT INTO users(username,email,pass_hash,role,created_at) VALUES(?,?,?,?,?)");
  $stmt->execute([$username, $email, $passHash, $role, $created]);

  $id = (int)$db->lastInsertId();
  auth_refresh_session($db, $id);
  return current_user();
}

function auth_login(PDO $db, string $login, string $password): array {
  $login = trim($login);
  $stmt = $db->prepare("SELECT * FROM users WHERE username = ? OR email = ? LIMIT 1");
  $stmt->execute([$login, $login]);
  $u = $stmt->fetch();
  if (!$u || !password_verify($password, $u['pass_hash'])) {
    throw new Exception("Credenciales incorrectas.");
  }
  $_SESSION['user'] = [
    'id' => (int)$u['id'],
    'username' => $u['username'],
    'email' => $u['email'],
    'role' => $u['role'],
    'can_read' => (int)$u['can_read'],
    'can_write' => (int)$u['can_write'],
  ];
  return $_SESSION['user'];
}

function auth_logout(): void {
  $_SESSION = [];
  if (ini_get("session.use_cookies")) {
    $params = session_get_cookie_params();
    setcookie(session_name(), '', time() - 42000,
      $params["path"], $params["domain"],
      $params["secure"], $params["httponly"]
    );
  }
  session_destroy();
}

function auth_update_profile(PDO $db, int $userId, string $newUsername, string $newEmail): void {
  $newUsername = trim($newUsername);
  $newEmail = trim($newEmail);
  if (strlen($newUsername) < 3) throw new Exception("Usuario demasiado corto (mín 3).");
  if (!filter_var($newEmail, FILTER_VALIDATE_EMAIL)) throw new Exception("Email inválido.");
  $stmt = $db->prepare("UPDATE users SET username = ?, email = ? WHERE id = ?");
  $stmt->execute([$newUsername, $newEmail, $userId]);
}

function auth_change_password(PDO $db, int $userId, string $current, string $new): void {
  if (strlen($new) < 6) throw new Exception("Contraseña demasiado corta (mín 6).");
  $stmt = $db->prepare("SELECT pass_hash FROM users WHERE id = ?");
  $stmt->execute([$userId]);
  $row = $stmt->fetch();
  if (!$row || !password_verify($current, $row['pass_hash'])) {
    throw new Exception("La contraseña actual no coincide.");
  }
  $hash = password_hash($new, PASSWORD_DEFAULT);
  $stmt = $db->prepare("UPDATE users SET pass_hash = ? WHERE id = ?");
  $stmt->execute([$hash, $userId]);
}
