<?php

namespace App\Http\Controllers\Admin;

use App\Actions\Events\ApproveRegistrationAction;
use App\Actions\Events\PromoteWaitlistAction;
use App\Actions\Events\RejectRegistrationAction;
use App\Enums\RegistrationStatus;
use App\Http\Controllers\Controller;
use App\Models\Event;
use App\Models\EventRegistration;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
use Illuminate\Http\Response;
use Illuminate\View\View;
use Symfony\Component\HttpFoundation\StreamedResponse;

class EventRegistrationController extends Controller
{
    public function __construct(
        private ApproveRegistrationAction $approveRegistration,
        private RejectRegistrationAction $rejectRegistration,
        private PromoteWaitlistAction $promoteWaitlist,
    ) {}

    public function index(Request $request, Event $event): View
    {
        $registrations = EventRegistration::query()
            ->where('event_id', $event->id)
            ->with(['user', 'playerProfile'])
            ->when($request->filled('status'), fn ($query) => $query->where('status', $request->string('status')))
            ->latest('registered_at')
            ->paginate(25)
            ->withQueryString();

        return view('admin.registrations.index', compact('event', 'registrations'));
    }

    public function approve(Event $event, EventRegistration $registration): RedirectResponse
    {
        $this->authorize('review', $registration);
        abort_unless($registration->event_id === $event->id, 404);

        $this->approveRegistration->execute($registration, auth()->user());

        return back()->with('success', __('admin.registrations.confirmed_success'));
    }

    public function reject(Request $request, Event $event, EventRegistration $registration): RedirectResponse
    {
        $this->authorize('review', $registration);
        abort_unless($registration->event_id === $event->id, 404);

        $reason = $request->string('reason')->toString() ?: null;
        $this->rejectRegistration->execute($registration, auth()->user(), $reason);

        return back()->with('success', __('admin.registrations.rejected_success'));
    }

    public function promoteWaitlist(Event $event, EventRegistration $registration): RedirectResponse
    {
        $this->authorize('review', $registration);
        abort_unless($registration->event_id === $event->id, 404);

        $this->promoteWaitlist->execute($registration, auth()->user());

        return back()->with('success', __('admin.actions.promote_waitlist'));
    }

    public function export(Event $event): StreamedResponse
    {
        $this->authorize('export-participants');

        $filename = 'event-'.$event->slug.'-registrations-'.now()->format('Y-m-d').'.csv';

        return response()->streamDownload(function () use ($event) {
            $handle = fopen('php://output', 'w');
            fputcsv($handle, [
                'public_id', 'user', 'email', 'status', 'payment_status',
                'contact_name', 'contact_email', 'contact_phone', 'registered_at',
            ]);

            EventRegistration::query()
                ->where('event_id', $event->id)
                ->with('user')
                ->orderBy('registered_at')
                ->chunk(100, function ($rows) use ($handle) {
                    foreach ($rows as $registration) {
                        fputcsv($handle, [
                            $registration->public_id,
                            $registration->user?->username,
                            $registration->user?->email,
                            $registration->status->value,
                            $registration->payment_status->value,
                            $registration->contact_name,
                            $registration->contact_email,
                            $registration->contact_phone_e164,
                            $registration->registered_at?->toDateTimeString(),
                        ]);
                    }
                });

            fclose($handle);
        }, $filename, ['Content-Type' => 'text/csv']);
    }
}
