<?php

namespace App\Components\Admin\Users;

use App\Models\API\ApiScope;
use App\Models\User\User;
use App\Services\HistoryService;
use Livewire\Component;

class UserApiKeys extends Component {
    public User $user;

    /** Create token */
    public string $tokenName = '';
    public array $selectedScopes = [];
    public ?string $newToken = null;

    public function mount(User $user): void {
        $this->authorize('viewApiKeys', $user);
        $this->user = $user;
        $this->scopes = ApiScope::orderBy('group')
            ->orderBy('label')
            ->get()
            ->groupBy('group');
    }

    public function createToken(HistoryService $history): void {
        $this->authorize('manageApiKeys', $this->user);

        $this->validate([
            'tokenName' => 'required|string|max:100',
            'selectedScopes' => 'array',
        ]);

        $token = $this->user->createToken(
            $this->tokenName,
            $this->selectedScopes
        );

        $this->newToken = $token->plainTextToken;

        $history->add($this->user, "API token '{$this->tokenName}' created", [
            'token_id' => $token->accessToken->id ?? null,
            'name'     => $this->tokenName,
            'scopes'   => $this->selectedScopes,
        ]);

        $this->reset(['tokenName', 'selectedScopes']);
    }

    public function revokeToken(int $tokenId, HistoryService $history): void {
        $this->authorize('manageApiKeys', $this->user);

        $token = $this->user->tokens()->where('id', $tokenId)->first();
        $tokenName = $token?->name;

        $this->user->tokens()
            ->where('id', $tokenId)
            ->delete();

        $history->add($this->user, "API token '{$tokenName}' revoked", [
            'token_id' => $tokenId,
            'name'     => $tokenName,
        ]);
    }

    public function render() {
        return view('components.admin.users.user-api-keys', [
            'tokens' => $this->user->tokens()
                ->orderByDesc('created_at')
                ->get(),

            'scopes' => ApiScope::orderBy('group')
                ->orderBy('label')
                ->get()
                ->groupBy('group'),
        ]);
    }
}
