<?php

declare(strict_types=1);

/*
 * This file is part of the VITICORE2 package.
 *
 * (c) CP Creation <web@cpcreation.fr>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace CpCreation\VitiCore\Cart;

use CpCreation\VitiCore\Bridge\Symfony\Bundle\Tracking\MatomoEcommerceTracker;
use CpCreation\VitiCore\Bridge\Symfony\Bundle\Tracking\MetaConversionsApiTracker;
use CpCreation\VitiCore\Cart\Model\Cart;
use CpCreation\VitiCore\Cart\Repository\CartRepository;
use Doctrine\ORM\EntityManagerInterface;

final readonly class CartAbandonmentMarker
{
    public const int DEFAULT_PENDING_AFTER_HOURS = 24;
    public const int DEFAULT_CHECKOUT_AFTER_HOURS = 2;
    public const int DEFAULT_LIMIT = 100;

    public function __construct(
        private CartRepository $cartRepository,
        private EntityManagerInterface $em,
        private MatomoEcommerceTracker $matomoEcommerceTracker,
        private MetaConversionsApiTracker $metaConversionsApiTracker,
    ) {
    }

    public function mark(
        int $pendingAfterHours = self::DEFAULT_PENDING_AFTER_HOURS,
        int $checkoutAfterHours = self::DEFAULT_CHECKOUT_AFTER_HOURS,
        int $limit = self::DEFAULT_LIMIT,
        bool $dryRun = false,
    ): CartAbandonmentResult {
        $now = new \DateTimeImmutable();
        $pendingCutoff = $now->modify(sprintf('-%d hours', $pendingAfterHours));
        $checkoutCutoff = $now->modify(sprintf('-%d hours', $checkoutAfterHours));
        $carts = $this->cartRepository->findAbandonableCarts($pendingCutoff, $checkoutCutoff, $limit);
        $marked = 0;
        $markedCarts = [];

        if (!$dryRun) {
            foreach ($carts as $cart) {
                if ($cart instanceof Cart && $cart->markAbandoned($now)) {
                    ++$marked;
                    $markedCarts[] = $cart;
                }
            }

            if ($marked > 0) {
                $this->em->flush();
            }

            foreach ($markedCarts as $cart) {
                $this->matomoEcommerceTracker->trackAbandonedCart($cart);
                $this->metaConversionsApiTracker->trackAbandonedCart($cart);
            }
        }

        return new CartAbandonmentResult(
            markedAt: $now,
            pendingCutoff: $pendingCutoff,
            checkoutCutoff: $checkoutCutoff,
            eligibleCarts: $carts,
            markedCarts: $markedCarts,
            markedCount: $marked,
            dryRun: $dryRun,
        );
    }
}
