<?php

/*
 * This file is part of the VitiCore 2.
 *
 * (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\Bridge\Symfony\Bundle\Provider\Payment;

use CpCreation\VitiCore\Behavior\HasPayment;
use CpCreation\VitiCore\Bridge\Symfony\Bundle\Utils\Mailer;
use CpCreation\VitiCore\Cart\Model\Cart;
use CpCreation\VitiCore\Contact\Model\Contact;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpFoundation\RequestStack;
use Symfony\Component\HttpFoundation\Session\SessionInterface;
use Symfony\Component\Routing\RouterInterface;

final class CheckProvider implements PaymentProviderInterface
{
    public const string TYPE = 'check';

    private string $path;

    /**
     * @param array<int,array{name:string,path:string}> $paths
     */
    public function __construct(
        private readonly RouterInterface $router,
        private readonly RequestStack $requestStack,
        private readonly Mailer $mailer,
        array $paths,
    ) {
        foreach ($paths as $path) {
            if (($path['name'] ?? null) === $this->getMethod()) {
                $this->path = (string) ($path['path'] ?? '');
                break;
            }
        }

        // fallback "safe" si config incomplète
        $this->path ??= '';
    }

    private function getSession(): ?SessionInterface
    {
        return $this->requestStack->getSession();
    }

    /**
     * @throws \Twig\Error\LoaderError
     * @throws \Twig\Error\RuntimeError
     * @throws \Twig\Error\SyntaxError
     */
    public function checkout(Contact $contact, HasPayment $payment): RedirectResponse
    {
        $this->getSession()->set('cart', null);

        if ($payment instanceof Cart) {
            $this->mailer->sendOfflineOrder($contact, $payment);
        }

        return new RedirectResponse(
            $this->router->generate($this->path, [
                'id' => $payment->getId()->toString(),
            ])
        );
    }

    public function getMethod(): string
    {
        return self::TYPE;
    }
}
