<?php

namespace Database\Seeders;

use App\Models\Permission;
use App\Models\Role;
use App\Support\Authorization\EffectiveRoleMatrix;
use App\Support\Authorization\PermissionCatalog;
use Illuminate\Database\Seeder;
use Spatie\Permission\PermissionRegistrar;

class AuthorizationSeeder extends Seeder
{
    public function run(PermissionRegistrar $registrar): void
    {
        $registrar->forgetCachedPermissions();

        foreach (PermissionCatalog::definitions() as $definition) {
            $attributes = [
                'guard_name' => PermissionCatalog::GUARD,
                'display_name' => $definition['display_name'],
                'group' => $definition['group'],
            ];

            if ($definition['description'] !== null) {
                $attributes['description'] = $definition['description'];
            }

            Permission::query()->updateOrCreate(
                ['name' => $definition['name']],
                $attributes,
            );
        }

        $permissions = Permission::query()
            ->whereIn('name', PermissionCatalog::names())
            ->get()
            ->keyBy('name');

        foreach (EffectiveRoleMatrix::roles() as $name => $definition) {
            $attributes = [
                'guard_name' => PermissionCatalog::GUARD,
                'display_name' => $definition['display_name'],
                'is_system' => true,
            ];

            if ($definition['description'] !== null) {
                $attributes['description'] = $definition['description'];
            }

            $role = Role::query()->updateOrCreate(['name' => $name], $attributes);
            $role->syncPermissions(
                collect($definition['permissions'])
                    ->map(fn (string $permissionName) => $permissions->get($permissionName))
                    ->filter()
                    ->values(),
            );
        }

        $registrar->forgetCachedPermissions();
    }
}
