<?php

use Illuminate\Database\Migrations\Migration;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Schema;
use Spatie\Permission\PermissionRegistrar;

return new class extends Migration
{
    public function up(): void
    {
        foreach (['permissions', 'roles', 'role_has_permissions'] as $table) {
            if (! Schema::hasTable($table)) {
                throw new \RuntimeException("Credit-score permission migration blocked: required table {$table} is missing.");
            }
        }

        $now = now();
        $permissions = [
            'credit-score.view' => ['View customer credit scores', 'read'],
            'credit-score.history' => ['View customer credit score history', 'read'],
            'credit-score.recalculate' => ['Recalculate customer credit scores', 'operate'],
        ];

        DB::transaction(function () use ($permissions, $now): void {
            foreach ($permissions as $name => [$displayName, $risk]) {
                DB::table('permissions')->updateOrInsert(
                    ['name' => $name, 'guard_name' => 'web'],
                    [
                        'display_name' => $displayName,
                        'group' => 'customers',
                        'description' => $risk === 'read'
                            ? 'Credit scoring decision-support access.'
                            : 'Authorized manual credit-score recalculation.',
                        'updated_at' => $now,
                        'created_at' => $now,
                    ],
                );
            }

            $permissionIds = DB::table('permissions')
                ->where('guard_name', 'web')
                ->whereIn('name', array_keys($permissions))
                ->pluck('id')
                ->all();

            $roleIds = DB::table('roles')
                ->where('guard_name', 'web')
                ->whereIn('name', ['branch-administrator', 'branch-manager', 'loan-officer', 'loan-inspector'])
                ->pluck('id')
                ->all();

            foreach ($roleIds as $roleId) {
                foreach ($permissionIds as $permissionId) {
                    DB::table('role_has_permissions')->insertOrIgnore([
                        'permission_id' => $permissionId,
                        'role_id' => $roleId,
                    ]);
                }
            }
        });

        app(PermissionRegistrar::class)->forgetCachedPermissions();
    }

    public function down(): void
    {
        if (! Schema::hasTable('permissions')) {
            return;
        }

        $permissionIds = DB::table('permissions')
            ->where('guard_name', 'web')
            ->whereIn('name', ['credit-score.view', 'credit-score.history', 'credit-score.recalculate'])
            ->pluck('id')
            ->all();

        if (Schema::hasTable('role_has_permissions') && $permissionIds !== []) {
            DB::table('role_has_permissions')->whereIn('permission_id', $permissionIds)->delete();
        }

        if ($permissionIds !== []) {
            DB::table('permissions')->whereIn('id', $permissionIds)->delete();
        }

        app(PermissionRegistrar::class)->forgetCachedPermissions();
    }
};
