<?php

namespace App\Controllers;

use App\Models\EventModel;
use App\Models\EventRegistrationFieldModel;
use App\Models\EventRegistrationModel;

/**
 * Public, anonymous — reached via the link/QR staff share from
 * EventController::show() (event-register/{public_token}, never the raw
 * events.id — see AddPublicTokenToEventsTable's migration comment). Only
 * `confirmed` events accept registrations; an `inquiry` that never became
 * a real booking, or a `cancelled`/`completed` one, shouldn't.
 */
class EventRegistrationController extends BaseController
{
    public function form(string $token)
    {
        $event = (new EventModel())->findByPublicToken($token);

        if ($event === null || $event->status !== 'confirmed') {
            return view('public/not_found', ['pageTitle' => 'Not Found']);
        }

        $fieldModel = new EventRegistrationFieldModel();
        $fields     = $fieldModel->forEvent($event->id);

        return view('event_registration/form', [
            'pageTitle'    => 'Register — ' . $event->event_name,
            'event'        => $event,
            'token'        => $token,
            'fields'       => $fields,
            'fieldOptions' => array_combine(
                array_map(static fn ($f) => $f->id, $fields),
                array_map(static fn ($f) => $fieldModel->decodedOptions($f), $fields),
            ),
        ]);
    }

    public function register(string $token)
    {
        $event = (new EventModel())->findByPublicToken($token);

        if ($event === null || $event->status !== 'confirmed') {
            return view('public/not_found', ['pageTitle' => 'Not Found']);
        }

        $fieldModel = new EventRegistrationFieldModel();
        $fields     = $fieldModel->forEvent($event->id);
        $rawCustomFields = $this->request->getPost('custom_fields') ?? [];

        $customFieldValues = [];
        $missingRequired   = [];

        foreach ($fields as $field) {
            $answer = $rawCustomFields[$field->id] ?? null;

            if ($field->field_type === 'checkbox') {
                $answer = is_array($answer) ? array_values(array_filter(array_map('trim', $answer), static fn ($v) => $v !== '')) : [];

                if ($field->is_required && empty($answer)) {
                    $missingRequired[] = $field->label;
                }

                if (! empty($answer)) {
                    $customFieldValues[$field->id] = $answer;
                }
            } else {
                $answer = is_string($answer) ? trim($answer) : '';

                if ($field->is_required && $answer === '') {
                    $missingRequired[] = $field->label;
                }

                if ($answer !== '') {
                    $customFieldValues[$field->id] = $answer;
                }
            }
        }

        if (! empty($missingRequired)) {
            return redirect()->back()->withInput()->with('error', 'Please fill in: ' . implode(', ', $missingRequired) . '.');
        }

        $registrations = new EventRegistrationModel();
        $data = [
            'event_id'  => $event->id,
            'full_name' => $this->request->getPost('full_name'),
            'phone'     => $this->request->getPost('phone'),
            'email'     => $this->request->getPost('email') ?: null,
            'custom_field_values' => empty($customFieldValues) ? null : json_encode($customFieldValues),
        ];
        $data['registration_code'] = $registrations->generateCode($event->id);

        if (! $registrations->insert($data)) {
            return $this->redirectWithModelErrors($registrations);
        }

        $this->logActivity('events', 'New online registration for "' . $event->event_name . '": ' . $data['full_name'] . '.');

        service('messagingService')->send(
            'event_registration_code',
            null,
            $data['phone'],
            "Hi {$data['full_name']}, you're registered for {$event->event_name}. Your check-in code is {$data['registration_code']} — show this or type it at the venue.",
            [$data['full_name'], $event->event_name, $data['registration_code']],
        );

        return view('event_registration/confirmed', [
            'pageTitle' => 'Registered — ' . $event->event_name,
            'event'     => $event,
            'fullName'  => $data['full_name'],
            'code'      => $data['registration_code'],
        ]);
    }
}
