<?php

declare(strict_types=1);

/*
 * This file is part of the Ferienpass package.
 *
 * (c) Richard Henkenjohann <richard@ferienpass.online>
 *
 * For more information visit the project website <https://ferienpass.online>
 * or the documentation under <https://docs.ferienpass.online>.
 */

namespace Ferienpass\CoreBundle\Application;

use Ferienpass\CoreBundle\ConsentManager\ConsentState;
use Ferienpass\CoreBundle\Entity\Offer\OfferInterface;

/**
 * Descriptor that tells the application form WHAT to render and validate for a
 * given (offer, participant?, user?) combination — single source of truth so the
 * anonymous and signed-in flows stay aligned.
 *
 * @see ApplicationFormBuilder
 */
final readonly class ApplicationFormSpec
{
    /**
     * @param ConsentState[]                                          $offerConsents       account-level (subject=account) consents, decided once
     * @param ConsentState[]                                          $participantConsents per-participant consents (subject=participant, offer- or edition-scoped)
     * @param array<array{uuid:string, question:string, type:string}> $extras              offer-specific extra questions
     */
    public function __construct(
        public OfferInterface $offer,
        public bool $needsParticipantData,
        public array $offerConsents,
        public array $participantConsents,
        public array $extras,
        public ?int $minAge,
        public ?int $maxAge,
        /**
         * True when the system requires a postal address with every application.
         * For anonymous applications the address is collected inline; signed-in
         * users add it once in their profile (see ApplicationForm::mustAddPostalAddress).
         */
        public bool $requiresPostalAddress = false,
    ) {
    }

    public function hasConsents(): bool
    {
        return [] !== $this->offerConsents || [] !== $this->participantConsents;
    }

    public function hasExtras(): bool
    {
        return [] !== $this->extras;
    }
}
