<?php

namespace App\Http\Controllers\Role;

use App\Http\Controllers\Controller;
use App\Http\Requests\Role\StoreRoleRequest;
use App\Http\Requests\Role\UpdateRoleRequest;
use App\Models\Role;
use App\Services\Permission\PermissionRegistry;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
use Illuminate\View\View;

class RoleController extends Controller
{
    public function __construct(
        private readonly PermissionRegistry $permissionRegistry,
    ) {}

    public function index(Request $request): RedirectResponse
    {
        $this->authorize('viewAny', Role::class);

        return redirect()->route('staff.index', array_filter([
            'tab' => 'roles',
            'role' => $request->query('role'),
        ], fn ($value) => $value !== null && $value !== ''));
    }

    public function create(): View
    {
        $this->authorize('create', Role::class);

        return view('roles.create', [
            'permissionGroups' => $this->permissionRegistry->matrixForRole(null),
        ]);
    }

    public function store(StoreRoleRequest $request): RedirectResponse
    {
        $role = Role::create([
            'name' => $request->validated('name'),
            'guard_name' => config('permissions.guard', 'web'),
        ]);

        if ($request->has('permissions')) {
            $role->syncPermissions($request->validated('permissions', []));
        }

        return redirect()
            ->route('staff.index', ['tab' => 'roles', 'role' => $role->id])
            ->with('success', 'Role created.');
    }

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

        $role->load('permissions:id,name');

        return view('roles.edit', [
            'role' => $role,
            'permissionGroups' => $this->permissionRegistry->matrixForRole($role),
        ]);
    }

    public function update(UpdateRoleRequest $request, Role $role): RedirectResponse
    {
        if ($request->filled('name') && ! $role->isSuperAdmin()) {
            $role->update(['name' => $request->validated('name')]);
        }

        if ($request->has('permissions') && ! $role->isSuperAdmin()) {
            $role->syncPermissions($request->validated('permissions', []));
        }

        return redirect()
            ->route('staff.index', ['tab' => 'roles', 'role' => $role->id])
            ->with('success', 'Role updated.');
    }

    public function destroy(Role $role): RedirectResponse
    {
        $this->authorize('delete', $role);

        if ($role->users()->exists()) {
            return back()->with('error', 'This role cannot be deleted while staff members are assigned to it.');
        }

        $role->delete();

        return redirect()->route('staff.index', ['tab' => 'roles'])->with('success', 'Role deleted.');
    }
}
