<?php

declare(strict_types=1);

namespace PpPhp\Core\Auth;

use PpPhp\Core\DB;

/**
 * Tracks sign-in and activity on the platform `users` table so Manage Users can
 * show "last login" and "last seen". The columns are added on demand (older
 * installs predate them), and every write uses the DATABASE clock (NOW()) so the
 * values stay comparable with created_at regardless of PHP/MySQL timezone skew.
 *
 * Platform-only — generated apps track their own sessions separately.
 */
class UserActivity
{
    private static bool $ensured = false;

    /** Idempotently add the activity columns to the users table (once per request). */
    public static function ensureColumns(): void
    {
        if (self::$ensured) {
            return;
        }
        self::$ensured = true;
        try {
            DB::Init();
            DB::SetConnection();
            $have = [];
            foreach (DB::FetchAll('SHOW COLUMNS FROM `users`') as $row) {
                $have[strtolower((string) ($row['Field'] ?? ''))] = true;
            }
            $add = [];
            if (!isset($have['last_login_at'])) { $add[] = 'ADD COLUMN `last_login_at` DATETIME NULL'; }
            if (!isset($have['last_login_ip'])) { $add[] = 'ADD COLUMN `last_login_ip` VARCHAR(45) NULL'; }
            if (!isset($have['last_seen_at']))  { $add[] = 'ADD COLUMN `last_seen_at` DATETIME NULL'; }
            if ($add) {
                DB::Query('ALTER TABLE `users` ' . implode(', ', $add));
            }
        } catch (\Throwable $e) {
            // A read-only or non-standard users table simply won't show activity.
        }
    }

    /** Stamp a successful sign-in (login time + IP), and reset the seen throttle. */
    public static function recordLogin(int $userId, string $ip): void
    {
        if ($userId <= 0) {
            return;
        }
        self::ensureColumns();
        try {
            DB::Query(
                'UPDATE `users` SET `last_login_at` = NOW(), `last_seen_at` = NOW(), `last_login_ip` = ? WHERE `id` = ?',
                [substr($ip, 0, 45), $userId]
            );
        } catch (\Throwable $e) {}
        $_SESSION['_ls_touch'] = time();
    }

    /** Update "last seen" on activity — throttled to at most once every 2 minutes. */
    public static function touch(int $userId): void
    {
        if ($userId <= 0) {
            return;
        }
        $last = (int) ($_SESSION['_ls_touch'] ?? 0);
        if (time() - $last < 120) {
            return;
        }
        $_SESSION['_ls_touch'] = time();
        try {
            DB::Query('UPDATE `users` SET `last_seen_at` = NOW() WHERE `id` = ?', [$userId]);
        } catch (\Throwable $e) {}
    }
}
