<?php

use App\Support\TenantPermissionCatalog;
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Schema;

return new class extends Migration
{
    public function up(): void
    {
        Schema::create('role_profiles', function (Blueprint $table) {
            $table->id();
            $table->foreignId('tenant_id')->constrained()->cascadeOnDelete();
            $table->string('name');
            $table->text('description')->nullable();
            $table->string('base_role')->nullable()->index();
            $table->json('permissions');
            $table->boolean('is_system')->default(false);
            $table->boolean('is_active')->default(true)->index();
            $table->timestamps();
            $table->unique(['tenant_id', 'name']);
            $table->index(['tenant_id', 'is_active']);
        });

        Schema::table('users', function (Blueprint $table) {
            $table->foreignId('role_profile_id')->nullable()->after('role')->constrained('role_profiles')->nullOnDelete();
        });

        $now = now();
        $profileIds = [];

        DB::table('tenants')->orderBy('id')->get(['id'])->each(function ($tenant) use ($now, &$profileIds): void {
            foreach (TenantPermissionCatalog::defaultProfiles() as $baseRole => $profile) {
                $id = DB::table('role_profiles')->insertGetId([
                    'tenant_id' => $tenant->id,
                    'name' => $profile['name'],
                    'description' => $profile['description'],
                    'base_role' => $baseRole,
                    'permissions' => json_encode(TenantPermissionCatalog::defaultForRole($baseRole)),
                    'is_system' => true,
                    'is_active' => true,
                    'created_at' => $now,
                    'updated_at' => $now,
                ]);

                $profileIds[$tenant->id][$baseRole] = $id;
            }
        });

        DB::table('users')
            ->whereNotNull('tenant_id')
            ->whereIn('role', array_keys(TenantPermissionCatalog::defaultProfiles()))
            ->orderBy('id')
            ->get(['id', 'tenant_id', 'role'])
            ->each(function ($user) use ($profileIds): void {
                $profileId = $profileIds[$user->tenant_id][$user->role] ?? null;

                if ($profileId) {
                    DB::table('users')->where('id', $user->id)->update(['role_profile_id' => $profileId]);
                }
            });
    }

    public function down(): void
    {
        Schema::table('users', function (Blueprint $table) {
            $table->dropConstrainedForeignId('role_profile_id');
        });

        Schema::dropIfExists('role_profiles');
    }
};
