<?php
/**
 * OBG Customizations
 *
 * Copyright (c) 2021 vonRotenberg
 *
 * @license commercial
 */

namespace vonRotenberg\RealEstateListingBundle\Controller\FrontendModule;

use Contao\CoreBundle\DependencyInjection\Attribute\AsFrontendModule;
use Contao\CoreBundle\Exception\ResponseException;
use Contao\CoreBundle\Image\Studio\Studio;
use Contao\CoreBundle\Twig\FragmentTemplate;
use Contao\Input;
use Contao\ModuleModel;
use Contao\PageModel;
use Contao\StringUtil;
use Contao\System;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Contracts\Translation\TranslatorInterface;

#[AsFrontendModule(RealEstateAssetsListController::TYPE, category: 'miscellaneous')]
class RealEstateAssetsListController extends RealEstateAssetsModuleController
{
    public const TYPE = 'vr_re_assets_list';

    /**
     * @var TranslatorInterface
     */
    protected $translator;

    public function __construct(TranslatorInterface $translator)
    {
        $this->translator = $translator;
    }

    protected function getResponse(FragmentTemplate $template, ModuleModel $model, Request $request): Response
    {
        $arrGroups = [];
        $arrFilterOptions = [
            'numberOfRooms' => [],
            'coldRent' => [],
            'livingSpace' => [],
            'city' => []
        ];
        $arrFilterSelected = [];
        $arrAssetsOptions = [];

        $jumpTo = PageModel::findByPk($model->jumpTo);
        $urlGenerator = System::getContainer()->get('contao.routing.content_url_generator');

        // Filter
        if (isset($_GET['filter']) && \is_array(Input::get('filter')))
        {
            foreach (Input::get('filter') as $filter=>$value)
            {
                if (in_array($filter, array_keys($arrFilterOptions)) && !empty($value))
                {
                    $rawValue = StringUtil::decodeEntities($value);
                    $arrFilterSelected[$filter] = $rawValue;

                    if (preg_match('/^.*<>.*$/',$rawValue))
                    {
                        list($start,$stop) = preg_split('/<>/',$rawValue, 2);
                        $arrAssetsOptions['column'][$filter] = "$filter BETWEEN $start AND $stop";
                    } else {
                        if ($filter == 'city')
                        {
                            $arrAssetsOptions['column'][$filter] = "($filter = ? AND managedPropertyId < 1) OR ? IN (SELECT p.city FROM tl_vr_re_managedProperties p WHERE p.id = managedPropertyId)";
                            $arrAssetsOptions['value'][$filter.'_sq'] = $rawValue;
                        } else
                        {
                            $arrAssetsOptions['column'][$filter] = "$filter = ?";
                        }
                        $arrAssetsOptions['value'][$filter] = $rawValue;
                    }
                }
            }
        }

        if (($assets = $this->getRealEstateAssets(StringUtil::deserialize($model->vr_re_categories),$arrAssetsOptions)) === null)
        {
            return $template->getResponse();
        }

        // Figure Builder
        $figureBuilder = System::getContainer()
            ->get('contao.image.studio')
            ->createFigureBuilder()
            ->setSize($model->imgSize)
            ->setLightboxGroupIdentifier('lb' . $model->id);

        foreach ($assets as $asset)
        {
            $strUrl = $jumpTo !== null ? $urlGenerator->generate($jumpTo, ['parameters'=>'/items/'.($asset->alias ?: $asset->id)]) : null;
            $figureBuilder->setLinkHref($strUrl);
            $arrItem = array_merge($asset->row(), [
                'teaserFigure' => $this->getImageFigures($asset->gallerySRC, $figureBuilder, $asset->orderSRC, 1),
                'detailsUrl'   => $strUrl,
                'hasProperty' => false
            ]);
            $figureBuilder->setLinkHref(null);

            // Check for object
            if (($Property = $asset->getRelated('managedPropertyId')) !== null) {
                $arrItem['hasProperty'] = true;
                $arrItem['property'] = array_merge($Property->row(),[
                    'teaserFigure'      => $this->getImageFigures($Property->gallerySRC, $figureBuilder, $Property->orderSRC, 1),
                    'galleryFigures'    => $this->getImageFigures($Property->gallerySRC, $figureBuilder, $Property->orderSRC, 0, 0),
                ]);
            }

            // Grouping
            if ($model->vr_re_grouped)
            {
                if (!isset($arrGroups[$arrItem['pid']]))
                {
                    $Group = $asset->getRelated('pid');
                    $arrGroups[$arrItem['pid']] = [
                        'label' => $Group->title,
                        'items' => []
                    ];
                }

                $arrGroups[$arrItem['pid']]['items'][] = $arrItem;
            } else {
                $arrGroups['nogroup']['items'][] = $arrItem;
            }
        }

        // Populate filters
        $filterAssets = $this->getRealEstateAssets(StringUtil::deserialize($model->vr_re_categories));
        foreach ($filterAssets as $asset)
        {
            // Filter options
            if (!empty($asset->numberOfRooms))
            {
                $tmpOptions = $arrAssetsOptions;
                $tmpOptions['column'] = array_merge((isset($arrAssetsOptions['column']) ? $arrAssetsOptions['column'] : []),['numberOfRooms'=>'numberOfRooms = ?']);
                $tmpOptions['value'] = array_merge((isset($arrAssetsOptions['value']) ? $arrAssetsOptions['value'] : []),['numberOfRooms'=>$asset->numberOfRooms]);
                $count = $this->countRealEstateAssets(StringUtil::deserialize($model->vr_re_categories),$tmpOptions);
                if ($count > 0)
                {
                    $arrFilterOptions['numberOfRooms'][$asset->numberOfRooms] = $asset->numberOfRooms . ' ' . ($asset->numberOfRooms > 1 ? $this->translator->trans('MSC.re_rooms', [], 'contao_default') : $this->translator->trans('MSC.re_room', [], 'contao_default')) . ' ('.$count.')';
                }
            }
            if (!empty($asset->city))
            {
                $strCity = $asset->city;

                // Check for object
                if (($Property = $asset->getRelated('managedPropertyId')) !== null) {
                    $strCity = $Property->city;
                }

                $tmpOptions = $arrAssetsOptions;
                $tmpOptions['column'] = array_merge((isset($arrAssetsOptions['column']) ? $arrAssetsOptions['column'] : []),['city'=>'(city = ? AND managedPropertyId < 1) OR ? IN (SELECT p.city FROM tl_vr_re_managedProperties p WHERE p.id = managedPropertyId)']);
                $tmpOptions['value'] = array_merge((isset($arrAssetsOptions['value']) ? $arrAssetsOptions['value'] : []),['city'=>$strCity,'city_sq'=>$strCity]);
                $count = $this->countRealEstateAssets(StringUtil::deserialize($model->vr_re_categories),$tmpOptions);
                if ($count > 0)
                {
                    $arrFilterOptions['city'][$strCity] = $strCity . ' (' . $count . ')';
                }
            }
            if (!empty($asset->coldRent))
            {
                $rangeStart = floor($asset->coldRent / 100) * 100;
                $rangeEnd = $rangeStart + 99;
                $tmpOptions = $arrAssetsOptions;
                $tmpOptions['column'] = array_merge((isset($arrAssetsOptions['column']) ? $arrAssetsOptions['column'] : []),['coldRent'=>"coldRent BETWEEN $rangeStart AND $rangeEnd"]);
                $count = $this->countRealEstateAssets(StringUtil::deserialize($model->vr_re_categories),$tmpOptions);
                if ($count > 0)
                {
                    $arrFilterOptions['coldRent'][$rangeStart.'<>'.$rangeEnd] = $rangeStart . ' - ' . $rangeEnd . ' €' . ' ('.$count.')';
                }
            }
            if (!empty($asset->livingSpace))
            {
                $rangeStart = floor($asset->livingSpace / 10) * 10;
                $rangeEnd = $rangeStart + 9;
                $tmpOptions = $arrAssetsOptions;
                $tmpOptions['column'] = array_merge((isset($arrAssetsOptions['column']) ? $arrAssetsOptions['column'] : []),['livingSpace'=>"livingSpace BETWEEN $rangeStart AND $rangeEnd"]);
                $count = $this->countRealEstateAssets(StringUtil::deserialize($model->vr_re_categories),$tmpOptions);
                if ($count > 0)
                {
                    $arrFilterOptions['livingSpace'][$rangeStart.'<>'.$rangeEnd] = $rangeStart . ' - ' . $rangeEnd . ' m²' . ' ('.$count.')';
                }
            }
        }

        foreach (array_keys($arrFilterOptions) as $filterName)
        {
            $arrFilterOptions[$filterName] = array_unique($arrFilterOptions[$filterName]);
        }

        // Set template data
        $template->set('filterOptions',$arrFilterOptions);
        $template->set('filter',$arrFilterSelected);
        $template->set('groups',$arrGroups);

        // Handle ajax
        if ($request->headers->get('VR-Ajax') == 'ReAssetsList')
        {
            throw new ResponseException($template->getResponse());
        }

        return $template->getResponse();
    }

}
