<?php
// includes/auth.php

declare(strict_types=1);

if (session_status() === PHP_SESSION_NONE) {
  session_start();
}

require __DIR__ . '/db.php';

/**
 * Login with username/password.
 * Expects admin_users(username, password_hash, role, is_active [, district_id, ulb_id]).
 * On success, stores a compact user payload in $_SESSION['admin'].
 */
function auth_login(string $username, string $password): array {
  global $pdo;

  $sql = 'SELECT id, username, password_hash, role, is_active,
                 /* optional scope columns (NULL-safe if not present) */
                 district_id, ulb_id
          FROM admin_users
          WHERE username = :u
          LIMIT 1';
  $st = $pdo->prepare($sql);
  $st->execute(['u' => $username]);
  $u = $st->fetch();

  if (!$u || empty($u['is_active'])) {
    return ['success' => false, 'message' => 'Invalid credentials'];
  }
  if (!password_verify($password, (string)$u['password_hash'])) {
    return ['success' => false, 'message' => 'Invalid credentials'];
  }

  // rotate session id on login
  session_regenerate_id(true);

  $_SESSION['admin'] = [
    'id'         => (int)$u['id'],
    'username'   => (string)$u['username'],
    'role'       => (string)$u['role'],
    'district_id'=> isset($u['district_id']) ? (int)$u['district_id'] : null,
    'ulb_id'     => isset($u['ulb_id']) ? (int)$u['ulb_id'] : null,
    'login_at'   => date('Y-m-d H:i:s'),
  ];

  return ['success' => true];
}

/** Clear all auth state and destroy session. */
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'] ?? false,
      $params['httponly'] ?? true
    );
  }
  session_destroy();
}

/** Returns the current logged-in admin (or null). */
function auth_user(): ?array {
  return $_SESSION['admin'] ?? null;
}

/**
 * Gatekeeper: require a login, and optionally restrict to certain roles.
 * Adjust the redirect path if your login URL differs.
 */
function require_login(array $roles = []): void {
  $u = auth_user();
  if (!$u) {
    header('Location: /sbm/public/admin/login.php');
    exit;
  }
  if ($roles && !in_array($u['role'], $roles, true)) {
    http_response_code(403);
    echo 'Forbidden';
    exit;
  }
}

/**
 * Same as require_login(), but returns the current user array for convenience.
 * Example: $me = require_login_scoped(['super_admin','district_admin','ulb_admin']);
 */
function require_login_scoped(array $roles = []): array {
  require_login($roles);
  $me = auth_user();
  if (!$me) {
    header('Location: /sbm/public/admin/login.php');
    exit;
  }
  return $me;
}

/** Small helper: check a single role. */
function auth_is(string $role): bool {
  $u = auth_user();
  return $u && strtolower($u['role'] ?? '') === strtolower($role);
}

/**
 * Compute the list of ULB IDs the current user can access.
 * - super_admin: all ULBs
 * - district_admin: all ULBs within their district_id
 * - ulb_admin: just their ulb_id
 * - (legacy roles like president/dm): default to all ULBs (backward compatible)
 *
 * Usage:
 *   $scope = auth_ulb_scope($pdo); // returns [ulb_id, ...]
 */
function auth_ulb_scope(PDO $pdo): array {
  $me = auth_user();
  if (!$me) return [];

  $role = strtolower($me['role'] ?? '');

  // ULB admin: single ULB
  if ($role === 'ulb_admin') {
    $ulbId = (int)($me['ulb_id'] ?? 0);
    return $ulbId > 0 ? [$ulbId] : [];
  }

  // District admin: all ULBs in their district
  if ($role === 'district_admin') {
    $d = (int)($me['district_id'] ?? 0);
    if ($d <= 0) return [];
    $st = $pdo->prepare('SELECT id FROM ulbs WHERE district_id = :d');
    $st->execute(['d' => $d]);
    $rows = $st->fetchAll(PDO::FETCH_COLUMN);
    return array_map('intval', $rows ?: []);
  }

  // Super admin OR legacy roles (president/dm): full access
  $rows = $pdo->query('SELECT id FROM ulbs')->fetchAll(PDO::FETCH_COLUMN);
  return array_map('intval', $rows ?: []);
}
