<?php

namespace App\Services;

use App\Auth\Permissions;
use App\Models\Tenant\User;
use Spatie\Permission\Models\Permission;
use Spatie\Permission\Models\Role;
use Spatie\Permission\PermissionRegistrar;

/**
 * Seeds the RBAC catalog for a tenant: 50 permissions (global) + 7 system roles
 * + role-permission matrix per the TZ.
 *
 * Idempotent — safe to run multiple times. Adding new permissions later is also
 * idempotent: each Permission::firstOrCreate skips existing rows.
 */
class RbacSeeder
{
    /** Seed permissions globally (they're not tenant-scoped). */
    public function seedPermissions(): void
    {
        foreach (Permissions::all() as $slug) {
            Permission::firstOrCreate(['name' => $slug, 'guard_name' => 'web']);
        }
    }

    /** Seed 7 system roles + role-permission matrix for a specific tenant (team). */
    public function seedTenantRoles(int $companyId): void
    {
        $this->seedPermissions();

        $registrar = app(PermissionRegistrar::class);
        $registrar->setPermissionsTeamId($companyId);
        // Bust cache so newly created roles are visible immediately.
        $registrar->forgetCachedPermissions();

        foreach (Permissions::roleMatrix() as $roleName => $perms) {
            $role = Role::firstOrCreate(
                ['name' => $roleName, 'guard_name' => 'web', 'company_id' => $companyId]
            );
            $role->syncPermissions($perms);
        }
    }

    /**
     * After seeding roles, sync each user's role assignment based on legacy
     * users.role string column. Idempotent: re-running just re-syncs.
     */
    public function syncUsersToRoles(int $companyId): int
    {
        $registrar = app(PermissionRegistrar::class);
        $registrar->setPermissionsTeamId($companyId);
        $registrar->forgetCachedPermissions();

        $count = 0;
        $validRoles = array_keys(Permissions::roleMatrix());

        User::query()
            ->where('company_id', $companyId)
            ->whereNotNull('role')
            ->chunk(100, function ($users) use ($validRoles, &$count) {
                foreach ($users as $user) {
                    // Map legacy role strings to the new catalog
                    $role = match ($user->role) {
                        'admin' => 'admin',
                        'manager' => 'manager',
                        'receptionist' => 'receptionist',
                        'mechanic', 'master' => 'mechanic',
                        'accountant' => 'accountant',
                        'parts_manager' => 'manager',  // map to manager
                        'marketer' => 'manager',
                        'owner' => 'owner',
                        'viewer', 'user' => 'viewer',
                        default => 'viewer',
                    };
                    if (in_array($role, $validRoles, true)) {
                        $user->syncRoles([$role]);
                        $count++;
                    }
                }
            });

        return $count;
    }
}
