<?php

declare(strict_types=1);

namespace CpCreation\VitiCore\Tests\Marketing;

use CpCreation\VitiCore\Cart\Model\Cart;
use CpCreation\VitiCore\Marketing\Model\ProductReview;
use CpCreation\VitiCore\Marketing\Model\ReviewInvitation;
use CpCreation\VitiCore\Marketing\ReviewPublicationPolicy;
use CpCreation\VitiCore\Product\Model\Product;
use PHPUnit\Framework\TestCase;

final class ReviewPublicationPolicyTest extends TestCase
{
    public function testPublicationDeadlineIsThirtyDaysAfterSubmission(): void
    {
        $submittedAt = new \DateTimeImmutable('2026-07-23 10:00:00');
        $review = $this->createReview($submittedAt);

        $deadline = new ReviewPublicationPolicy()->publicationDeadline($review);

        self::assertSame('2026-08-22 10:00:00', $deadline->format('Y-m-d H:i:s'));
    }

    public function testOnlyPublishedReviewsInsideTheFiveYearWindowArePublic(): void
    {
        $policy = new ReviewPublicationPolicy();
        $now = new \DateTimeImmutable('2026-07-23 10:00:00');

        $pending = $this->createReview($now->modify('-1 day'));
        $withinWindow = $this->createReview($now->modify('-4 years'));
        $withinWindow->publish($now->modify('-4 years'));
        $atBoundary = $this->createReview($now->modify('-5 years'));
        $atBoundary->publish($now->modify('-5 years'));
        $tooOld = $this->createReview($now->modify('-5 years -1 second'));
        $tooOld->publish($now->modify('-5 years -1 second'));
        $future = $this->createReview($now);
        $future->publish($now->modify('+1 second'));

        self::assertFalse($policy->isPublic($pending, $now));
        self::assertTrue($policy->isPublic($withinWindow, $now));
        self::assertTrue($policy->isPublic($atBoundary, $now));
        self::assertFalse($policy->isPublic($tooOld, $now));
        self::assertFalse($policy->isPublic($future, $now));
    }

    public function testItDefinesPrivateDataRetentionCutoffs(): void
    {
        $now = new \DateTimeImmutable('2031-07-23 10:00:00');
        $policy = new ReviewPublicationPolicy();

        self::assertEquals(
            new \DateTimeImmutable('2026-07-23 10:00:00'),
            $policy->retainedReviewDataSince($now),
        );
        self::assertEquals(
            new \DateTimeImmutable('2031-06-23 10:00:00'),
            $policy->unusedInvitationPurgeBefore($now),
        );
    }

    private function createReview(\DateTimeImmutable $submittedAt): ProductReview
    {
        $cart = new Cart();
        $cart->markFulfilled($submittedAt->modify('-10 days'));
        $invitation = new ReviewInvitation(
            $cart,
            'client@example.com',
            hash('sha256', $submittedAt->format(\DateTimeInterface::ATOM)),
            $submittedAt,
            $submittedAt->modify('+90 days'),
        );
        $invitation->markSent($submittedAt);

        return new ProductReview(
            invitation: $invitation,
            product: new Product(),
            cartItem: null,
            rating: 4,
            authorDisplayName: 'Client',
            title: null,
            comment: 'Une belle découverte.',
            moderationRequired: true,
            submittedAt: $submittedAt,
        );
    }
}
