<?php

namespace App\Console\Commands;

use App\Models\User;
use Illuminate\Console\Command;
use Illuminate\Support\Facades\Hash;
use Illuminate\Support\Str;

/**
 * Emergency, shell-only recovery: resets the admin password (and optionally 2FA)
 * when the operator is locked out (lost password + authenticator + backup codes).
 * Requires server access, so it is a safe last resort.
 */
class ResetAdmin extends Command
{
    protected $signature = 'clusev:reset-admin
        {--email= : E-Mail des Admin-Kontos (sonst der einzige Benutzer)}
        {--password= : Neues Passwort (zufällig erzeugt, falls leer)}
        {--disable-2fa : 2FA + Backup-Codes ebenfalls zurücksetzen}';

    protected $description = 'Notfall-Reset: setzt das Admin-Passwort (und optional 2FA) per Shell zurück';

    public function handle(): int
    {
        $email = (string) $this->option('email');
        $user = $email !== ''
            ? User::where('email', $email)->first()
            : (User::count() === 1 ? User::first() : null);

        if (! $user) {
            $this->error($email !== '' ? "Kein Benutzer mit E-Mail {$email}." : 'Kein eindeutiger Benutzer — bitte --email angeben.');

            return self::FAILURE;
        }

        $password = (string) ($this->option('password') ?: Str::password(20));
        // Rotate remember_token so any previously issued remember-me cookie is revoked.
        $user->forceFill([
            'password' => Hash::make($password),
            'must_change_password' => false,
            'remember_token' => Str::random(60),
            // Restore full admin rights — this is a lockout-recovery path, so the operator must
            // regain the control plane regardless of the account's prior role.
            'role' => 'admin',
        ]);

        if ($this->option('disable-2fa')) {
            $user->forceFill([
                'two_factor_secret' => null,
                'two_factor_confirmed_at' => null,
                'two_factor_recovery_codes' => null,
            ]);
            // Drop security keys too — a key that prompted the emergency reset must not
            // silently revive when 2FA is re-enabled.
            $user->webauthnCredentials()->delete();
        }

        $user->save();

        $this->info("Passwort für {$user->email} zurückgesetzt.");
        if (! $this->option('password')) {
            $this->warn("Neues Passwort (jetzt notieren): {$password}");
        }
        if ($this->option('disable-2fa')) {
            $this->info('2FA + Backup-Codes entfernt — beim nächsten Login neu einrichten.');
        }

        return self::SUCCESS;
    }
}
