<?php

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

/**
 * Spatie gives us role→permission. §66A additionally requires each grant to
 * carry an organizational scope (own/assigned/team/branch/company/global) and
 * roles to be manageable from the admin UI, so we extend both.
 */
return new class extends Migration
{
    public function up(): void
    {
        Schema::table(config('permission.table_names.roles'), function (Blueprint $table) {
            $table->string('label')->nullable()->after('name');
            $table->text('description')->nullable()->after('label');
            $table->unsignedSmallInteger('level')->default(100)->after('description');
            $table->boolean('is_system')->default(false)->after('level');
            $table->boolean('is_active')->default(true)->after('is_system');
        });

        Schema::table(config('permission.table_names.permissions'), function (Blueprint $table) {
            $table->string('module', 64)->nullable()->after('name');
            $table->string('label')->nullable()->after('module');
            $table->text('description')->nullable()->after('label');
        });

        // Scope of a permission as granted through a specific role.
        Schema::create('role_permission_scopes', function (Blueprint $table) {
            $table->id();
            $table->foreignId('role_id')->constrained(config('permission.table_names.roles'))->cascadeOnDelete();
            $table->foreignId('permission_id')->constrained(config('permission.table_names.permissions'))->cascadeOnDelete();
            $table->string('scope', 16)->default('own');
            $table->timestamps();

            $table->unique(['role_id', 'permission_id']);
        });

        // Per-user grant/deny overrides on top of role-derived permissions.
        Schema::create('user_permission_overrides', function (Blueprint $table) {
            $table->id();
            $table->foreignId('user_id')->constrained()->cascadeOnDelete();
            $table->foreignId('permission_id')->constrained(config('permission.table_names.permissions'))->cascadeOnDelete();
            $table->string('effect', 8)->default('grant'); // grant | deny
            $table->string('scope', 16)->nullable();
            $table->text('reason')->nullable();
            $table->foreignId('granted_by')->nullable()->constrained('users')->nullOnDelete();
            $table->timestamp('expires_at')->nullable();
            $table->timestamps();

            $table->unique(['user_id', 'permission_id']);
            $table->index('expires_at');
        });
    }

    public function down(): void
    {
        Schema::dropIfExists('user_permission_overrides');
        Schema::dropIfExists('role_permission_scopes');

        Schema::table(config('permission.table_names.permissions'), function (Blueprint $table) {
            $table->dropColumn(['module', 'label', 'description']);
        });

        Schema::table(config('permission.table_names.roles'), function (Blueprint $table) {
            $table->dropColumn(['label', 'description', 'level', 'is_system', 'is_active']);
        });
    }
};
