<?php

namespace App\Provisioning\Steps\Customer;

use App\Models\ProvisioningRun;
use App\Provisioning\StepResult;
use App\Services\Proxmox\ProxmoxClient;
use App\Support\NextcloudOcc;
use Illuminate\Support\Facades\Crypt;
use Illuminate\Support\Str;

class CreateCustomerAdmin extends CustomerStep
{
    public function __construct(private ProxmoxClient $pve) {}

    public function key(): string
    {
        return 'create_customer_admin';
    }

    public function maxDuration(): int
    {
        return 120;
    }

    public function execute(ProvisioningRun $run): StepResult
    {
        // Idempotent: admin already created.
        if ($this->hasResource($run, 'nc_admin')) {
            return StepResult::advance();
        }

        $instance = $this->instance($run);
        $pve = $this->pve->forHost($instance->host);
        $node = (string) $run->context('node');
        $vmid = (int) $run->context('vmid');

        $username = 'admin';
        $password = Str::random(20);

        // Retry-safe: if a prior crashed attempt already created the user, reset
        // its password instead of re-running user:add (which Nextcloud rejects).
        $exists = (int) ($pve->guestExec($node, $vmid, NextcloudOcc::command('user:info '.escapeshellarg($username)))['exitcode'] ?? 1) === 0;

        $action = $exists
            ? 'user:resetpassword --password-from-env '.escapeshellarg($username)
            : 'user:add --password-from-env --group=admin '.escapeshellarg($username);

        // The password travels as OC_PASS rather than as an argument, so it never
        // shows up in the guest's process list — see NextcloudOcc::command().
        $this->guest($pve, $run, NextcloudOcc::command($action, ['OC_PASS' => $password]));

        // Persist only the username (encrypted ref); hand the password to step 15
        // encrypted-in-context for delivery, then it is scrubbed. Never plaintext.
        $instance->update(['nc_admin_ref' => $username]);
        $run->mergeContext(['admin_password' => Crypt::encryptString($password)]);
        $this->recordResource($run, $instance->host, 'nc_admin', $username);

        return StepResult::advance();
    }
}
