<?php

declare(strict_types=1);

use App\Infrastructure\Db\Migrations\BaseMigration;

/**
 * SEC_REVIEW F11: add a `disabled_at` nullable timestamp to `users` so an
 * operator can revoke a user without deleting the audit-history row.
 *
 * `NULL` means active; any non-null value means the user is disabled (the
 * stamp is informational — only the predicate `IS NULL` matters at the
 * impersonation boundary). Indexed because both the impersonation
 * 403-check (`SELECT … WHERE id = ?`) and the admin-users list page filter
 * by it; the index is partial on SQLite to keep the live-user lookup
 * branch index-free.
 */
final class AddDisabledAtToUsers extends BaseMigration
{
    public function up(): void
    {
        $table = $this->table('users');
        $this->addTimestampColumn($table, 'disabled_at', ['null' => true, 'after' => 'is_local']);
        $table->update();

        // Partial index speeds up the "list disabled users" admin page; the
        // active-user lookup path doesn't need it (PK lookup already).
        if ($this->isMysql()) {
            $this->execute('CREATE INDEX idx_users_disabled_at ON users (disabled_at)');
        } else {
            $this->execute('CREATE INDEX idx_users_disabled_at ON users (disabled_at) WHERE disabled_at IS NOT NULL');
        }
    }

    public function down(): void
    {
        if ($this->isMysql()) {
            $this->execute('DROP INDEX idx_users_disabled_at ON users');
        } else {
            $this->execute('DROP INDEX IF EXISTS idx_users_disabled_at');
        }

        $this->table('users')
            ->removeColumn('disabled_at')
            ->update();
    }
}
