<?php

use Illuminate\Database\Migrations\Migration;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Schema;
use Spatie\Permission\Models\Permission;
use Spatie\Permission\Models\Role;

/**
 * P5-T3 dermatology deep-dive — register the two new dermatology permissions and
 * grant them to existing clinic/admin roles. Mirrors DentalClinic's P5-T2
 * backfill:
 *   - Permission::findOrCreate($name, 'web') (name + guard only).
 *   - Backfill onto every Admin#<business_id> role and every role already
 *     holding clinic.access_module (a "ClinicCore user").
 * Business admins already pass every ->can() via the core Gate::before bypass;
 * this backfill makes the perms grantable to non-admin roles and shows them
 * checked for existing clinic staff. Idempotent (findOrCreate + givePermissionTo).
 */
class AddDermaPermissions extends Migration
{
    /** @var string[] */
    private $permissions = [
        'derma.lesions.manage',
        'derma.scores.manage',
    ];

    public function up()
    {
        if (! Schema::hasTable('permissions')) {
            return; // Spatie tables not migrated yet — perms land via module repair later.
        }

        foreach ($this->permissions as $permission) {
            Permission::findOrCreate($permission, 'web');
        }

        $perms = Permission::whereIn('name', $this->permissions)->get();
        if ($perms->isEmpty()) return;

        // Roles that already use ClinicCore (hold clinic.access_module) + every
        // business Admin role (UltimatePOS "Admin#<business_id>" naming).
        $accessRole = Permission::where('name', 'clinic.access_module')->first();
        $rolesWithAccess = $accessRole
            ? DB::table('model_has_permissions')
                ->where('permission_id', $accessRole->id)
                ->where('model_type', Role::class)
                ->pluck('model_id')->all()
            : [];

        $rolesViaPivot = $accessRole
            ? DB::table('role_has_permissions')
                ->where('permission_id', $accessRole->id)
                ->pluck('role_id')->all()
            : [];

        $adminRoles = Role::where('name', 'like', 'Admin#%')->pluck('id')->all();

        $candidateRoleIds = array_values(array_unique(array_merge(
            $rolesWithAccess, $rolesViaPivot, $adminRoles
        )));
        if (empty($candidateRoleIds)) return;

        $roles = Role::whereIn('id', $candidateRoleIds)->get();
        foreach ($roles as $role) {
            foreach ($perms as $p) {
                try {
                    $role->givePermissionTo($p);
                } catch (\Throwable $e) {
                    Log::warning('DermatologyClinic perm backfill skipped for role ' . $role->name . ' / ' . $p->name . ': ' . $e->getMessage());
                }
            }
        }
    }

    public function down()
    {
        // No-op rollback: revoking permissions could lock roles out unexpectedly.
    }
}
