<?php

namespace App\Http\Controllers\Testing;

use App\Http\Controllers\Controller;
use App\Models\Event;
use App\Models\EventJoinToken;
use App\Services\EventJoinTokenService;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Validation\ValidationException;
use SimpleSoftwareIO\QrCode\Facades\QrCode;

class TestEventController extends Controller
{
    public function joinToken(Request $request, EventJoinTokenService $tokens): JsonResponse
    {
        abort_unless(config('e2e.testing_enabled'), 404);

        $validated = $request->validate([
            'event_id' => ['nullable', 'integer'],
            'slug' => ['nullable', 'string'],
            'ensure_active' => ['sometimes', 'boolean'],
        ]);

        $eventId = $validated['event_id'] ?? null;
        $slug = $validated['slug'] ?? null;

        if (! $eventId && ! $slug) {
            throw ValidationException::withMessages([
                'event_id' => 'Provide either event_id or slug.',
            ]);
        }

        $eventQuery = Event::query();

        if ($eventId) {
            $eventQuery->whereKey($eventId);
        } else {
            $eventQuery->where('slug', $slug);
        }

        /** @var Event|null $event */
        $event = $eventQuery->first();

        if (! $event) {
            return response()->json([
                'data' => null,
            ], 404);
        }

        /** @var EventJoinToken|null $token */
        $token = $event->joinTokens()->latest()->first();

        if (! $token || (($validated['ensure_active'] ?? true) && ! $token->isActive())) {
            $token = $tokens->createToken($event, [
                'label' => 'Automation',
                'metadata' => [
                    'generated_for' => 'testing_api',
                ],
            ]);
        }

        $plainToken = $token->token;

        if (! $plainToken) {
            throw ValidationException::withMessages([
                'token' => 'Failed to resolve token value.',
            ]);
        }

        $joinUrl = route('guest.event', ['token' => $plainToken]);

        $qrSvg = QrCode::format('svg')
            ->size(256)
            ->generate($joinUrl);

        return response()->json([
            'data' => [
                'event_id' => $event->id,
                'token_id' => $token->id,
                'token' => $plainToken,
                'join_url' => $joinUrl,
                'qr_svg' => $qrSvg,
                'expires_at' => $token->expires_at?->toIso8601String(),
                'usage_count' => $token->usage_count,
                'usage_limit' => $token->usage_limit,
            ],
        ]);
    }
}
