<?php

namespace App\Modules\Settings\Rbac\Repositories;

use App\Models\User;
use App\Modules\Settings\Rbac\Models\Permission;
use Illuminate\Database\Eloquent\Collection;
use Illuminate\Support\Facades\DB;

class PermissionRepository
{
    public function allOrderedBySlug(): Collection
    {
        return Permission::query()->orderBy('slug')->get();
    }

    /**
     * @return list<string>
     */
    public function permissionSlugsForUser(User $user): array
    {
        if ($user->tenant_id === null) {
            return [];
        }

        return Permission::query()
            ->select('permissions.slug')
            ->join('role_permissions', 'permissions.id', '=', 'role_permissions.permission_id')
            ->join('roles', 'roles.id', '=', 'role_permissions.role_id')
            ->join('user_roles', 'roles.id', '=', 'user_roles.role_id')
            ->where('user_roles.user_id', $user->id)
            ->where('roles.tenant_id', $user->tenant_id)
            ->where('roles.is_active', true)
            ->whereNull('roles.deleted_at')
            ->distinct()
            ->orderBy('permissions.slug')
            ->pluck('permissions.slug')
            ->all();
    }

    /**
     * @return list<int>
     */
    public function allIdsOrdered(): array
    {
        return Permission::query()->orderBy('id')->pluck('id')->all();
    }

    public function syncFromConfigList(array $slugsWithLabels): void
    {
        foreach ($slugsWithLabels as $slug => $name) {
            Permission::query()->updateOrCreate(
                ['slug' => $slug],
                ['name' => $name],
            );
        }
    }

    /**
     * @param  list<int>  $permissionIds
     */
    public function attachToRole(int $roleId, array $permissionIds): void
    {
        $unique = array_values(array_unique(array_map('intval', $permissionIds)));
        $rows = array_map(fn (int $pid): array => [
            'role_id' => $roleId,
            'permission_id' => $pid,
        ], $unique);
        if ($rows === []) {
            DB::table('role_permissions')->where('role_id', $roleId)->delete();

            return;
        }
        DB::table('role_permissions')->where('role_id', $roleId)->delete();
        DB::table('role_permissions')->insert($rows);
    }
}
