<?php

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

return new class extends Migration
{
    /** @var list<string> */
    private const STALE_RESOURCE_CODES = [
        'admin.reports.index',
        'admin.reports.store',
        'admin.reconcile.index',
        'admin.reconcile.store',
        'admin.draws.publish',
    ];

    /** @var list<string> */
    private const REPORT_RESOURCE_CODES = [
        'admin.reports.daily-profit',
        'admin.reports.player-win-loss',
        'admin.reports.play-dimension',
        'admin.reports.rebate-commission',
        'admin.report-jobs.index',
        'admin.report-jobs.store',
        'admin.report-jobs.show',
        'admin.report-jobs.download',
    ];

    public function up(): void
    {
        $now = Carbon::now();

        $this->deleteStaleApiResources();
        $this->ensureReportViewOnRolesWithReportLegacy();
        $this->syncReportResourceBindings($now);
    }

    public function down(): void
    {
        // 绑定收紧与角色补权为数据修复，不回滚以免再现漂移。
    }

    private function deleteStaleApiResources(): void
    {
        $resourceIds = DB::table('admin_api_resources')
            ->whereIn('code', self::STALE_RESOURCE_CODES)
            ->pluck('id');

        foreach ($resourceIds as $resourceId) {
            $id = (int) $resourceId;
            DB::table('admin_api_resource_bindings')->where('api_resource_id', $id)->delete();
            DB::table('admin_api_resources')->where('id', $id)->delete();
        }
    }

    private function ensureReportViewOnRolesWithReportLegacy(): void
    {
        $menuActionId = DB::table('admin_menu_actions')
            ->where('permission_code', 'service.report.view')
            ->where('status', 1)
            ->value('id');

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

        $reportSlugs = ['prd.report.view', 'prd.report.all', 'prd.report.risk', 'prd.report.finance', 'prd.report.player'];
        $roleIds = DB::table('admin_role_legacy_permissions')
            ->whereIn('permission_slug', $reportSlugs)
            ->distinct()
            ->pluck('role_id');

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

    private function syncReportResourceBindings(Carbon $now): void
    {
        $menuActionIds = DB::table('admin_menu_actions')->pluck('id', 'permission_code');
        $registryByCode = [];
        foreach (AdminAuthorizationRegistry::resources() as $resource) {
            $registryByCode[$resource['code']] = $resource;
        }

        foreach (self::REPORT_RESOURCE_CODES as $code) {
            $resource = $registryByCode[$code] ?? null;
            if ($resource === null) {
                continue;
            }

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

            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,
                ]);
            }
        }
    }

};
