<?php 
 
namespace PortalBundle\Services; 
 
use CoreBundle\Entity\Brand; 
use CoreBundle\Entity\Dealer; 
use CoreBundle\Entity\Featured; 
use CoreBundle\Entity\Model; 
use CoreBundle\Entity\Vehicles\InStock; 
use CoreBundle\Entity\Vehicles\Vehicle; 
use CoreBundle\Factory\Vehicle as VehicleFactory; 
use CoreBundle\Model\Vehicles\AbstractVehicle; 
use CoreBundle\Model\Vehicles\VehicleType; 
use CoreBundle\Services\MediaExtensionVidi; 
use DcSiteBundle\Model\CreditModel; 
use Doctrine\ORM\EntityManagerInterface; 
use PortalBundle\Model\Catalog; 
use Symfony\Component\HttpFoundation\RequestStack; 
use Symfony\Component\Routing\RouterInterface; 
 
class VehicleService 
{ 
private EntityManagerInterface       $em; 
private RouterInterface             $router; 
private MediaExtensionVidi  $mediaExtension; 
private VehicleFactory      $vehicleFactory; 
private RequestStack        $requestStack; 
private CreditModel         $creditModel; 
    public function __construct( 
        EntityManagerInterface       $em, 
        RouterInterface             $router, 
        MediaExtensionVidi  $mediaExtension, 
        VehicleFactory      $vehicleFactory, 
        RequestStack        $requestStack, 
        CreditModel         $creditModel 
    ) 
    { 
        $this->em = $em; 
        $this->router = $router; 
        $this->mediaExtension = $mediaExtension; 
        $this->vehicleFactory = $vehicleFactory; 
        $this->requestStack = $requestStack; 
        $this->creditModel = $creditModel; 
    } 
 
    public function getVehicles() 
    { 
    } 
 
    public function getComparison(AbstractVehicle $vehicle) 
    { 
        $request = $this->requestStack->getCurrentRequest(); 
        $compareCookie = $request->cookies->get('compare'); 
        $vehicleComparison = explode(',', $compareCookie); 
 
        return in_array($vehicle->getVehicleItemId(),$vehicleComparison)? $vehicle->getVehicleItemId() : null; 
 
    } 
    public function getFeatures($user): array 
    { 
        $featuresIds = []; 
 
        if(!$user){ 
            return $featuresIds; 
        } 
 
        $features = $this->em->getRepository(Featured::class)->findBy(['type' => 'vehicle', 'user' => $user]); 
 
        /** @var Featured $feature */ 
        foreach ($features as $feature) { 
            $favData = json_decode($feature->getData()); 
 
            if(!isset($favData->vehicleItemId)){ 
                continue; 
            } 
            $featuresIds[$favData->vehicleItemId] = $feature->getId(); 
        } 
 
        return $featuresIds; 
    } 
 
    public function getVehicleInStock(Model $model, $user, Dealer $dealer = null,$limit = null) 
    { 
        $inStockVehicles = $this->em->getRepository(InStock::class)->getInStockVehicleByModel($model, $dealer, $limit); 
 
        $featuresIds = $this->getFeatures($user); 
 
        $items = []; 
        /** @var InStock $item */ 
        foreach ($inStockVehicles as $item) { 
            $vehicle = $this->vehicleFactory->createByVehicleItem($item->getVehicleItem()); 
            if (!$vehicle) { 
                continue; 
            } 
 
            $items[] = [ 
                'vehicleType' => VehicleType::getTypeDataById($vehicle->getVehicleType()), 
                'creditPayment' => $this->creditModel->getMinPayment($vehicle), 
                'vehicle' => $vehicle, 
                'link' => $this->router->generate('portal_in_stock_one',['dealer' => $vehicle->getDealer()->getUrl(), 'url' => $item->getUrl()]), 
                'featuredId' => $featuresIds[$vehicle->getVehicleItemId()] ?? null, 
                'comparedId' => $this->getComparison($vehicle), 
                'vehiclePrice' => $vehicle->fullPrice(), 
                'vehicleColors' => $this->getVehicleColors($vehicle), 
                'hasNds' => false, 
                'isSelect' => false, 
            ]; 
        } 
 
        return $items; 
    } 
 
    public function getVehicleInStockByBodyType($user, $characteristicId, $price = null, $limit = null) 
    { 
        $inStockVehicles = $this->em->getRepository(InStock::class)->getInStockVehicleByBodyType($characteristicId); 
        $featuresIds = $this->getFeatures($user); 
 
        $items = []; 
        /** @var InStock $item */ 
        foreach ($inStockVehicles as $item) { 
            $vehicle = $this->vehicleFactory->createByVehicleItem($item->getVehicleItem()); 
 
            if (!$vehicle || $item->calcPrice() == 0) { 
                continue; 
            } 
 
            $minPriceRange = $price * 0.8; 
            $maxPriceRange = $price * 1.2; 
            $vehicleItemPrice = $item->calcPrice(); 
 
            if ($vehicleItemPrice < $minPriceRange || $vehicleItemPrice > $maxPriceRange){ 
                continue; 
            } 
 
 
            $items[] = [ 
                'preview' => $item->getPreview(), 
                'vehicleType' => VehicleType::getTypeDataById($vehicle->getVehicleType()), 
                'creditPayment' => $this->creditModel->getMinPayment($vehicle), 
                'vehicle' => $vehicle, 
                'link' => $this->router->generate('portal_in_stock_one',['dealer' => $vehicle->getDealer()->getUrl(), 'url' => $item->getUrl()]), 
                'featuredId' => $featuresIds[$vehicle->getVehicleItemId()] ?? null, 
                'comparedId' => $this->getComparison($vehicle), 
                'vehiclePrice' => $item->calcPrice(), 
                'vehicleColors' => [], 
                'hasNds' => false, 
                'isSelect' => false, 
            ]; 
        } 
 
        return count($items) > $limit ? array_slice($items, 0,$limit) : $items; 
 
    } 
 
    public function getVehicleInStockByBrand(Brand $brand, $user, $vehicleTypeId, $limit) 
    { 
        $inStockVehicles = $this->em->getRepository(InStock::class)->getInStockVehicleByBrand($brand, $vehicleTypeId, $limit); 
        $featuresIds = $this->getFeatures($user); 
 
        $items = []; 
        /** @var InStock $item */ 
        foreach ($inStockVehicles as $item) { 
            $vehicle = $this->vehicleFactory->createByVehicleItem($item->getVehicleItem()); 
 
            if (!$vehicle) continue; 
 
            $items[] = [ 
                'preview' => $item->getPreview(), 
                'vehicleType' => VehicleType::getTypeDataById($vehicle->getVehicleType()), 
                'creditPayment' => $this->creditModel->getMinPayment($vehicle), 
                'vehicle' => $vehicle, 
                'link' => $this->router->generate('portal_in_stock_one',['dealer' => $vehicle->getDealer()->getUrl(), 'url' => $item->getUrl()]), 
                'featuredId' => $featuresIds[$vehicle->getVehicleItemId()] ?? null, 
                'comparedId' => $this->getComparison($vehicle), 
                'vehiclePrice' => $item->calcPrice(), 
                'vehicleColors' => [], 
                'hasNds' => false, 
                'isSelect' => false, 
            ]; 
        } 
 
        return $items; 
    } 
 
    public function getVehicleUsed(Model $model, $user, $limit) 
    { 
        $usedVehicle = $this->em->getRepository(Vehicle::class)->getUsedVehicleByModel($model, $limit); 
 
        $featuresIds = $this->getFeatures($user); 
 
        $items = []; 
        /** @var Vehicle $item */ 
        foreach ($usedVehicle as $item) { 
            $vehicle = $this->vehicleFactory->createUsedById($item->getId()); 
            if (!$vehicle) { 
                continue; 
            } 
 
            $items[] = [ 
                'preview' => $item->getPreview(), 
                'vehicleType' => VehicleType::getTypeDataById($vehicle->getVehicleType()), 
                'creditPayment' => $this->creditModel->getMinPayment($vehicle), 
                'vehicle' => $vehicle, 
                'link' => $this->router->generate('portal_used_car', ['url' => $vehicle->getUrl()]), 
                'featuredId' => $featuresIds[$vehicle->getVehicleItemId()] ?? null, 
                'comparedId' => $this->getComparison($vehicle), 
                'vehiclePrice' => $vehicle->fullPrice(), 
                'vehicleColors' => $this->getVehicleColors($vehicle), 
                'hasNds' => false, 
                'isSelect' => !in_array($vehicle->getDealer()->getId(), Catalog::NOT_VIDI_SELECT_DEALERS), 
            ]; 
        } 
 
        return $items; 
    } 
 
    public function getVehicleUsedByBrand(Brand $brand, $user, $vehicleTypeId, $limit) 
    { 
        $usedVehicle = $this->em->getRepository(Vehicle::class)->getUsedVehicleByBrand($brand, $vehicleTypeId, $limit); 
 
        $featuresIds = $this->getFeatures($user); 
 
        $items = []; 
        /** @var Vehicle $item */ 
        foreach ($usedVehicle as $item) { 
            $vehicle = $this->vehicleFactory->createUsedById($item->getId()); 
            if (!$vehicle) { 
                continue; 
            } 
 
 
 
            $items[] = [ 
                'preview' => $item->getPreview(), 
                'vehicleType' => VehicleType::getTypeDataById($vehicle->getVehicleType()), 
                'creditPayment' => $this->creditModel->getMinPayment($vehicle), 
                'vehicle' => $vehicle, 
                'link' => $this->router->generate('portal_used_car', ['url' => $vehicle->getUrl()]), 
                'featuredId' => $featuresIds[$vehicle->getVehicleItemId()] ?? null, 
                'comparedId' => $this->getComparison($vehicle), 
                'vehiclePrice' => $vehicle->fullPrice(), 
                'vehicleColors' => $this->getVehicleColors($vehicle), 
                'hasNds' => false, 
                'isSelect' => !in_array($vehicle->getDealer()->getId(), Catalog::NOT_VIDI_SELECT_DEALERS), 
            ]; 
        } 
 
        return $items; 
    } 
 
    public function getVehicleByCharacteristicId($user, $characteristicId, $isUsed = false, $limit = null, $price = null, $modelId = null, $limitRangeCount = null): array 
{ 
        $vehicleCharacteristic = $this->em->getRepository(Vehicle::class)->getVehicleByCharacteristicId($characteristicId, null, $isUsed, $limit); 
        $featuresIds = $this->getFeatures($user); 
 
        $items = []; 
        /** @var Vehicle $item */ 
        foreach ($vehicleCharacteristic as $item) { 
            $vehicles = []; 
 
            foreach ($item->getVehicleItems()->filter(fn($vehicleItem) => $vehicleItem->getState()) as $vehicleItem) { 
                $vehicles[] = $this->vehicleFactory->createByVehicleItem($vehicleItem); 
            } 
 
            foreach ($vehicles as $vehicle) { 
                if(!$vehicle || $modelId == $vehicle->getModel()->getId() || $vehicle->price() == 0) { 
                    continue; 
                } 
 
                if ($price){ 
                    $minPriceRange = $price * 0.8; 
                    $maxPriceRange = $price * 1.2; 
                    $vehicleItemPrice = $vehicle->price(); 
 
                    if ($vehicleItemPrice < $minPriceRange || $vehicleItemPrice > $maxPriceRange){ 
                        continue; 
                    } 
                } 
 
                if($isUsed){ 
                    $link = $this->router->generate('portal_used_car', ['dealer' => $vehicle->getDealer()->getUrl(), 'url' => $vehicle->getUrl()]); 
                } else { 
                    $link = $this->router->generate('portal_new_car', ['dealer' => $vehicle->getDealer()->getUrl(), 'url' => $vehicle->getUrl(), 'variation'=> $vehicle->getVehicleItemId()]); 
                } 
 
                $items[] = [ 
                    'preview' => $item->getPreview(), 
                    'vehicleType' => VehicleType::getTypeDataById($vehicle->getVehicleType()), 
                    'creditPayment' => $this->creditModel->getMinPayment($vehicle), 
                    'vehicle' => $vehicle, 
                    'link' => $link, 
                    'featuredId' => $featuresIds[$vehicle->getVehicleItemId()] ?? null, 
                    'comparedId' => $this->getComparison($vehicle), 
                    'vehiclePrice' => $vehicle->price(), 
                    'vehicleColors' => $this->getVehicleColors($vehicle), 
                    'hasNds' => false, 
                    'isSelect' => !in_array($vehicle->getDealer()->getId(), Catalog::NOT_VIDI_SELECT_DEALERS), 
                ]; 
            } 
 
 
        } 
 
        return count($items) > $limitRangeCount ? array_slice($items, 0,$limitRangeCount-1) : $items; 
 
    } 
 
    private function getVehicleColors($vehicle) 
    { 
 
        $vehicleColors = []; 
 
        foreach ($vehicle->getColors() as $color) { 
 
            if (!$color->getState()) { 
                continue; 
            } 
 
            $imageVehicle = $color->getGallery(); 
            if (!$imageVehicle) { 
                continue; 
            } 
 
            $firstImageVehicle = $imageVehicle->getGalleryItems()->first(); 
            if (!$firstImageVehicle) { 
                continue; 
            } 
            $vehicleColors[$color->getId()] = [ 
                'imageColor' => $this->mediaExtension->getPath($color->getImage(), 'reference'), 
                'imageWebpVehicle' => $this->mediaExtension->pathWebp($firstImageVehicle->getMedia(), 'reference'), 
                'imageVehicle' => $this->mediaExtension->getPath($firstImageVehicle->getMedia(), 'reference'), 
            ]; 
        } 
 
        return $vehicleColors; 
 
    } 
}