<?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\Entity\Attendance;
use Symfony\Component\HttpFoundation\UriSigner;
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;

/**
 * Builds the signed link to an application's confirmation page
 * ({@see \Ferienpass\CmsBundle\Controller\Page\AttendanceShowController}) — the
 * one piece of self-service a family without an account has. Behind it they can
 * review the registration, sign outstanding consents, correct their answers to
 * the extra questions (a photo included) and ask to withdraw.
 *
 * The `valid` parameter is part of the signature and states the expiry in the URL
 * itself, so the page can refuse an old link without keeping any server-side
 * state about the links handed out.
 */
final readonly class AttendanceLinkGenerator
{
    /**
     * How long a freshly handed-out link stays usable. Long enough for a family to
     * get to it after the weekend, short enough that a forwarded mail does not stay
     * a key to a child's data for a whole season.
     */
    public const VALIDITY = '+14 days';

    public function __construct(
        private UrlGeneratorInterface $urlGenerator,
        private UriSigner $uriSigner,
    ) {
    }

    /**
     * NOTE for callers outside a web request (message handlers, CLI): the absolute
     * URL comes from the router's context, so set its host from a trusted source
     * first — never from a request's Host header, which the signature would then
     * bless.
     */
    public function signedShowUrl(Attendance $attendance, string $validity = self::VALIDITY): string
    {
        return $this->uriSigner->sign(
            $this->urlGenerator->generate('cms_attendance_show', [
                'attendance' => $attendance->getUuid()->toBase58(),
                'valid' => new \DateTimeImmutable($validity)->format('c'),
            ], UrlGeneratorInterface::ABSOLUTE_URL)
        );
    }
}
