<?php
/**
 * @author Colinet Julien
 */

namespace CpCreation\VitiCore\Bridge\Symfony\Bundle\ParamConverter;

use CpCreation\VitiCore\Behavior\HasPayment;
use CpCreation\VitiCore\Cart\Model\Cart;
use CpCreation\VitiCore\Cart\Repository\CartRepository;
use CpCreation\VitiCore\Payment\Model\Payment;
use CpCreation\VitiCore\Payment\Repository\PaymentRepository;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\ParamConverter;
use Sensio\Bundle\FrameworkExtraBundle\Request\ParamConverter\ParamConverterInterface;
use Symfony\Component\HttpFoundation\Request;

class HasPaymentParamConverter implements ParamConverterInterface
{

    private $cartRepository;
    private $paymentRepository;

    public function __construct(CartRepository $cartRepository, PaymentRepository $paymentRepository)
    {
        $this->cartRepository    = $cartRepository;
        $this->paymentRepository = $paymentRepository;
    }

    /**
     * {@inheritdoc}
     *
     * Check, if object supported by our converter
     */
    public function supports(ParamConverter $configuration)
    {
        if (!$configuration->getClass()) {
            return false;
        }

        $reflection = new \ReflectionClass($configuration->getClass());

        if (HasPayment::class != $reflection->getName()) {
            return false;
        }

        return true;
    }

    /**
     * @param Request        $request
     * @param ParamConverter $configuration
     * @return bool
     * @throws \Exception
     */
    public function apply(Request $request, ParamConverter $configuration)
    {

        $id    = $request->attributes->get('id');
        $class = $request->get('class');
        // Check, if route attributes exists
        if (!$id) {
            return false;
        }
        $cart    = $this->cartRepository->find($id);
        $payment = $this->paymentRepository->find($id);
        if ($cart) {
            $request->attributes->set($configuration->getName(), $cart);
        } elseif ($payment) {
            $request->attributes->set($configuration->getName(), $this->paymentRepository->find($id));
        } else {
            throw new \Exception(
                sprintf(
                    'Expected an instance of %s or %s. Got: %s',
                    Cart::class, Payment::class, $class
                )
            );
        }

        return true;
    }
}
