<?php
/**
 * User authentication (app-side). Mirrors includes/auth_admin.php but for
 * role=USER accounts, using the same admin_sessions-style pattern via a
 * dedicated user_sessions table.
 */

require_once __DIR__ . '/../config/database.php';
require_once __DIR__ . '/../config/constants.php';
require_once __DIR__ . '/functions.php';

function create_user_session(int $userId, string $deviceId = ''): string
{
    $pdo = getDbConnection();
    $token = generate_token(32);
    $tokenHash = hash('sha256', $token);
    $expiresAt = date('Y-m-d H:i:s', time() + ADMIN_SESSION_LIFETIME);

    $stmt = $pdo->prepare(
        'INSERT INTO user_sessions (user_id, token_hash, device_id, ip_address, user_agent, expires_at)
         VALUES (:user_id, :token_hash, :device_id, :ip_address, :user_agent, :expires_at)'
    );
    $stmt->execute([
        ':user_id'    => $userId,
        ':token_hash' => $tokenHash,
        ':device_id'  => $deviceId,
        ':ip_address' => get_client_ip(),
        ':user_agent' => substr($_SERVER['HTTP_USER_AGENT'] ?? '', 0, 250),
        ':expires_at' => $expiresAt,
    ]);

    return $token;
}

/**
 * Validates the Bearer token. Returns the user row on success, or sends a
 * 401/403 JSON error and terminates on failure (blocked, expired plan is
 * NOT enforced here — screens decide what to do with an expired-but-valid
 * session so the app can show the Plan Expired screen instead of logging
 * the user out entirely).
 */
function require_user(): array
{
    $token = get_bearer_token();
    if (!$token) {
        send_error('Authentication required.', 401);
    }

    $pdo = getDbConnection();
    $tokenHash = hash('sha256', $token);

    $stmt = $pdo->prepare(
        'SELECT s.expires_at, u.id, u.full_name, u.email, u.phone_number, u.business_name,
                u.role, u.license_key, u.validity_days, u.activated_at, u.is_blocked, u.active_device_id
         FROM user_sessions s
         JOIN users u ON u.id = s.user_id
         WHERE s.token_hash = :token_hash LIMIT 1'
    );
    $stmt->execute([':token_hash' => $tokenHash]);
    $row = $stmt->fetch();

    if (!$row) {
        send_error('Invalid or expired session.', 401);
    }
    if (strtotime($row['expires_at']) < time()) {
        send_error('Session expired. Please log in again.', 401);
    }

    return $row;
}

function destroy_user_session(string $token): void
{
    $pdo = getDbConnection();
    $stmt = $pdo->prepare('DELETE FROM user_sessions WHERE token_hash = :hash');
    $stmt->execute([':hash' => hash('sha256', $token)]);
}
