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

if (session_status() !== PHP_SESSION_ACTIVE) session_start();

/** Attempts to log in with a login_id ('admin' or a CLRC code) and password. */
function attemptLogin(string $loginId, string $password): array {
    $pdo = getPDO();
    $stmt = $pdo->prepare('SELECT * FROM users WHERE login_id = ? LIMIT 1');
    $stmt->execute([strtolower(trim($loginId))]);
    $user = $stmt->fetch();

    if (!$user) {
        return ['ok' => false, 'error' => 'Incorrect login ID or password.'];
    }
    if (!$user['active']) {
        return ['ok' => false, 'error' => 'This account has been disabled. Contact the admin.'];
    }
    if (!password_verify($password, $user['password_hash'])) {
        return ['ok' => false, 'error' => 'Incorrect login ID or password.'];
    }

    $_SESSION['uid']                  = (int)$user['uid'];
    $_SESSION['login_id']             = $user['login_id'];
    $_SESSION['role']                 = $user['role'];
    $_SESSION['clrccode']             = $user['clrccode'];
    $_SESSION['display_name']         = $user['display_name'];
    $_SESSION['must_change_password'] = (bool)$user['must_change_password'];

    return ['ok' => true];
}

function isLoggedIn(): bool {
    return isset($_SESSION['uid']);
}

function currentRole(): ?string {
    return $_SESSION['role'] ?? null;
}

function currentClrcCode(): ?string {
    return $_SESSION['clrccode'] ?? null;
}

function mustChangePassword(): bool {
    return !empty($_SESSION['must_change_password']);
}

/** Redirects to login.php if not authenticated. Call at the top of every protected page. */
function requireLogin(): void {
    if (!isLoggedIn()) {
        header('Location: login.php');
        exit;
    }
    if (mustChangePassword() && basename($_SERVER['PHP_SELF']) !== 'change_password.php') {
        header('Location: change_password.php');
        exit;
    }
}

/**
 * Same check as requireLogin(), but for AJAX/API endpoints: a redirect
 * makes no sense for a fetch() call (and a relative Location header breaks
 * anyway for anything under api/, since it resolves against that deeper
 * path, not the app root). Returns a clean 401 JSON error instead, which
 * the calling JS checks for and handles (e.g. prompt to sign in again).
 */
function requireLoginApi(): void {
    if (!isLoggedIn() || mustChangePassword()) {
        http_response_code(401);
        header('Content-Type: application/json');
        echo json_encode(['error' => 'Your session has expired. Please sign in again.', 'sessionExpired' => true]);
        exit;
    }
}

/** Redirects home if the current user isn't Admin. Call after requireLogin(). */
function requireAdmin(): void {
    if (currentRole() !== 'admin') {
        header('Location: dashboard.php');
        exit;
    }
}

/** Admin sees everything; a CLRC user only their own CLRC's data. Use in WHERE clauses. */
function clrcScopeSql(string $column = 'clrccode'): array {
    if (currentRole() === 'clrc') {
        return ["$column = ?", [currentClrcCode()]];
    }
    return ['1=1', []];
}

function changeOwnPassword(string $newPassword): void {
    $pdo = getPDO();
    $hash = password_hash($newPassword, PASSWORD_DEFAULT);
    $stmt = $pdo->prepare('UPDATE users SET password_hash = ?, must_change_password = 0 WHERE uid = ?');
    $stmt->execute([$hash, $_SESSION['uid']]);
    $_SESSION['must_change_password'] = false;
}

function logout(): void {
    $_SESSION = [];
    session_destroy();
}
