<?php

namespace App\Models;

use App\Services\PermissionGroupHelper;
use Spatie\Permission\Models\Permission as SpatiePermission;

class Permission extends SpatiePermission
{
    protected $fillable = [
        'name',
        'guard_name',
        'group',
        'status',
    ];

    /**
     * Default group derived from permission name (used when group is not set in DB).
     */
    public static function deriveGroupFromName(string $name): string
    {
        return PermissionGroupHelper::getGroupName($name);
    }

    /**
     * Sync group column for permissions that have null/empty group (only fills defaults, does not overwrite custom groups).
     */
    public static function syncPermissionGroups(): int
    {
        $updated = 0;
        foreach (static::whereNull('group')->orWhere('group', '')->get() as $permission) {
            $permission->group = PermissionGroupHelper::getGroupName($permission->name);
            $permission->save();
            $updated++;
        }
        return $updated;
    }

    /**
     * Get permissions grouped by group (DB value or default from name) for assign permission UI.
     */
    public static function getGroupedForAssign(string $status = 'enable'): \Illuminate\Support\Collection
    {
        static::syncPermissionGroups();

        $order = PermissionGroupHelper::getGroupDisplayOrder();

        return static::where('status', $status)
            ->orderBy('name')
            ->get()
            ->groupBy(function ($p) {
                return $p->group ?: PermissionGroupHelper::getGroupName($p->name);
            })
            ->sortKeysUsing(function ($a, $b) use ($order) {
                $posA = array_search($a, $order, true);
                $posB = array_search($b, $order, true);
                $posA = $posA === false ? 999 : $posA;
                $posB = $posB === false ? 999 : $posB;
                return $posA <=> $posB;
            });
    }
}
