- <?php
- namespace PortalBundle\Controller;
- use CoreBundle\Component\CoreFormFactory;
- use CoreBundle\Entity\Dealer;
- use CoreBundle\Entity\Vehicles\InStock;
- use CoreBundle\Entity\Vehicles\RecommendGroup;
- use CoreBundle\Factory\InStockVehicle;
- use CoreBundle\Model\Vehicles\Repository;
- use CoreBundle\Model\Vehicles\Vehicle;
- use CoreBundle\Model\Vehicles\VehicleType;
- use DcSiteBundle\Model\Pagination;
- use Doctrine\ORM\EntityManagerInterface;
- use Exception;
- use PortalBundle\Model\Catalog;
- use PortalBundle\Model\SeoMetaTag;
- use PortalBundle\Services\CatalogService;
- use PortalBundle\Services\ServiceService;
- use PortalBundle\Services\VehicleFilterService;
- use Symfony\Component\HttpFoundation\JsonResponse;
- 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 StockController extends BaseController
- {
-     private Catalog $modelCatalog;
-     private CatalogService $catalogService;
-     private InStockVehicle $inStockVehicle;
-     private SeoMetaTag $seoMetaTag;
-     public function __construct(CoreFormFactory $coreFormFactory, RequestStack $requestStack,
-                                 RouterInterface $router, Repository $vehicleRepository, ServiceService $serviceService,
-                                 Catalog         $modelCatalog, CatalogService $catalogService, InStockVehicle $inStockVehicle,
-                                 SeoMetaTag      $seoMetaTag)
-     {
-         parent::__construct($coreFormFactory, $requestStack, $router, $vehicleRepository, $serviceService);
-         $this->modelCatalog = $modelCatalog;
-         $this->catalogService = $catalogService;
-         $this->inStockVehicle = $inStockVehicle;
-         $this->seoMetaTag = $seoMetaTag;
-     }
-     const PRE_PAGES = 15;
-     const MAX_PAGINATION_BUTTON = 5;
-     /**
-      * @param Request $request
-      * @return Response
-      * @throws Exception
-      */
-     public function inStock(Request $request, Pagination $paginationModel, EntityManagerInterface $em)
-     {
-         $routeParams = $request->attributes->get('_route_params');
-         $routeParams['brand'] = $request->query->all('brand');
-         $routeParams['model'] = $request->query->all('model');
-         $params = $request->query->all();
-         $param = null;
-         $value = null;
-         $model = '';
-         $brand = '';
-         $type = $request->get('type');
-         $state = $request->get('state');
-         if ($request->get('m-brand')) {
-             $brand = array_key_first($request->get('m-brand'));
-         }
-         if ($request->get('m-model')) {
-             $model = array_key_first($request->get('m-model'));
-         }
-         if (isset($params['dynamic'])) {
-             $param = array_key_first($params['dynamic']);
-             if (isset($params['dynamic'][$param])) {
-                 $value = array_key_first($params['dynamic'][$param]);
-             }
-         }
-         if ($brand && $brand === 'all') {
-             throw new NotFoundHttpException();
-         }
-         $vehicles = $this->modelCatalog->findStockByParams($routeParams, $params, self::PRE_PAGES);
-         $allBrands = $em->getRepository(InStock::class)->gatAllBrands();
-         if (!$vehicles['data']) {
-             $vehicles = $this->modelCatalog->noFindStockVehicleByParams($routeParams, $params, self::PRE_PAGES);
-         }
-         /** @var InStock $vehicle */
-         $result = [];
-         foreach ($vehicles['data'] as $vehicle) {
-             $inStockModel = $this->inStockVehicle->createByEntity($vehicle[0]);
-             $vehicle = $this->modelCatalog->getInStockVehicleByCatalog($this->getUser(), $inStockModel);
-             $result[] = $vehicle;
-         }
-         $typeData = VehicleType::getTypeDataByUrl($type);
-         if (!$typeData) {
-             throw new NotFoundHttpException();
-         }
-         $vehicleTypeId = $typeData['id'];
-         $catalogNav = $this->modelCatalog->getStockCatalogNav($type, $state, $brand, $params, $value);
-         $brandEm = $em->getRepository(\CoreBundle\Entity\Brand::class)->getBrandByUrl($brand);
-         $pagination = $paginationModel->initPagination($vehicles['count'], self::PRE_PAGES, 5);
-         $filters = $this->catalogService->getFilters($params, $request->getLocale(), $state, $vehicleTypeId, $brand, $model, $param, $value, $routeParams);
-         $catalogCharacteristic = $this->catalogService->catalogCharacteristic($vehicleTypeId, false);
-         $dealers = $em->getRepository(Dealer::class)->getDealerByBrandUrl($brandEm);
-         $dealers = array_filter($dealers, fn($dealer) => $dealer->getId() !== 39 && $dealer->getId() !== 16);
-         return $this->basePortalRender('@Portal/Car/new-in-stock-catalog.html.twig', [
-             'count' => $vehicles['count'],
-             'result' => $result,
-             'allBrands' => $allBrands,
-             'filters' => $filters,
-             'perPage' => self::PRE_PAGES,
-             'type' => $type,
-             'state' => $state,
-             'baseParams' => $routeParams,
-             'searchParams' => $params,
-             'catalogNav' => $catalogNav,
-             'pagination' => $pagination,
-             'page' => $request->query->get('page') ?: 1,
-             'dealers' => $dealers,
-             'locale' => $request->getLocale(),
-             'seoMeta' => $this->seoMetaTag->buildSeoMetaGetParams($request, $routeParams, $params, $param, $value),
-             'brand' => $brand,
-             'model' => $model,
-             'param' => $param,
-             'value' => $value,
-             'year' => ($param === 1000) ? $param : $value,
-             'seo_year' => date('Y'),
-             'valueParam' => $catalogCharacteristic[$param][$value] ?? null,
-             'userId' => $this->getUser()
-                 ? $this->getUser()->getId()
-                 : null,
-         ]);
-     }
-     public function inStockApi(Request $request, Pagination $paginationModel, InStockVehicle $inStockVehicle)
-     {
-         $routeParams = $request->attributes->get('_route_params');
-         $routeParams['brand'] = $request->query->get('brand');
-         $routeParams['model'] = $request->query->get('model');
-         $params = $request->query->all();
-         $param = null;
-         $value = null;
-         $model = '';
-         $brand = '';
-         $type = $request->get('type');
-         $state = $request->get('state');
-         if ($request->get('m-brand')) {
-             $brand = array_key_first($request->get('m-brand'));
-         }
-         if ($request->get('m-model')) {
-             $model = array_key_first($request->get('m-model'));
-         }
-         if (isset($params['dynamic'])) {
-             $param = array_key_first($params['dynamic']);
-             if (isset($params['dynamic'][$param])) {
-                 $value = array_key_first($params['dynamic'][$param]);
-             }
-         }
-         if ($brand && $brand === 'all') {
-             throw new NotFoundHttpException();
-         }
-         $vehicles = $this->modelCatalog->findStockByParams($routeParams, $params, self::PRE_PAGES);
-         if (!$vehicles['data']) {
-             $vehicles = $this->modelCatalog->noFindStockVehicleByParams($routeParams, $params, self::PRE_PAGES);
-         }
-         /** @var InStock $vehicle */
-         $result = [];
-         foreach ($vehicles['data'] as $vehicle) {
-             $inStockModel = $inStockVehicle->createByEntity($vehicle[0]);
-             $vehicle = $this->modelCatalog->getInStockVehicleByCatalog($this->getUser(), $inStockModel);
-             $result[] = $vehicle;
-         }
-         $typeData = VehicleType::getTypeDataByUrl($type);
-         if (!$typeData) {
-             throw new NotFoundHttpException();
-         }
-         $vehicleTypeId = $typeData['id'];
-         $pagination = $paginationModel->initPagination($vehicles['count'], self::PRE_PAGES, 5);
-         $filters = $this->catalogService->getFilters($params, $request->getLocale(), $state, $vehicleTypeId, $brand, $model, $param, $value, $routeParams);
-         if ($request->isXmlHttpRequest()) {
-             return $this->json([
-                 'vehicles' => $this->catalogService->getStockAjaxResult($result, $request->getLocale()),
-                 'pagination' => $pagination,
-                 'count' => $vehicles['count'],
-                 'searchFilters' => $filters
-             ]);
-         }
-         return false;
-     }
-     /**
-      * @param Request $request
-      * @return JsonResponse
-      */
-     public function buildStockFilters(Request $request): JsonResponse
-     {
-         $filters = $this->modelCatalog->buildStockFilters($request->request->all(), $request->getLocale());
-         return $this->json($filters);
-     }
-     /**
-      * @param Request $request
-      * @return JsonResponse
-      */
-     public function buildUrl(Request $request)
-     {
-         $params = $request->request->all();
-         $type = $params['type'];
-         $state = $params['state'];
-         $brand = $params['brand'] ?? null;
-         $model = $params['model'] ?? null;
-         $isAjax = $params['isAjax'] ?? null;
-         if (is_array($brand) && count($brand) == 1) {
-             $brand = array_keys($brand)[0];
-         }
-         if (is_array($model) && count($model) == 1) {
-             $model = array_keys($model)[0];
-         }
-         $baseRouteParams = [
-             'type' => $type,
-             'state' => $state,
-         ];
-         $getParams = [];
-         foreach ($params as $key => $row) {
-             if (!in_array($key, ['type', 'state', 'brand', 'model', 'dynamic']) && $row) {
-                 $getParams[$key] = $row;
-             }
-         }
-         $getParams['hasNDS'] = true;
-         $getParams['isSelect'] = true;
-         $getParams['inStock'] = true;
-         if (is_array($brand)) {
-             $getParams['m-brand'] = $brand;
-             $brand = null;
-         } else if ($brand) {
-             $getParams['m-brand'] = [$brand => true];
-         }
-         if (is_array($model)) {
-             $getParams['m-model'] = $model;
-             $model = null;
-         } else if ($model) {
-             $getParams['m-model'] = [$model => true];
-             $model = null;
-         }
-         $dynamic = [];
-         if (isset($params['dynamic'])) {
-             foreach ($params['dynamic'] as $id => $values) {
-                 if (array_key_exists('from', $values) || array_key_exists('to', $values)) {
-                     $dynamic[$id] = $values;
-                 } else {
-                     foreach ($values as $url => $v) {
-                         if ($v != 'false') {
-                             $dynamic[$id][$url] = 1;
-                         }
-                     }
-                 }
-             }
-         }
-         $catalogCharacteristic = array_flip($this->modelCatalog->getCatalogCharacteristicsId());
-         if (!$brand && !$model && (!count($dynamic) || empty(array_intersect_key($dynamic, $catalogCharacteristic)))) {
-             $url = $this->router->generate(
-                     'portal_in_stock_filter_catalog',
-                     array_merge($baseRouteParams, $getParams, ['dynamic' => $dynamic])
-                 );
-             $apiUrl = $this->router->generate(
-                     'portal_in_stock_filter_catalog_api',
-                     array_merge($baseRouteParams, $getParams, ['dynamic' => $dynamic])
-                 );
-             return $this->json(['url' => $url, 'apiUrl' => $apiUrl]);
-         }
-         if (!$brand && !$model && count($dynamic)) {
-             $dId = key($dynamic);
-             $value = key($dynamic[$dId]);
-             if (!count($dynamic[$dId])) {
-                 unset($dynamic[$dId]);
-             }
-             $url = $this->router->generate(
-                     'portal_in_stock_filter_catalog',
-                     array_merge($baseRouteParams, $getParams, ['dynamic' => $dynamic])
-                 );
-             $apiUrl = $this->router->generate(
-                     'portal_in_stock_filter_catalog_api',
-                     array_merge($baseRouteParams, $getParams, ['dynamic' => $dynamic])
-                 );
-             return $this->json(['url' => $url, 'apiUrl' => $apiUrl]);
-         }
-         if ($model) {
-             $baseRouteParams['model'] = $model;
-             $baseRouteParams['brand'] = $brand;
-             $url = $this->router->generate(
-                     'portal_in_stock_filter_catalog',
-                     array_merge($baseRouteParams, $getParams, ['dynamic' => $dynamic])
-                 );
-             $apiUrl = $this->router->generate(
-                     'portal_in_stock_filter_catalog_api',
-                     array_merge($baseRouteParams, $getParams, ['dynamic' => $dynamic])
-                 );
-             return $this->json(['url' => $url, 'apiUrl' => $apiUrl]);
-         }
-         if ($brand) {
-             $baseRouteParams['brand'] = $brand;
-             $url = $this->router->generate(
-                     'portal_in_stock_filter_catalog',
-                     array_merge($baseRouteParams, $getParams, ['dynamic' => $dynamic])
-                 );
-             $apiUrl = $this->router->generate(
-                     'portal_in_stock_filter_catalog_api',
-                     array_merge($baseRouteParams, $getParams, ['dynamic' => $dynamic])
-                 );
-             return $this->json(['url' => $url, 'apiUrl' => $apiUrl]);
-         }
-     }
-     public function catalogCategory(Request $request, $url, EntityManagerInterface $em, \CoreBundle\Factory\Vehicle $vehicleFactory): Response
-     {
-         $dealers = $em->getRepository(Dealer::class)->getCarDealer();
-         $recommends = $em->getRepository(RecommendGroup::class)->findBy(['state' => 1]);
-         $recommendGroup = $em->getRepository(RecommendGroup::class)->findOneBy(['url' => $url]);
-         $recommendGroupVehicles = $em->getRepository(\CoreBundle\Entity\Vehicles\Vehicle::class)->getVehicleByRecommendGroupUrl(['url' => $url]);
-         $vehicles = $vehicleFactory->createByEntities($recommendGroupVehicles);
-         $sort = $request->get('sort');
-         usort($vehicles, function (Vehicle $a, Vehicle $b) use ($sort) {
-             switch ($sort) {
-                 case 'price-DESC':
-                     return $a->fullPrice() < $b->fullPrice();
-                 default:
-                     return $a->fullPrice() > $b->fullPrice();
-             }
-         });
-         $seoMeta = [];
-         $urn = preg_replace('/^(\/?ua\/|\/?ru\/)/', '/', $request->getRequestUri());
-         $seo = $em->getRepository(\CoreBundle\Entity\SeoMetaTag::class)->findOneBy(['domain' => $request->getHost(), 'urn' => $urn]);
-         if ($seo && $seo->getState()) {
-             $seoMeta = [
-                 'title' => $seo->getTitle($request->getLocale()),
-                 'description' => $seo->getDescription($request->getLocale()),
-                 'h1' => $seo->getH1($request->getLocale()),
-                 'robots' => $seo->getRobots(),
-             ];
-         }
-         return $this->basePortalRender('@Portal/Car/category.html.twig', [
-             'dealers' => $dealers,
-             'recommends' => $recommends,
-             'recommendGroup' => $recommendGroup,
-             'vehicles' => $vehicles,
-             'url' => $url,
-             'seoMeta' => $seoMeta,
-         ]);
-     }
-     //TODO remove this magic numbers
-     private function createPaginator($data, $page = 1, $limit = 21): array
-     {
-         $maxPages = 10;
-         $paginator = [
-             'total' => ceil(count($data) / $limit),
-             'current' => $page,
-         ];
-         if ($paginator['total'] > $maxPages && $page > floor($maxPages / 2)) {
-             $paginator['start'] = $page - floor($maxPages / 2);
-             $paginator['end'] = $paginator['start'] + $maxPages - 1;
-         } else {
-             $paginator['start'] = 1;
-             $paginator['end'] = min($paginator['total'], $maxPages);
-         }
-         return $paginator;
-     }
-     public function getChangeFilter(VehicleFilterService $vehicleFilterService): JsonResponse
-     {
-         return $this->json(['success' => true, 'filter' => $vehicleFilterService->initFilter()]);
-     }
-     public function initVehicleFilterUrl(VehicleFilterService $vehicleFilterService): JsonResponse
-     {
-         return $this->json(['success' => true, 'filterUrl' => $vehicleFilterService->getUrl()]);
-     }
-     public function vehicleColor(): JsonResponse
-     {
-         return $this->json([
-             'success' => true,
-             'image' => $this->modelCatalog->getVehicleImageColor(),
-         ]);
-     }
- }
-