<?php

declare(strict_types=1);

namespace CpCreation\VitiCore\Marketing;

use CpCreation\VitiCore\Cart\Model\Cart;
use CpCreation\VitiCore\Marketing\Model\ReviewInvitation;
use CpCreation\VitiCore\Marketing\Repository\ReviewInvitationRepository;

final readonly class ReviewInvitationIssuer
{
    public function __construct(
        private ReviewInvitationRepository $invitationRepository,
    ) {}

    public function issue(
        Cart $cart,
        string $recipientEmail,
        int $tokenLifetimeDays,
        ?\DateTimeImmutable $now = null,
    ): IssuedReviewInvitation {
        $now ??= new \DateTimeImmutable();
        $token = self::createToken();
        $invitation = new ReviewInvitation(
            cart: $cart,
            recipientEmail: $recipientEmail,
            tokenHash: hash('sha256', $token),
            scheduledAt: $now,
            expiresAt: $now->modify(sprintf('+%d days', $tokenLifetimeDays)),
        );
        $this->invitationRepository->persist($invitation);

        return new IssuedReviewInvitation($invitation, $token);
    }

    private static function createToken(): string
    {
        return rtrim(strtr(base64_encode(random_bytes(32)), '+/', '-_'), '=');
    }
}
