<?php

namespace App\Domains\Event\Controllers;

use App\Domains\Event\Actions\CertificateOfConductionCheck\CertificateOfConductionCheckCommand;
use App\Domains\Event\Actions\CertificateOfConductionCheck\CertificateOfConductionCheckRequest;
use App\Domains\Event\Actions\SignUp\SignUpCommand;
use App\Domains\Event\Actions\SignUp\SignUpRequest;
use App\Mail\ParticipantParticipationMails\EventSignUpSuccessfullMail;
use App\Models\Tenant;
use App\Providers\DoubleCheckEventRegistrationProvider;
use App\Providers\InertiaProvider;
use App\Resources\UserResource;
use App\Scopes\CommonController;
use DateTime;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Mail;

class SignupController extends CommonController {
    public function __invoke(string $eventId, Request $request) {
        $availableEvents = [];
        foreach ($this->events->getAvailable(false) as $event) {
            $availableEvents[] = $event->toResource()->toArray($request);
        };

        $event = $this->events->getByIdentifier($eventId, false)?->toResource()->toArray($request);

        $participantData = [
            'firstname' => '',
            'lastname' => '',
        ];

        if (auth()->check()) {
            $user = new UserResource(auth()->user())->toArray($request);

            $participantData = [
                'id' => $user['id'],
                'firstname' => $user['firstname'],
                'lastname' => $user['lastname'],
                'nickname' => $user['nickname'],
                'email' => $user['email'],
                'phone' => $user['phone'],
                'postcode' => $user['postcode'],
                'city' => $user['city'],
                'address_1' => $user['address_1'],
                'address_2' => $user['address_2'],
                'birthday' => $user['birthday'],
                'localGroup' => $user['localGroup'],
                'allergies' => $user['allergies'],
                'intolerances' => $user['intolerances'],
                'eating_habit' => $user['eating_habits'],
                'medications' => $user['medications'],
                'tetanusVaccination' => $user['tetanus_vaccination'],
            ];

        }


        $inertiaProvider = new InertiaProvider('Event/Signup', [
            'event' => $event,
            'availableEvents' => $availableEvents,
            'localGroups' => $event['contributingLocalGroups'],
            'participantData' => $participantData,
        ]);
        return $inertiaProvider->render();
    }

    public function signUp(int $eventId, Request $request) {
        $event = $this->events->getById($eventId, false);

        if (!$event->registration_allowed || new \DateTime() > $event->start_date) {
            return response()->json(['status' => 'closed'], 403);
        }

        $eventResource = $event->toResource();
        $registrationData = $request->input('registration_data');
        $siblingReduction = $registrationData['sibling'] === 'true';


        $arrival = \DateTime::createFromFormat('Y-m-d', $registrationData['arrival']);
        $departure = \DateTime::createFromFormat('Y-m-d', $registrationData['departure']);
        $tetanusVaccination = $registrationData['tetanusVaccination'] ? \DateTime::createFromFormat('Y-m-d', $registrationData['tetanusVaccination']) : null;

        $doubleCheckEventRegistrationProvider = new DoubleCheckEventRegistrationProvider(
            $event,
            $registrationData['vorname'],
            $registrationData['nachname'],
            $registrationData['email_1'],
            DateTime::createFromFormat('Y-m-d', $registrationData['geburtsdatum']));

            if ($doubleCheckEventRegistrationProvider->isRegistered()) {
                return response()->json(['status' => 'exists']);
            }

        $amount = $eventResource->calculateAmount(
            $registrationData['participationType'],
            $registrationData['beitrag'],
            $arrival,
            $departure,
            $siblingReduction
        );

        $signupRequest = new SignUpRequest(
            $event,
            $registrationData['userId'] ?? null,
            $registrationData['vorname'],
            $registrationData['nachname'],
            $registrationData['pfadiname'],
            $registrationData['participationType'],
            Tenant::findOrFail($registrationData['localGroup']),
            \DateTime::createFromFormat('Y-m-d', $registrationData['geburtsdatum']),
            $registrationData['address1'],
            $registrationData['address2'],
            $registrationData['plz'],
            $registrationData['ort'],
            $registrationData['email_1'],
            $registrationData['telefon_1'],
            $registrationData['email_2'],
            $registrationData['telefon_2'],
            $registrationData['ansprechpartner'],
            $registrationData['allergien'],
            $registrationData['intolerances'],
            $registrationData['medikamente'],
            $tetanusVaccination,
            $registrationData['essgewohnheit'],
            $registrationData['badeerlaubnis'],
            $registrationData['first_aid'],
            $registrationData['foto']['socialmedia'],
            $registrationData['foto']['print'],
            $registrationData['foto']['webseite'],
            $registrationData['foto']['partner'],
            $registrationData['foto']['intern'],
            $arrival,
            $departure,
            $registrationData['anreise_essen'],
            $registrationData['abreise_essen'],
            $registrationData['anmerkungen'],
            $amount
        );

        $signupCommand = new SignUpCommand($signupRequest);
        $signupResponse = $signupCommand->execute();

        // 4. Addons registrieren


        $certificateOfConductionCheckRequest = new CertificateOfConductionCheckRequest($signupResponse->participant);
        $certificateOfConductionCheckCommand = new CertificateOfConductionCheckCommand($certificateOfConductionCheckRequest);
        $certificateOfConductionCheckResponse = $certificateOfConductionCheckCommand->execute();

        $signupResponse->participant->efz_status = $certificateOfConductionCheckResponse->status;
        $signupResponse->participant->save();

        Mail::to($signupResponse->participant->email_1)->send(new EventSignUpSuccessfullMail(
            participant: $signupResponse->participant,
        ));

        if ($signupResponse->participant->email_2 !== null) {
            Mail::to($signupResponse->participant->email_2)->send(new EventSignUpSuccessfullMail(
                participant: $signupResponse->participant,
            ));
        }

        return response()->json(
            [
                'participant' => $signupResponse->participant->toResource()->toArray($request),
                'status' => 'success',
            ]
        );
    }

    public function calculateAmount(int $eventId, Request $request, bool $forDisplay = true) : JsonResponse | float {
        $event = $this->events->getById($eventId, false)->toResource();

        $siblingReduction = $request->input('sibling') === 'true';

        return response()->json(['amount' =>
            $event->calculateAmount(
                $request->input('participationType'),
                $request->input('beitrag'),
                \DateTime::createFromFormat('Y-m-d', $request->input('arrival')),
                \DateTime::createFromFormat('Y-m-d', $request->input('departure')),
                $siblingReduction
            )->toString()
        ]);
    }
}
