<?php 
 
namespace PortalBundle\Controller; 
 
use CoreBundle\Component\CoreFormFactory; 
use CoreBundle\Entity\Post; 
use CoreBundle\Factory\InStockVehicle; 
use CoreBundle\Model\Leasing\LeasingClient; 
use CoreBundle\Model\Vehicles\Repository; 
use DcSiteBundle\Model\CreditModel; 
use DcSiteBundle\Services\HistoryManager; 
use DcSiteBundle\Services\VehicleViewService; 
use CoreBundle\Entity\Dealer; 
use CoreBundle\Entity\Forms; 
use CoreBundle\Entity\Vehicles\VehicleItem; 
use CoreBundle\Model\Vehicles\AbstractVehicle; 
use CoreBundle\Model\Vehicles\Vehicle; 
use CoreBundle\Model\Vehicles\VehicleType; 
use DateTime; 
use Doctrine\ORM\EntityManagerInterface; 
use Doctrine\ORM\OptimisticLockException; 
use PortalBundle\Model\Breadcrumbs; 
use PortalBundle\Model\Catalog; 
use PortalBundle\Services\ServiceService; 
use PortalBundle\Services\VehicleService; 
use Symfony\Component\HttpFoundation\Cookie; 
use Symfony\Component\HttpFoundation\Request; 
use Symfony\Component\HttpFoundation\RequestStack; 
use Symfony\Component\HttpFoundation\Response; 
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException; 
use Symfony\Component\Routing\RouterInterface; 
 
class CarController extends BaseController 
{ 
    private VehicleService $vehicleService; 
    public function __construct(VehicleService $vehicleService, CoreFormFactory $coreFormFactory, RequestStack $requestStack, 
                                RouterInterface $router, Repository      $vehicleRepository, ServiceService $serviceService) 
    { 
        parent::__construct($coreFormFactory, $requestStack, $router, $vehicleRepository, $serviceService); 
        $this->vehicleService = $vehicleService; 
    } 
 
    /** 
     * @param Vehicle $CarModel 
     * @return array 
     */ 
    private function buildCarForms(AbstractVehicle $CarModel): array 
    { 
        $TiForm = new Forms(); 
        $BuyForm = new Forms(); 
        $CreditForm = new Forms(); 
        $TiForm->setVehicle($CarModel->getVehicleEntity()); 
 
        $CreditForm->setVehicle($CarModel->getVehicleEntity()); 
        return [ 
            'testDrive' => $this->CoreFormFactory()->testDriveForm($CarModel->getDealer())->createView(), 
            'buyForm' => $this->CoreFormFactory()->buyForm($BuyForm, $CarModel->getVehicleEntity())->createView(), 
            'creditForm' => $this->CoreFormFactory()->creditForm($CarModel->getDealer(), $CreditForm)->createView() 
        ]; 
    } 
 
    public function index(Request $request, \CoreBundle\Factory\Vehicle $vehicleFactory, HistoryManager $historyManager, 
                          \DcSiteBundle\Services\VehicleService $vehicleService, CreditModel $creditModel, 
                          LeasingClient $leasingClient, EntityManagerInterface $em): Response 
    { 
        $vehicleItemId = $request->get('variation'); 
        $buyForm = new Forms(); 
 
        /** @var Dealer $dealer */ 
        $dealer = $em->getRepository(Dealer::class)->findOneBy(['url' => $request->get('dealer')]); 
 
        $variation = null; 
        if ($vehicleItemId) { 
            /** @var VehicleItem $vehicleItem */ 
            $vehicleItem = $em->getRepository(VehicleItem::class)->getVehicleItemByVariation($vehicleItemId, $dealer); 
            if($vehicleItem && $vehicleItem->getSold()) { 
                throw new NotFoundHttpException(); 
            } 
            if($vehicleItem){ 
                $variation = $vehicleItem->getVariation()->getId(); 
                $vehicle = $vehicleFactory->createByVehicleItem($vehicleItem); 
                $historyManager->setUserCarHistory($this->getUser(), $vehicle->getVehicleEntity(), $vehicleItem); 
            } 
        } 
 
        if(!$variation){ 
            $vehicle = $vehicleFactory->createByUrl($request->get('url'), $dealer); 
        } 
 
        if (!$vehicle || $vehicle->isUsed()) { 
            throw new NotFoundHttpException(); 
        } 
 
        $vehicleTypeData = VehicleType::getTypeDataById($vehicle->getVehicleType()); 
 
        $vehicleTypeId = $vehicleTypeData['id']; 
 
        $vehicleEm = $vehicle->getVehicleEntity(); 
 
        $vehicleService->addViews($vehicleEm); 
 
        $vehicleInStock = $this->vehicleService->getVehicleInStockByBrand($vehicleEm->getModel()->getBrand(), $this->getUser(), $vehicleTypeId, 10); 
        $countModelInStock = count($this->vehicleService->getVehicleInStock($vehicleEm->getModel(), $this->getUser())); 
        $vehicleUsed = $this->vehicleService->getVehicleUsedByBrand($vehicleEm->getModel()->getBrand(), $this->getUser(), $vehicleTypeId, 10); 
 
        $characteristicId = ($vehicle->getBodyType())? $vehicle->getBodyType()->getId() : null; 
        $vehiclePrice = $vehicle->price(); 
        $modelId = $vehicle->getModel()->getId(); 
 
        $vehicleBodyType = $this->vehicleService 
            ->getVehicleByCharacteristicId($this->getUser(), $characteristicId, false,null, $vehiclePrice, $modelId, 11); 
 
        $urlParams = [ 
          'routeName' => 'portal_new_car', 
            'params' => [ 
                'dealer' => $dealer->getUrl(), 
                'url'=> $vehicle->getModel()->getUrl(), 
            ] 
        ]; 
 
        $vehicleColor = $vehicleService->getVehicleColor($vehicleEm); 
        $compareVehicleEquipment = ($vehicleTypeData['url'] == 'car')?$vehicleService->getCompareVehicleEquipment($vehicleEm, $urlParams):null; 
        $creditPayment = $creditModel->getMinPayment($vehicle); 
        $featuresIds = $this->vehicleService->getFeatures($this->getUser()); 
 
        $leasingPayment = $leasingClient->getFirstAnnuitetData($vehicle->fullPrice(), $vehicle->getVehicleType()); 
        $inArchive = ($vehicle->getShowDisabled() == 1 && $vehicle->getState() == 0 && $vehicle->isUsed() == 0); 
 
        return $this->basePortalRender('@Portal/Car/new-card-car.html.twig', [ 
            'vehicle' => $vehicle, 
            'vehicleInStock' => $vehicleInStock, 
            'inArchive' => $inArchive, 
            'countModelInStock' => $countModelInStock, 
            'vehicleUsed' => $vehicleUsed, 
            'vehicleBodyType' => $vehicleBodyType, 
            'vehicleColor' => $vehicleColor, 
            'creditPayment' => $creditPayment, 
            'leasingPayment' => $leasingPayment->payment, 
            'compareVehicleEquipment' => $compareVehicleEquipment, 
            'leasingCalculatorForm' => $this->CoreFormFactory()->leasingForm()->createView(), 
            'dealer' => $dealer, 
            'type' => $vehicleTypeData['url'], 
            'state' => 'new', 
            'featuredId' => $featuresIds[$vehicle->getVehicleItemId()] ?? null, 
            'comparedId' => $this->vehicleService->getComparison($vehicle), 
            'buyForm' => $this->CoreFormFactory()->buyForm($buyForm, $vehicleEm, $vehicle->getVehicleItemId(),  null, false, false, $vehicle->getPrice())->createView(), 
        ]); 
    } 
 
    public function vehicleInStock(Request $request, InStockVehicle $inStockVehicleFactory, EntityManagerInterface $em, 
                                   \CoreBundle\Factory\Vehicle $vehicleFactory, \DcSiteBundle\Services\VehicleService $vehicleService, 
                                   CreditModel $creditModel, LeasingClient $leasingClient): Response 
    { 
        $buyForm = new Forms(); 
 
        $dealer = $em->getRepository(Dealer::class)->findOneBy(['url' => $request->get('dealer')]); 
        if (!$dealer) { 
            throw $this->createNotFoundException(); 
        } 
        /** @var Dealer $dealer */ 
        $vehicle = $inStockVehicleFactory->createByUrl($request->get('url'), $dealer); 
 
        if (!$vehicle ) { 
            throw $this->createNotFoundException(); 
        } 
 
        $vehicleEm = $vehicle->getVehicle(); 
        $vehicleEntity = $vehicleFactory->createByEntity($vehicleEm); 
 
        $vehicleTypeData = VehicleType::getTypeDataById($vehicleEm->getVehicleType()); 
        $vehicleInStock = $this->vehicleService->getVehicleInStock($vehicleEm->getModel(), $this->getUser(), $vehicleEm->getDealer(), 6); 
        $countModelInStock = count($this->vehicleService->getVehicleInStock($vehicleEm->getModel(), $this->getUser())); 
        $vehicleUsed = $this->vehicleService->getVehicleUsed($vehicleEm->getModel(), $this->getUser(), 6); 
 
        $vehiclePrice = $vehicle->Price(); 
        $characteristicId = $vehicle->getBodyType()->getId(); 
 
        $vehicleBodyType = $this->vehicleService 
            ->getVehicleInStockByBodyType($this->getUser(), $characteristicId, $vehiclePrice, 10); 
 
        $vehicleService->addViews($vehicleEm); 
        $featuresIds = $this->vehicleService->getFeatures($this->getUser()); 
 
        $creditPayment = $creditModel->getMinPayment($vehicleEntity); 
        $leasingPayment = $leasingClient->getFirstAnnuitetData($vehicleEntity->fullPrice(), $vehicleEntity->getVehicleType()); 
 
        return $this->basePortalRender('@Portal/Car/new-in-stock-card-car.html.twig', [ 
            'vehicle' => $vehicle, 
            'vehicleInStock' => $vehicleInStock, 
            'countModelInStock' => $countModelInStock, 
            'vehicleUsed' => $vehicleUsed, 
            'vehicleBodyType' => $vehicleBodyType, 
            'creditPayment' => $creditPayment, 
            'leasingPayment' => $leasingPayment->payment, 
            'dealer' => $dealer, 
            'type' => $vehicleTypeData['url'], 
            'state' => 'new', 
            'featuredId' => $featuresIds[$vehicle->getVehicleItemId()] ?? null, 
            'comparedId' => $this->vehicleService->getComparison($vehicleEntity), 
            'leasingCalculatorForm' => $this->CoreFormFactory()->leasingForm()->createView(), 
            'buyForm' => $this->CoreFormFactory() 
                ->buyForm($buyForm, $vehicleEm, $vehicle->getVehicleItemId(), null, false, true)->createView(), 
        ]); 
    } 
 
    public function vehicleUsed(Request $request, \CoreBundle\Factory\Vehicle $vehicleFactory, 
                                VehicleViewService $vehicleViewService, CreditModel $creditModel, LeasingClient $leasingClient): Response 
    { 
 
        $vehicle = $vehicleFactory->createUsedByUrl($request->get('url')); 
 
        if(!$vehicle) { 
            throw new NotFoundHttpException(); 
        } 
 
        $vehicleViewService->saveViewVehicle($vehicle, $request->getClientIp(), new DateTime()); 
 
        $buyForm = new Forms(); 
 
        $vehicleTypeData = VehicleType::getTypeDataById($vehicle->getVehicleType()); 
 
        $dealer = $vehicle->getDealer(); 
 
        $vehicleEm = $vehicle->getVehicleEntity(); 
 
        $characteristicId = ($vehicle->getBodyType())? $vehicle->getBodyType()->getId() : null; 
 
        $vehicleInStock = $this->vehicleService->getVehicleInStock($vehicleEm->getModel(), $this->getUser(), $dealer, 6); 
        $vehicleUsed = $this->vehicleService->getVehicleUsed($vehicleEm->getModel(), $this->getUser(), 6); 
        $price = $vehicle->Price(); 
 
        $vehicleBodyType = $this->vehicleService->getVehicleByCharacteristicId($this->getUser(), $characteristicId, true,100, $price, null, 11); 
        $featuresIds = $this->vehicleService->getFeatures($this->getUser()); 
 
        $creditPayment = $creditModel->getMinPayment($vehicle); 
        $leasingPayment = $leasingClient->getFirstAnnuitetData($vehicle->fullPrice(), $vehicle->getVehicleType()); 
 
        return $this->basePortalRender('@Portal/Car/new-used-card-car.html.twig', [ 
            'vehicle' => $vehicle, 
            'vehicleInStock' => $vehicleInStock, 
            'vehicleUsed' => $vehicleUsed, 
            'vehicleBodyType' => $vehicleBodyType, 
            'creditPayment' => $creditPayment, 
            'leasingPayment' => $leasingPayment->payment, 
            'dealer' => $dealer, 
            'type' => $vehicleTypeData['url'], 
            'state' => 'new', 
            'featuredId' =>  $featuresIds[$vehicle->getVehicleItemId()] ?? null, 
            'comparedId' => $this->vehicleService->getComparison($vehicle), 
            'leasingCalculatorForm' => $this->CoreFormFactory()->leasingForm()->createView(), 
            'buyForm' => $this->CoreFormFactory()->buyForm($buyForm, $vehicleEm, $vehicle->getVehicleItemId(), null, true, false, $vehicle->getPrice())->createView(), 
            'orderTestDriveForm' => $this->CoreFormFactory()->buyForm($buyForm, $vehicleEm, $vehicle->getVehicleItemId())->createView(), 
            'hasNds' => $vehicle->getHasNds(), 
            'isSelect' => !in_array($vehicle->getDealer()->getId(), Catalog::NOT_VIDI_SELECT_DEALERS), 
        ]); 
    } 
 
    public function catalog(Request $request, \CoreBundle\Factory\Vehicle $vehicleFactory): Response 
    { 
        throw $this->createNotFoundException(); 
        $carsCookie = $request->cookies->get('viewed-cars'); 
        $models = []; 
 
        if ($carsCookie) { 
            $carsId = explode(',', $carsCookie); 
            foreach ($carsId as $oneId) { 
                if (count($models) >= 2) continue; 
                if (!($Car = $vehicleFactory->createById($oneId))) { 
                    continue; 
                } 
                $models[] = $Car; 
            } 
        } 
 
        return $this->basePortalRender('@Portal/Car/catalog.html.twig', [ 
            'vModels' => $models, 
        ]); 
    } 
 
    /** 
     * @param Request $request 
     * @return Response 
     * @throws OptimisticLockException 
     */ 
    public function usedCar(Request $request, \CoreBundle\Factory\Vehicle $vehicleFactory, EntityManagerInterface $em, 
                            HistoryManager $historyManager, Breadcrumbs $breadcrumbs): Response 
    { 
        $url = $request->get('url'); 
        $CarModel = $vehicleFactory->createUsedByUrl($url); 
        if (!$CarModel) { 
            throw new NotFoundHttpException(); 
        } 
        $CarModel->getVehicleEntity()->setViews((int)$CarModel->getVehicleEntity()->getViews() + 1); 
        $em->persist($CarModel->getVehicleEntity()); 
        $em->flush(); 
        $historyManager->setUserCarHistory($this->getUser(), $CarModel->getVehicleEntity()); 
 
        $carsCookie = $request->cookies->get('viewed-cars'); 
 
        $models = []; 
        $carsId = []; 
        if ($carsCookie) { 
            $carsId = explode(',', $carsCookie); 
            foreach ($carsId as $oneId) { 
                if ($CarModel->getVehicleId() == $oneId) { 
                    continue; 
                } 
                //TODO remove magic numbers 
                if (count($models) >= 2) { 
                    continue; 
                } 
                $car = $vehicleFactory->createById($oneId); 
                if (!$car) { 
                    continue; 
                } 
                $models[] = $car; 
            } 
        } 
        //TODO remove magic numbers 
        if (!in_array($CarModel->getVehicleId(), $carsId)) { 
            if (count($carsId) >= 2) { 
                $carsId = array_slice($carsId, 0, 1); 
            } 
            $carsId[] = $CarModel->getVehicleId(); 
        } 
 
        $Response = new Response(); 
        if ($carsId) { 
            $cookie = new Cookie('viewed-cars', implode(',', $carsId)); 
            $Response->headers->setCookie($cookie); 
        } 
 
        $creditPaymentDisabled = false; 
        $TdForm = new Forms(); 
        $TdForm->setVehicle($CarModel->getVehicleEntity()); 
 
        return $this->basePortalRender( 
            '@Portal/Car/used-car.html.twig', 
            array_merge( 
                ['forms' => $this->buildCarForms($CarModel)], 
                [ 
                    'model' => $CarModel, 
                    'tdForm' => 
                        $this->CoreFormFactory() 
                            ->testDriveForm($CarModel->getDealer(), $TdForm, ['is_used' => true]) 
                            ->createView(), 
                    'creditForm' => $this->CoreFormFactory()->creditForm($CarModel->getDealer())->createView(), 
                    'vModels' => $models, 
                    'creditPayment' => $creditPaymentDisabled, 
                    'options' => [], 
                    'breadcrumbs' => $breadcrumbs->generateByCarCard($CarModel), 
                ] 
            ), 
            $Response 
        ); 
    } 
 
    public function inStockOne(Request $request, EntityManagerInterface $em, InStockVehicle $inStockVehicleFactory): Response 
    { 
        $dealer = $em 
            ->getRepository(Dealer::class) 
            ->findOneBy(['url' => $request->get('dealer')]); 
        if (!$dealer) { 
            throw $this->createNotFoundException(); 
        } 
        /** @var Dealer $dealer */ 
        $inStockVehicle = $inStockVehicleFactory->createByUrl($request->get('url'), $dealer); 
        if (!$inStockVehicle) { 
            throw $this->createNotFoundException(); 
        } 
        //TODO remove magic numbers 
        $posts['used'] = $em->getRepository(Post::class)->getUsedCarActions(3); 
        $posts['service'] = $em->getRepository(Post::class)->getServiceActions(3); 
        $posts['new'] = $em->getRepository(Post::class)->getNewCarActions(3); 
 
        $BuyForm = new Forms(); 
        $TdForm = new Forms(); 
        $TdForm->setVehicle($inStockVehicle->getVehicle()); 
        $BuyForm->setVehicle($inStockVehicle->getVehicle()); 
 
        return $this->basePortalRender('@Portal/Car/in-stock-card-car.html.twig', [ 
            'model' => $inStockVehicle, 
            'buyForm' => 
                $this->CoreFormFactory() 
                    ->buyForm($BuyForm, $inStockVehicle->getVehicle(), $inStockVehicle->getVehicleItemId()) 
                    ->createView(), 
            'testDrivePageForm' => 
                $this->CoreFormFactory() 
                ->testDriveForm($inStockVehicle->getDealer(), $TdForm) 
                ->createView(), 
            'creditForm' => $this->CoreFormFactory()->creditForm($inStockVehicle->getDealer())->createView(), 
            'dealer' => $dealer, 
            'posts' => $posts, 
            'leasingCalculatorForm' => $this->CoreFormFactory()->leasingForm()->createView(), 
        ]); 
    } 
 
    public function archive(\CoreBundle\Factory\Vehicle $vehicleFactory): Response 
    { 
        $vehicles = $this->vehicleRepository->getAllDisabled(); 
        $result = []; 
        foreach ($vehicles as $vehicle) { 
            $model = $vehicleFactory->createByEntity($vehicle); 
            if (!$model) { 
                continue; 
            } 
            $result[] = $model; 
        } 
        return $this->basePortalRender('@Portal/Car/archive.html.twig', ['cars' => $result]); 
    } 
}