<?php

namespace App\Console\Commands;

use App\Models\Customer;
use App\Models\Operator;
use App\Support\PasswordPolicy;
use Illuminate\Console\Command;
use Illuminate\Support\Facades\Hash;
use Illuminate\Support\Facades\Validator;
use Spatie\Permission\PermissionRegistrar;

/**
 * Creates (or promotes) an operator with the Owner role — the account the
 * installer sets up so a fresh server is usable immediately.
 *
 * Promotion is deliberate: running this twice with the same address should fix
 * a lost role, not fail with "email already taken".
 *
 * Renamed from clupilot:create-admin now that the account this creates is an
 * Operator, not a User with is_admin set — the old name stays reachable as an
 * alias so existing install scripts and muscle memory keep working.
 */
class CreateAdmin extends Command
{
    protected $signature = 'clupilot:create-operator
                            {--email= : Login address}
                            {--name= : Display name}
                            {--password= : Leave empty to be prompted}';

    protected $aliases = ['clupilot:create-admin'];

    protected $description = 'Create or promote an operator account with the Owner role';

    public function handle(): int
    {
        $email = $this->option('email') ?: $this->ask('Email');
        $name = $this->option('name') ?: $this->ask('Name', 'Administrator');
        $password = $this->option('password') ?: $this->secret('Password');

        $validator = Validator::make(
            ['email' => $email, 'name' => $name, 'password' => $password],
            [
                'email' => 'required|email|max:255',
                'name' => 'required|string|max:255',
                'password' => PasswordPolicy::rules(),
            ],
        );

        if ($validator->fails()) {
            foreach ($validator->errors()->all() as $error) {
                $this->error($error);
            }

            return self::FAILURE;
        }

        // An operator address that also belongs to a customer would block that
        // customer from ever getting a portal login. Checked directly against
        // `users`, not only `customers`: see Customer::emailTaken().
        if (Customer::emailTaken($email)) {
            $this->error('That address already belongs to a customer.');

            return self::FAILURE;
        }

        $operator = Operator::query()->firstOrNew(['email' => $email]);
        $existed = $operator->exists;

        $operator->fill([
            'name' => $name,
            'password' => Hash::make($password),
        ])->save();

        $operator->syncRoles(['Owner']);
        app(PermissionRegistrar::class)->forgetCachedPermissions();

        $this->info($existed
            ? "Existing account {$email} promoted to Owner and password reset."
            : "Owner account {$email} created.");

        return self::SUCCESS;
    }
}
