<?php

use Illuminate\Support\Carbon;
use Illuminate\Support\Facades\DB;
use App\Support\AdminAuthorizationRegistry;
use Illuminate\Database\Migrations\Migration;
use Illuminate\Support\Facades\Schema;

return new class extends Migration
{
    public function up(): void
    {
        $now = Carbon::now();
        $viewActionId = DB::table('admin_action_catalog')->where('code', 'view')->value('id');
        $manageActionId = DB::table('admin_action_catalog')->where('code', 'manage')->value('id');
        if ($viewActionId === null || $manageActionId === null) {
            return;
        }

        $systemMenuId = DB::table('admin_menus')->where('code', 'system')->value('id');
        if ($systemMenuId === null) {
            $systemMenuId = DB::table('admin_menus')->insertGetId([
                'parent_id' => null,
                'menu_type' => 'directory',
                'code' => 'system',
                'name' => '系统',
                'path' => null,
                'route_name' => null,
                'component' => null,
                'icon' => null,
                'active_menu_code' => null,
                'sort_order' => 90,
                'is_visible' => true,
                'is_cache' => false,
                'is_external' => false,
                'status' => 1,
                'meta_json' => null,
                'created_at' => $now,
                'updated_at' => $now,
            ]);
        }

        $agentMenuId = DB::table('admin_menus')->where('code', 'system.agents')->value('id');
        if ($agentMenuId === null) {
            $agentMenuId = DB::table('admin_menus')->insertGetId([
                'parent_id' => (int) $systemMenuId,
                'menu_type' => 'page',
                'code' => 'system.agents',
                'name' => '代理管理',
                'path' => '/admin/agents',
                'route_name' => 'admin.agents',
                'component' => 'agents/index',
                'icon' => null,
                'active_menu_code' => null,
                'sort_order' => 25,
                'is_visible' => true,
                'is_cache' => false,
                'is_external' => false,
                'status' => 1,
                'meta_json' => null,
                'created_at' => $now,
                'updated_at' => $now,
            ]);
        }

        foreach ([
            ['permission_code' => 'agent.node.view', 'action_id' => (int) $viewActionId, 'name' => '代理节点查看'],
            ['permission_code' => 'agent.node.manage', 'action_id' => (int) $manageActionId, 'name' => '代理节点管理'],
        ] as $row) {
            if (DB::table('admin_menu_actions')->where('permission_code', $row['permission_code'])->exists()) {
                continue;
            }

            DB::table('admin_menu_actions')->insert([
                'menu_id' => (int) $agentMenuId,
                'action_id' => $row['action_id'],
                'permission_code' => $row['permission_code'],
                'name' => $row['name'],
                'status' => 1,
                'created_at' => $now,
                'updated_at' => $now,
            ]);
        }

        $menuActionIds = DB::table('admin_menu_actions')->pluck('id', 'permission_code');
        $resources = array_values(array_filter(
            AdminAuthorizationRegistry::resources(),
            static fn (array $resource): bool => str_starts_with((string) $resource['code'], 'admin.agent-nodes.'),
        ));

        foreach ($resources as $resource) {
            $resourceId = DB::table('admin_api_resources')->where('code', $resource['code'])->value('id');
            $payload = [
                'module_code' => $resource['module_code'],
                'name' => $resource['name'],
                'http_method' => $resource['http_method'],
                'uri_pattern' => $resource['uri_pattern'],
                'route_name' => $resource['route_name'],
                'auth_mode' => $resource['auth_mode'],
                'is_audit_required' => $resource['is_audit_required'],
                'status' => 1,
                'meta_json' => null,
                'updated_at' => $now,
            ];

            if ($resourceId === null) {
                $resourceId = DB::table('admin_api_resources')->insertGetId($payload + [
                    'code' => $resource['code'],
                    'created_at' => $now,
                ]);
            } else {
                DB::table('admin_api_resources')->where('id', (int) $resourceId)->update($payload);
            }

            DB::table('admin_api_resource_bindings')
                ->where('api_resource_id', (int) $resourceId)
                ->delete();

            $permissionCodes = $resource['permission_codes'] ?? [];
            foreach ($permissionCodes as $permissionCode) {
                $menuActionId = $menuActionIds[$permissionCode] ?? null;
                if ($menuActionId === null) {
                    continue;
                }

                DB::table('admin_api_resource_bindings')->insert([
                    'api_resource_id' => (int) $resourceId,
                    'menu_action_id' => (int) $menuActionId,
                    'created_at' => $now,
                    'updated_at' => $now,
                ]);
            }
        }

        if (! Schema::hasTable('admin_role_api_resources')) {
            return;
        }

        $superRoleId = DB::table('admin_roles')->where('slug', 'super_admin')->value('id');
        if ($superRoleId === null) {
            return;
        }

        foreach ($resources as $resource) {
            $resourceId = DB::table('admin_api_resources')->where('code', $resource['code'])->value('id');
            if ($resourceId === null) {
                continue;
            }

            DB::table('admin_role_api_resources')->updateOrInsert([
                'role_id' => (int) $superRoleId,
                'api_resource_id' => (int) $resourceId,
            ], []);
        }

        $menuActionIdList = DB::table('admin_menu_actions')
            ->whereIn('permission_code', ['agent.node.view', 'agent.node.manage'])
            ->pluck('id');

        foreach ($menuActionIdList as $menuActionId) {
            DB::table('admin_role_menu_actions')->updateOrInsert([
                'role_id' => (int) $superRoleId,
                'menu_action_id' => (int) $menuActionId,
            ], []);
        }
    }

    public function down(): void
    {
        $codes = [
            'admin.agent-nodes.tree',
            'admin.agent-nodes.store',
            'admin.agent-nodes.show',
            'admin.agent-nodes.update',
            'admin.agent-nodes.children',
        ];

        foreach ($codes as $code) {
            $resourceId = DB::table('admin_api_resources')->where('code', $code)->value('id');
            if ($resourceId === null) {
                continue;
            }

            if (Schema::hasTable('admin_role_api_resources')) {
                DB::table('admin_role_api_resources')->where('api_resource_id', (int) $resourceId)->delete();
            }
            DB::table('admin_api_resource_bindings')->where('api_resource_id', (int) $resourceId)->delete();
            DB::table('admin_api_resources')->where('id', (int) $resourceId)->delete();
        }

        DB::table('admin_menu_actions')
            ->whereIn('permission_code', ['agent.node.view', 'agent.node.manage'])
            ->delete();
    }
};
