<?php

namespace App\Components\Admin\Role;

use App\Models\User\Permission;
use App\Models\User\Role;
use App\Services\HistoryService;
use Illuminate\Foundation\Auth\Access\AuthorizesRequests;
use Illuminate\Validation\Rule;
use Livewire\Component;

class RoleEdit extends Component {
    use AuthorizesRequests;

    public Role $role;

    public string $name;
    public array $permissions = [];
    public string $filterGroup = '';

    public function mount(Role $role): void {
        $this->authorize('edit', $role);

        $this->role = $role;
        $this->name = $role->name;
        $this->permissions = $role->permissions->pluck('name')->toArray();
    }

    public function save(HistoryService $historyService): void {
        $this->authorize('edit', $this->role);
        $this->validate();

        $originalName  = $this->role->name;
        $previousPerms = $this->role->permissions->pluck('name')->toArray();

        $this->role->update([
            'name' => $this->name,
        ]);

        $this->role->syncPermissions($this->permissions);

        $added   = array_values(array_diff($this->permissions, $previousPerms));
        $removed = array_values(array_diff($previousPerms, $this->permissions));
        $renamed = $originalName !== $this->name;

        if ($renamed || $added || $removed) {
            $parts = [];
            if ($renamed) $parts[] = "renamed from '{$originalName}' to '{$this->name}'";
            if ($added)   $parts[] = count($added) . ' permission(s) added';
            if ($removed) $parts[] = count($removed) . ' permission(s) removed';

            $historyService->add(
                auth()->user(),
                "Updated role '{$this->name}' — " . implode('; ', $parts),
                [
                    'role_id' => $this->role->id,
                    'added'   => $added,
                    'removed' => $removed,
                    'renamed' => $renamed ? ['from' => $originalName, 'to' => $this->name] : null,
                ]
            );
        }

        $this->dispatch('toast',
            title: 'Saved',
            message: 'Successfully saved role.',
            type: 'success'
        );
    }

    public function render() {
        $allGroups = Permission::orderBy('group')->distinct()->pluck('group');

        $permissionGroups = Permission::orderBy('group')
            ->orderBy('label')
            ->when($this->filterGroup, fn($q) => $q->where('group', $this->filterGroup))
            ->get()
            ->groupBy('group');

        return view('components.admin.role.role-edit', compact('permissionGroups', 'allGroups'));
    }

    protected function rules(): array {
        return [
            'name' => [
                'required',
                'string',
                'max:100',
                Rule::unique('roles', 'name')->ignore($this->role->id),
            ],
            'permissions' => ['array'],
        ];
    }
}
