<?php

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

/**
 * SIFA P3-T5 / P3-T6 — register the new prescriptions-upgrade + unified-orders
 * permissions and backfill them to every business's Admin role + any role
 * already holding clinic.access_module (same pattern as
 * 2026_07_03_0008_add_patient_master_permissions).
 *
 *   - clinic.order.create  — place a clinical order
 *   - clinic.order.view    — view the orders screen / order details
 *   - clinic.order.verify  — verify order results (final sign-off)
 *   - clinic.rx.refill     — dispense a prescription refill
 */
class AddRxOrderPermissions extends Migration
{
    private array $newPerms = [
        'clinic.order.create',
        'clinic.order.view',
        'clinic.order.verify',
        'clinic.rx.refill',
    ];

    public function up()
    {
        foreach ($this->newPerms as $name) {
            Permission::findOrCreate($name, 'web');
        }

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

        $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('ClinicCore rx/order perm backfill skipped for role ' . $role->name . ' / ' . $p->name . ': ' . $e->getMessage());
                }
            }
        }
    }

    public function down()
    {
        // No-op: revoking permissions could lock admins out unexpectedly.
        // (Same convention as the earlier ClinicCore permission backfills.)
    }
}
