<?php

namespace App\Http\Controllers\Api\V1\Admin;

use App\Http\Controllers\Controller;
use App\Http\Middleware\RecordAdminApiAudit;
use App\Http\Requests\Admin\AdminSettingBatchUpdateRequest;
use App\Http\Requests\Admin\AdminSettingIndexRequest;
use App\Http\Requests\Admin\AdminSettingUpdateRequest;
use App\Models\LotterySetting;
use App\Services\AuditLogger;
use App\Support\ApiResponse;
use App\Services\LotterySettings;
use Illuminate\Http\JsonResponse;
use Illuminate\Support\Facades\DB;

/**
 * 后台：运营配置（KV 设置）读写。
 */
final class AdminSettingController extends Controller
{
    public function deployment(): JsonResponse
    {
        return ApiResponse::success(LotterySettings::deploymentSnapshot());
    }

    public function index(AdminSettingIndexRequest $request): JsonResponse
    {
        $validated = $request->validated();
        $query = LotterySetting::query()->orderBy('setting_key');

        if (! empty($validated['group'])) {
            $query->where('group_name', $validated['group']);
        }

        $items = $query->get()->map(fn (LotterySetting $s): array => [
            'key' => $s->setting_key,
            'value' => $s->value_json,
            'group' => $s->group_name,
            'description' => $s->description_zh,
        ]);

        return ApiResponse::success(['items' => $items]);
    }

    public function update(AdminSettingUpdateRequest $request, string $key): JsonResponse
    {
        $setting = LotterySetting::query()->where('setting_key', $key)->first();

        LotterySettings::put(
            $key,
            $request->validated('value'),
            $setting ? $setting->group_name : (explode('.', $key)[0] ?? 'general'),
            $setting ? $setting->description_zh : null,
        );

        $fresh = LotterySetting::query()->where('setting_key', $key)->first();

        return ApiResponse::success([
            'key' => $fresh->setting_key,
            'value' => $fresh->value_json,
            'group' => $fresh->group_name,
            'description' => $fresh->description_zh,
        ]);
    }

    public function batchUpdate(AdminSettingBatchUpdateRequest $request): JsonResponse
    {
        /** @var list<array{key: string, value: mixed}> $items */
        $items = $request->validated('items');

        DB::transaction(static function () use ($items): void {
            LotterySettings::putMany($items);
        });

        $keys = array_map(static fn (array $item): string => (string) $item['key'], $items);
        $rows = LotterySetting::query()
            ->whereIn('setting_key', $keys)
            ->orderBy('setting_key')
            ->get();

        $admin = $request->lotteryAdmin();
        if ($admin !== null) {
            AuditLogger::recordForAdmin(
                $admin,
                $request,
                moduleCode: 'settings',
                actionCode: 'batch_update',
                targetType: 'lottery_settings',
                targetId: 'batch',
                beforeJson: null,
                afterJson: [
                    'keys' => $keys,
                    'count' => count($keys),
                ],
            );
            $request->attributes->set(RecordAdminApiAudit::ATTRIBUTE_AUDIT_RECORDED, true);
        }

        return ApiResponse::success([
            'items' => $rows->map(fn (LotterySetting $s): array => [
                'key' => $s->setting_key,
                'value' => $s->value_json,
                'group' => $s->group_name,
                'description' => $s->description_zh,
            ])->values()->all(),
        ]);
    }
}
