<?php

namespace App\Http\Controllers\Testing;

use App\Http\Controllers\Controller;
use App\Models\Event;
use App\Models\EventType;
use App\Models\Task;
use App\Models\Tenant;
use App\Models\User;
use App\Services\EventJoinTokenService;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Carbon;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Hash;
use Illuminate\Support\Str;

class TestGuestEventController extends Controller
{
    public function store(Request $request, EventJoinTokenService $joinTokens): JsonResponse
    {
        abort_unless(config('e2e.testing_enabled'), 404);

        $validated = $request->validate([
            'slug' => ['nullable', 'string', 'max:100'],
            'name' => ['nullable', 'string', 'max:255'],
            'date' => ['nullable', 'date'],
            'event_type' => ['nullable', 'string', 'max:100'],
            'tasks' => ['nullable', 'array'],
            'tasks.*.slug' => ['required_with:tasks', 'string', 'max:120'],
            'tasks.*.title' => ['required_with:tasks', 'string', 'max:255'],
            'tasks.*.description' => ['nullable', 'string', 'max:1000'],
        ]);

        $slug = Str::slug($validated['slug'] ?? 'pwa-demo-event');

        [$event, $tokenValue] = DB::transaction(function () use ($validated, $slug, $joinTokens) {
            $tenant = $this->ensureTenant();
            $eventType = $this->ensureEventType($validated['event_type'] ?? 'wedding');

            $event = Event::updateOrCreate(
                ['slug' => $slug],
                [
                    'tenant_id' => $tenant->id,
                    'event_type_id' => $eventType->id,
                    'name' => [
                        'de' => $validated['name'] ?? 'PWA Demo Event',
                        'en' => $validated['name'] ?? 'PWA Demo Event',
                    ],
                    'description' => [
                        'de' => 'Automatisches Demo-Event für Playwright.',
                        'en' => 'Automated demo event for Playwright.',
                    ],
                    'default_locale' => 'de',
                    'status' => 'published',
                    'is_active' => true,
                    'date' => ($validated['date'] ?? Carbon::now()->addWeeks(2)->toDateString()),
                    'settings' => [
                        'branding' => [
                            'primary_color' => '#FF5A5F',
                            'secondary_color' => '#FFF8F5',
                            'font_family' => 'Inter, sans-serif',
                        ],
                    ],
                ]
            );

            $taskIds = $this->ensureTasks($tenant->id, $eventType->id, $validated['tasks'] ?? null);
            if ($taskIds !== []) {
                $event->tasks()->syncWithoutDetaching($taskIds);
            }

            $token = $event->joinTokens()->latest()->first();
            if (! $token || ! $token->isActive()) {
                $token = $joinTokens->createToken($event, [
                    'label' => 'Testing Automation',
                    'metadata' => ['generator' => 'testing_api'],
                ]);
            }

            return [$event, $token?->token];
        });

        return response()->json([
            'data' => [
                'event_id' => $event->id,
                'slug' => $event->slug,
                'name' => $event->name,
                'join_token' => $tokenValue,
            ],
        ]);
    }

    private function ensureTenant(): Tenant
    {
        $user = User::firstOrCreate(
            ['email' => 'guest-suite@example.com'],
            [
                'name' => 'Guest Suite Admin',
                'first_name' => 'Guest',
                'last_name' => 'Suite',
                'password' => Hash::make('Password123!'),
                'role' => 'tenant_admin',
            ]
        );

        $tenant = Tenant::firstOrCreate(
            ['slug' => 'guest-suite-tenant'],
            [
                'user_id' => $user->id,
                'name' => 'Guest Suite Tenant',
                'email' => $user->email,
                'is_active' => true,
            ]
        );

        if (! $user->tenant_id) {
            $user->forceFill(['tenant_id' => $tenant->id])->save();
        }

        return $tenant;
    }

    private function ensureEventType(string $slug): EventType
    {
        $slug = Str::slug($slug) ?: 'wedding';

        return EventType::updateOrCreate(
            ['slug' => $slug],
            [
                'name' => [
                    'de' => Str::title($slug),
                    'en' => Str::title($slug),
                ],
                'settings' => [],
            ]
        );
    }

    /**
     * @return array<int, int>
     */
    private function ensureTasks(int $tenantId, int $eventTypeId, ?array $payload): array
    {
        $definitions = $payload ?: [
            [
                'slug' => 'guest-demo-rings',
                'title' => 'Ringe im Fokus',
                'description' => 'Halte die Ringe oder eure Hände mit einem kreativen Hintergrund fest.',
            ],
            [
                'slug' => 'guest-demo-dancefloor',
                'title' => 'Tanzfläche in Bewegung',
                'description' => 'Zeigt uns eure besten Moves – gerne mit Motion Blur.',
            ],
            [
                'slug' => 'guest-demo-cheers',
                'title' => 'Cheers!',
                'description' => 'Ein Toast-Moment mit Gläsern oder Konfetti.',
            ],
        ];

        $ids = [];
        foreach ($definitions as $index => $definition) {
            $task = Task::updateOrCreate(
                ['slug' => $definition['slug']],
                [
                    'tenant_id' => $tenantId,
                    'event_type_id' => $eventTypeId,
                    'title' => [
                        'de' => $definition['title'],
                        'en' => $definition['title'],
                    ],
                    'description' => [
                        'de' => $definition['description'] ?? $definition['title'],
                        'en' => $definition['description'] ?? $definition['title'],
                    ],
                    'instructions' => [
                        'de' => 'Creatives Willkommen',
                        'en' => 'Get creative',
                    ],
                    'priority' => $index === 0 ? 'high' : 'medium',
                ]
            );

            $ids[] = $task->id;
        }

        return $ids;
    }
}
