<?php

namespace App\Livewire\Modals;

use App\Models\Server;
use App\Services\SshKeyProvisioner;
use Livewire\Attributes\Locked;
use LivewireUI\Modal\ModalComponent;

/**
 * Confirm + run the safe "generate key → install → verify → switch credential → disable
 * password login" flow (R5). On success the freshly generated private key is revealed ONCE
 * (download client-side; it is never re-fetchable). The key is also kept encrypted in the vault.
 */
class SshKeyProvision extends ModalComponent
{
    #[Locked]
    public int $serverId;

    public string $serverName = '';

    public bool $done = false;

    public bool $ok = false;

    public ?string $privateKey = null;

    public ?string $publicKey = null;

    public ?string $error = null;

    public function mount(int $serverId): void
    {
        // Rotating to key-only access (installs a key, switches the credential, disables
        // password login) over SSH is a fleet-admin action.
        abort_unless(auth()->user()?->can('manage-fleet'), 403);

        $this->serverId = $serverId;
        $this->serverName = Server::find($serverId)?->name ?? '';
    }

    public static function modalMaxWidth(): string
    {
        return 'lg';
    }

    public function run(SshKeyProvisioner $provisioner): void
    {
        // Re-gate on run: refuse a demoted user / hand-crafted /livewire/update after mount.
        abort_unless(auth()->user()?->can('manage-fleet'), 403);

        if ($this->done) {
            return;
        }

        $server = Server::find($this->serverId);
        if (! $server) {
            $this->error = __('common.server_not_found');

            return;
        }

        try {
            $result = $provisioner->enableKeyOnlyAccess($server);
        } catch (\Throwable $e) {
            $this->done = true;
            $this->ok = false;
            $this->error = $e->getMessage();
            $this->dispatch('hardeningApplied');
            $this->dispatch('credentialChanged');
            $this->dispatch('notify', message: __('modals.ssh_key_provision.notify_failed'));

            return;
        }

        $this->done = true;
        $this->ok = $result['ok'];
        $this->privateKey = $result['privateKey'] ?? null;
        $this->publicKey = $result['publicKey'] ?? null;
        $this->error = $result['ok'] ? null : ($result['error'] ?? __('modals.ssh_key_provision.error_unknown'));

        $this->dispatch('hardeningApplied');
        $this->dispatch('credentialChanged');

        $this->dispatch('notify', message: $this->ok
            ? __('modals.ssh_key_provision.notify_ok', ['server' => $this->serverName])
            : __('modals.ssh_key_provision.notify_failed'));
    }

    public function render()
    {
        return view('livewire.modals.ssh-key-provision');
    }
}
