<?php

namespace App\Http\Controllers;

use App\Actions\Events\CancelRegistrationAction;
use App\Actions\Events\RegisterForEventAction;
use App\Http\Requests\Events\StoreEventRegistrationRequest;
use App\Models\Event;
use App\Models\EventRegistration;
use App\Models\PlayerGameProfile;
use App\Services\PhoneNormalizationService;
use Illuminate\Http\RedirectResponse;
use Illuminate\View\View;
use InvalidArgumentException;

class EventRegistrationController extends Controller
{
    public function __construct(
        private PhoneNormalizationService $phoneNormalizer,
    ) {}

    public function create(Event $event): View
    {
        $this->authorize('view', $event);

        $profile = auth()->user()->playerProfile;
        $gameProfiles = $profile
            ?->gameProfiles()
            ->where('game_id', $event->game_id)
            ->with('game')
            ->get() ?? collect();

        return view('pages.events.register', [
            'event' => $event->load(['game', 'paymentMethods.manualPaymentMethod']),
            'gameProfiles' => $gameProfiles,
            'needsPhone' => ! $this->phoneNormalizer->hasValidPhone(auth()->user()->phone_e164),
        ]);
    }

    public function store(
        StoreEventRegistrationRequest $request,
        Event $event,
        RegisterForEventAction $action,
    ): RedirectResponse {
        $this->authorize('view', $event);

        $user = auth()->user();

        if ($request->filled('phone')) {
            $phoneData = $this->phoneNormalizer->normalize(
                $request->input('phone_country_code'),
                $request->input('phone'),
            );
            $user->update($phoneData ?? []);
            $user->refresh();
        }

        $gameProfile = PlayerGameProfile::query()
            ->whereKey($request->validated('player_game_profile_id'))
            ->where('player_profile_id', $user->playerProfile?->id)
            ->where('game_id', $event->game_id)
            ->firstOrFail();

        try {
            $registration = $action->execute($event, $user, [
                'player_game_profile_id' => $gameProfile->id,
                'contact_name' => $request->validated('contact_name'),
                'contact_email' => $request->validated('contact_email'),
                'contact_phone_e164' => $user->phone_e164,
                'contact_whatsapp' => $request->boolean('contact_whatsapp'),
                'user_notes' => $request->validated('user_notes'),
            ]);
        } catch (InvalidArgumentException $e) {
            return back()->withInput()->withErrors(['registration' => $e->getMessage()]);
        }

        return redirect()
            ->route('registrations.show', $registration)
            ->with('status', __('events.flash.registered'));
    }

    public function show(EventRegistration $registration): View
    {
        $this->authorize('view', $registration);

        $registration->load(['event.game', 'statusEvents.changedBy', 'paymentProofs.manualPaymentMethod']);

        return view('pages.registrations.show', [
            'registration' => $registration,
        ]);
    }

    public function cancel(
        EventRegistration $registration,
        CancelRegistrationAction $action,
    ): RedirectResponse {
        $this->authorize('cancel', $registration);

        try {
            $action->execute($registration, auth()->user(), 'Cancelled by participant');
        } catch (InvalidArgumentException $e) {
            return back()->withErrors(['registration' => $e->getMessage()]);
        }

        return redirect()
            ->route('my-events.index')
            ->with('status', __('events.flash.cancelled'));
    }
}
