<?php

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

return new class extends Migration
{
    public function up(): void
    {
        Schema::table('admin_sites', function (Blueprint $table): void {
            $table->string('wallet_api_url', 512)->nullable()->after('extra_json');
            $table->string('wallet_debit_path', 128)->default('/wallet/debit-for-lottery')->after('wallet_api_url');
            $table->string('wallet_credit_path', 128)->default('/wallet/credit-from-lottery')->after('wallet_debit_path');
            $table->string('wallet_balance_path', 128)->default('/wallet/balance')->after('wallet_credit_path');
            $table->text('wallet_api_key_encrypted')->nullable()->after('wallet_balance_path');
            $table->text('sso_jwt_secret_encrypted')->nullable()->after('wallet_api_key_encrypted');
            $table->unsignedSmallInteger('wallet_timeout_seconds')->default(10)->after('sso_jwt_secret_encrypted');
            $table->json('iframe_allowed_origins')->nullable()->after('wallet_timeout_seconds');
            $table->string('lottery_h5_base_url', 512)->nullable()->after('iframe_allowed_origins');
            $table->text('notes')->nullable()->after('lottery_h5_base_url');
        });

        $this->seedIntegrationMenuActions();
        $this->backfillDefaultSiteFromEnv();
        $this->syncIntegrationApiResources();
    }

    public function down(): void
    {
        $resourceIds = DB::table('admin_api_resources')
            ->where('code', 'like', 'admin.integration-sites.%')
            ->pluck('id')
            ->all();

        if ($resourceIds !== []) {
            DB::table('admin_role_api_resources')->whereIn('api_resource_id', $resourceIds)->delete();
            DB::table('admin_api_resource_bindings')->whereIn('api_resource_id', $resourceIds)->delete();
            DB::table('admin_api_resources')->whereIn('id', $resourceIds)->delete();
        }

        Schema::table('admin_sites', function (Blueprint $table): void {
            $table->dropColumn([
                'wallet_api_url',
                'wallet_debit_path',
                'wallet_credit_path',
                'wallet_balance_path',
                'wallet_api_key_encrypted',
                'sso_jwt_secret_encrypted',
                'wallet_timeout_seconds',
                'iframe_allowed_origins',
                'lottery_h5_base_url',
                'notes',
            ]);
        });
    }

    private function seedIntegrationMenuActions(): 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;
        }

        $configMenuId = DB::table('admin_menus')->where('code', 'config')->value('id');
        if ($configMenuId === null) {
            return;
        }

        $integrationMenuId = DB::table('admin_menus')->where('code', 'config.integration')->value('id');
        if ($integrationMenuId === null) {
            $integrationMenuId = DB::table('admin_menus')->insertGetId([
                'parent_id' => (int) $configMenuId,
                'menu_type' => 'page',
                'code' => 'config.integration',
                'name' => '主站接入站点',
                'path' => '/admin/config/integration-sites',
                'route_name' => 'admin.config.integration',
                'component' => 'config/integration',
                'icon' => null,
                'active_menu_code' => null,
                'sort_order' => 45,
                'is_visible' => true,
                'is_cache' => false,
                'is_external' => false,
                'status' => 1,
                'meta_json' => null,
                'created_at' => $now,
                'updated_at' => $now,
            ]);
        }

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

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

    private function backfillDefaultSiteFromEnv(): void
    {
        $siteId = DB::table('admin_sites')->where('is_default', true)->value('id')
            ?? DB::table('admin_sites')->orderBy('id')->value('id');

        if ($siteId === null) {
            return;
        }

        $walletUrl = env('MAIN_SITE_WALLET_API_URL');
        $ssoSecret = env('MAIN_SITE_SSO_JWT_SECRET');
        $walletKey = env('MAIN_SITE_WALLET_API_KEY');

        $payload = [
            'updated_at' => Carbon::now(),
        ];

        if (is_string($walletUrl) && trim($walletUrl) !== '') {
            $payload['wallet_api_url'] = rtrim(trim($walletUrl), '/');
        }

        $debitPath = env('MAIN_SITE_WALLET_DEBIT_PATH');
        if (is_string($debitPath) && $debitPath !== '') {
            $payload['wallet_debit_path'] = $debitPath;
        }

        $creditPath = env('MAIN_SITE_WALLET_CREDIT_PATH');
        if (is_string($creditPath) && $creditPath !== '') {
            $payload['wallet_credit_path'] = $creditPath;
        }

        $balancePath = env('MAIN_SITE_WALLET_BALANCE_PATH');
        if (is_string($balancePath) && $balancePath !== '') {
            $payload['wallet_balance_path'] = $balancePath;
        }

        $timeout = env('MAIN_SITE_WALLET_TIMEOUT');
        if (is_numeric($timeout)) {
            $payload['wallet_timeout_seconds'] = max(1, (int) $timeout);
        }

        if (is_string($ssoSecret) && $ssoSecret !== '') {
            $payload['sso_jwt_secret_encrypted'] = encrypt($ssoSecret);
        }

        if (is_string($walletKey) && $walletKey !== '') {
            $payload['wallet_api_key_encrypted'] = encrypt($walletKey);
        }

        if (count($payload) > 1) {
            DB::table('admin_sites')->where('id', (int) $siteId)->update($payload);
        }
    }

    private function syncIntegrationApiResources(): void
    {
        if (! Schema::hasTable('admin_api_resources')) {
            return;
        }

        $now = Carbon::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.integration-sites.'),
        ));

        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();

            foreach ($resource['permission_codes'] 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,
                ]);
            }
        }
    }
};
