<?php

declare(strict_types=1);

use App\Enums\AdminRoleStatus;
use DBCore\Permission\Enums\PermissionEffect;
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

return new class extends Migration
{
    public function up(): void
    {
        Schema::create('core_permissions', function (Blueprint $table): void {
            $table->id();
            $table->string('name', 128)->comment('权限点编码');
            $table->string('display_name', 120)->comment('面向业务人员的权限名称');
            $table->string('guard_name', 32)->default('web');
            $table->string('module', 64)->comment('所属模块');
            $table->string('description', 255)->nullable()->comment('权限说明');
            $table->unsignedInteger('sort_order')->default(100)->comment('排序值，越小越靠前');
            $table->boolean('is_system')->default(true)->comment('是否系统权限');
            $table->timestamps();

            $table->unique('name', 'uq_core_permissions_name');
            $table->index(['module', 'sort_order'], 'idx_core_permissions_module');
            $table->index(['guard_name', 'sort_order'], 'idx_core_permissions_guard');
        });

        Schema::create('core_roles', function (Blueprint $table): void {
            $table->id();
            $table->string('name', 64)->comment('角色编码');
            $table->string('display_name', 120)->comment('角色名称');
            $table->string('guard_name', 32)->default('web');
            $table->string('description', 255)->nullable()->comment('角色说明');
            $table->unsignedInteger('sort_order')->default(100)->comment('排序值，越小越靠前');
            $table->string('status', 20)->default(AdminRoleStatus::Enabled->value)->comment('角色状态');
            $table->boolean('is_system')->default(false)->comment('是否系统角色');
            $table->boolean('is_super_admin')->default(false)->comment('是否超级管理员角色');
            $table->timestamps();

            $table->unique('name', 'uq_core_roles_name');
            $table->index(['status', 'sort_order'], 'idx_core_roles_status_sort');
            $table->index(['is_super_admin', 'status'], 'idx_core_roles_super');
        });

        Schema::create('core_role_permissions', function (Blueprint $table): void {
            $table->id();
            $table->foreignId('role_id');
            $table->foreign('role_id', 'fk_core_role_perm_role')->references('id')->on('core_roles')->cascadeOnDelete();
            $table->foreignId('permission_id');
            $table->foreign('permission_id', 'fk_core_role_perm_perm')->references('id')->on('core_permissions')->cascadeOnDelete();
            $table->string('effect', 20)->default(PermissionEffect::Allow->value)->comment('授权效果');
            $table->timestamps();

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

        Schema::create('core_user_roles', function (Blueprint $table): void {
            $table->id();
            $table->unsignedBigInteger('user_id')->comment('用户 ID');
            $table->string('user_type', 191)->comment('用户模型类名');
            $table->foreignId('role_id');
            $table->foreign('role_id', 'fk_core_user_role_role')->references('id')->on('core_roles')->cascadeOnDelete();
            $table->string('guard_name', 32)->default('web');
            $table->timestamps();

            $table->unique(['user_id', 'user_type', 'role_id', 'guard_name'], 'uq_core_user_role');
            $table->index(['user_type', 'user_id'], 'idx_core_user_role_user');
            $table->index(['role_id', 'user_type'], 'idx_core_user_role_lookup');
        });

        if (Schema::hasTable('core_audit_logs') && ! Schema::hasColumn('core_audit_logs', 'correlation_id')) {
            Schema::table('core_audit_logs', function (Blueprint $table): void {
                $table->string('correlation_id', 36)->nullable()->after('user_agent');
                $table->index(['correlation_id', 'created_at']);
            });
        }
    }

    public function down(): void
    {
        if (Schema::hasTable('core_audit_logs') && Schema::hasColumn('core_audit_logs', 'correlation_id')) {
            Schema::table('core_audit_logs', function (Blueprint $table): void {
                $table->dropIndex(['correlation_id', 'created_at']);
                $table->dropColumn('correlation_id');
            });
        }

        Schema::dropIfExists('core_user_roles');
        Schema::dropIfExists('core_role_permissions');
        Schema::dropIfExists('core_roles');
        Schema::dropIfExists('core_permissions');
    }
};
