<?php

namespace FiloBlu\Storelocator\ConfigProvider;

use FiloBlu\Storelocator\Helper\Data;
use FiloBlu\Storelocator\Model\StoresFactory;
use FiloBlu\Storelocator\Model\TagsFactory;
use Magento\Checkout\Model\ConfigProviderInterface;
use Magento\Checkout\Model\Session;
use Magento\Directory\Model\AllowedCountries;
use Magento\Framework\Locale\Resolver;
use Magento\Framework\Webapi\Rest\Request\Deserializer\Json;

/**
 *
 */
class CheckoutConfigProvider implements ConfigProviderInterface
{
    /**
     * @var \FiloBlu\Storelocator\Helper\Data
     */
    protected $helper;
    /**
     * @var \Magento\Framework\Webapi\Rest\Request\Deserializer\Json
     */
    protected $jsonHelper;
    /**
     * @var \FiloBlu\Storelocator\Model\TagsFactory
     */
    protected $tagsFactory;
    /**
     * @var \Magento\Directory\Model\AllowedCountries
     */
    protected $allowedCountryModel;
    /**
     * @var \Magento\Checkout\Model\Session
     */
    protected $checkoutSession;
    /**
     * @var \FiloBlu\Storelocator\Model\StoresFactory
     */
    protected $storeFactory;
    /**
     * @var \Magento\Framework\Locale\Resolver
     */
    private $localeResolver;

    /**
     * @param \FiloBlu\Storelocator\Helper\Data $helper
     * @param \Magento\Framework\Webapi\Rest\Request\Deserializer\Json $jsonHelper
     * @param \FiloBlu\Storelocator\Model\TagsFactory $tagsFactory
     * @param \Magento\Directory\Model\AllowedCountries $allowedCountryModel
     * @param \Magento\Checkout\Model\Session $checkoutSession
     * @param \FiloBlu\Storelocator\Model\StoresFactory $storeFactory
     * @param \Magento\Framework\Locale\Resolver $localeResolver
     */
    public function __construct(
        Data $helper,
        Json $jsonHelper,
        TagsFactory $tagsFactory,
        AllowedCountries $allowedCountryModel,
        Session $checkoutSession,
        StoresFactory $storeFactory,
        Resolver $localeResolver
    ) {
        $this->helper = $helper;
        $this->jsonHelper = $jsonHelper;
        $this->tagsFactory = $tagsFactory;
        $this->allowedCountryModel = $allowedCountryModel;
        $this->checkoutSession = $checkoutSession;
        $this->storeFactory = $storeFactory;
        $this->localeResolver = $localeResolver;
    }

    /**
     * @return array[]|\false[][]
     * @throws \Magento\Framework\Exception\LocalizedException
     * @throws \Magento\Framework\Exception\NoSuchEntityException
     * @throws \Magento\Framework\Webapi\Exception
     */
    public function getConfig()
    {
        if (!$this->helper->getConfig('carriers/pickupinstore/active')) {
            return [
                'pickup_in_store' => [
                    'enabled' => false
                ]
            ];
        }

        $googleIncludePlaces = $this->helper->getConfig(
            'filoblu_storelocator_section/search/gmaps_search_autocomplete_enabled'
        ) ? '&libraries=places' : '';
        $googleMapConfig = [
            'center'                                     => [
                'lat' => (float)explode(
                    ';',
                    $this->helper->getConfig('filoblu_storelocator_section/map_options/gmaps_default_center')
                )[0],
                'lng' => (float)explode(
                    ';',
                    $this->helper->getConfig('filoblu_storelocator_section/map_options/gmaps_default_center')
                )[1]
            ],
            'zoom'                                       => (int)$this->helper->getConfig(
                'filoblu_storelocator_section/map_options/gmaps_default_zoom'
            ),
            'minZoom'                                    => (int)$this->helper->getConfig(
                'filoblu_storelocator_section/map_options/gmaps_min_zoom'
            ),
            'maxZoom'                                    => (int)$this->helper->getConfig(
                'filoblu_storelocator_section/map_options/gmaps_max_zoom'
            ),
            'mapContainerId'                             => 'map',
            'mapTypeId'                                  => $this->helper->getConfig(
                'filoblu_storelocator_section/map_options/gmaps_type'
            ),
            'zoomControl'                                => (bool)$this->helper->getConfig(
                'filoblu_storelocator_section/map_options/gmaps_ui_zoomControl_enabled'
            ),
            'mapTypeControl'                             => (bool)$this->helper->getConfig(
                'filoblu_storelocator_section/map_options/gmaps_ui_mapTypeControl_enabled'
            ),
            'streetViewControl'                          => (bool)$this->helper->getConfig(
                'filoblu_storelocator_section/map_options/gmaps_ui_streetViewControl_enabled'
            ),
            'rotateControl'                              => (bool)$this->helper->getConfig(
                'filoblu_storelocator_section/map_options/gmaps_ui_rotateControl_enabled'
            ),
            'scaleControl'                               => (bool)$this->helper->getConfig(
                'filoblu_storelocator_section/map_options/gmaps_ui_scaleControl_enabled'
            ),
            'fullscreenControl'                          => (bool)$this->helper->getConfig(
                'filoblu_storelocator_section/map_options/gmaps_ui_fullscreenControl_enabled'
            ),
            'gmapApiUrl'                                 => $this->helper->getConfig(
                'filoblu_storelocator_section/general/gmaps_api_url'
            ),
            'gmapGeolocationApiUrl'                      => $this->helper->getConfig(
                'filoblu_storelocator_section/geolocation/gmaps_geolocation_api_url'
            ),
            'gmapApiKey'                                 => $this->helper->getConfig(
                'filoblu_storelocator_section/general/gmaps_api_key'
            ),
            'gmapLanguage'                               => explode('_', $this->localeResolver->getLocale())[0],
            'gmapGeoLocation'                            => (bool)$this->helper->getConfig(
                'filoblu_storelocator_section/geolocation/gmaps_geolocation_enabled'
            ),
            'gmapGeoLocationZoom'                        => (int)$this->helper->getConfig(
                'filoblu_storelocator_section/geolocation/gmaps_geolocation_zoom'
            ),
            'gmapGeoLocationMarker'                      => (bool)$this->helper->getConfig(
                'filoblu_storelocator_section/geolocation/gmaps_geolocation_marker_enabled'
            ),
            'gmapGeoLocationMarkerAnimation'             => (bool)$this->helper->getConfig(
                'filoblu_storelocator_section/geolocation/gmaps_geolocation_marker_animation_enabled'
            ),
            'gmapGeoLocationMarkerImage'                 => $this->helper->getConfig(
                'filoblu_storelocator_section/geolocation/gmaps_geolocation_marker_image'
            ) ? $this->helper->getBaseUrlConfigImage() . $this->helper->getConfig(
                    'filoblu_storelocator_section/geolocation/gmaps_geolocation_marker_image'
                ) : '',
            'gmapGeoLocationDistance'                    => (bool)$this->helper->getConfig(
                'filoblu_storelocator_section/geolocation/gmaps_geolocation_distance_enabled'
            ),
            'gmapGeoLocationDuration'                    => (bool)$this->helper->getConfig(
                'filoblu_storelocator_section/geolocation/gmaps_geolocation_duration_enabled'
            ),
            'gmapGeoLocationTravelMode'                  => $this->helper->getConfig(
                'filoblu_storelocator_section/geolocation/gmaps_geolocation_travelmode'
            ),
            'gmapGeoLocationUnitSystem'                  => (int)$this->helper->getConfig(
                'filoblu_storelocator_section/geolocation/gmaps_geolocation_unitsystem'
            ),
            'gmapGeoLocationGetDirections'               => (bool)$this->helper->getConfig(
                'filoblu_storelocator_section/geolocation/gmaps_geolocation_getdirections_enabled'
            ),
            'gmapGeoLocationGetDirectionsPanelId'        => 'gmapGetDirectionsPanel',
            'gmapMarkersMarkerImage'                     => $this->helper->getConfig(
                'filoblu_storelocator_section/markers/gmaps_markers_marker_image'
            ) ? $this->helper->getBaseUrlConfigImage() . $this->helper->getConfig(
                    'filoblu_storelocator_section/markers/gmaps_markers_marker_image'
                ) : '',
            'gmapStoresImageDir'                         => $this->helper->getBaseUrlStoresImage(),
            'gmapMarkersClusterMarker'                   => (bool)$this->helper->getConfig(
                'filoblu_storelocator_section/markers/gmaps_markers_cluster_marker_enabled'
            ),
            'gmapMarkersClusterMarkerGridSize'           => (int)$this->helper->getConfig(
                'filoblu_storelocator_section/markers/gmaps_markers_cluster_marker_gridSize'
            ),
            'gmapMarkersClusterMarkerMaxZoom'            => $this->helper->getConfig(
                'filoblu_storelocator_section/markers/gmaps_markers_cluster_marker_maxZoom'
            ) ? $this->helper->getConfig(
                'filoblu_storelocator_section/markers/gmaps_markers_cluster_marker_maxZoom'
            ) : null,
            'gmapMarkersClusterMarkerZoomOnClick'        => (bool)$this->helper->getConfig(
                'filoblu_storelocator_section/markers/gmaps_markers_cluster_marker_zoomOnClick'
            ),
            'gmapMarkersClusterMarkerAverageCenter'      => (bool)$this->helper->getConfig(
                'filoblu_storelocator_section/markers/gmaps_markers_cluster_marker_averageCenter'
            ),
            'gmapMarkersClusterMarkerMinimumClusterSize' => (int)$this->helper->getConfig(
                'filoblu_storelocator_section/markers/gmaps_markers_cluster_minimumClusterSize'
            ),
            'gmapMarkersClusterMarkerImage'              => $this->helper->getConfig(
                'filoblu_storelocator_section/markers/gmaps_markers_cluster_image'
            ) ? $this->helper->getBaseUrlConfigImage() . $this->helper->getConfig(
                    'filoblu_storelocator_section/markers/gmaps_markers_cluster_image'
                ) : $this->helper->getViewFileUrl('FiloBlu_Storelocator::images/cluster_marker.png'),
            'gmapMarkersClusterMarkerImageWidth'         => (int)$this->helper->getConfig(
                'filoblu_storelocator_section/markers/gmaps_markers_cluster_image_width'
            ),
            'gmapMarkersClusterMarkerImageHeight'        => (int)$this->helper->getConfig(
                'filoblu_storelocator_section/markers/gmaps_markers_cluster_image_height'
            ),
            'gmapMarkersClusterMarkerTextColor'          => $this->helper->getConfig(
                'filoblu_storelocator_section/markers/gmaps_markers_cluster_textColor'
            ),
            'gmapMarkersClusterMarkerTextSize'           => (int)$this->helper->getConfig(
                'filoblu_storelocator_section/markers/gmaps_markers_cluster_textSize'
            ),
            'gmapMarkersClusterMarkerTextOffsetWidth'    => (int)$this->helper->getConfig(
                'filoblu_storelocator_section/markers/gmaps_markers_cluster_text_offsetWidth'
            ),
            'gmapMarkersClusterMarkerTextOffsetHeight'   => (int)$this->helper->getConfig(
                'filoblu_storelocator_section/markers/gmaps_markers_cluster_text_offsetHeight'
            ),
            'gmapSearchAutocomplete'                     => (bool)$this->helper->getConfig(
                'filoblu_storelocator_section/search/gmaps_search_autocomplete_enabled'
            ),
            'gmapSearchAutocompleteId'                   => 'gmapSearch',
            'gmapSearchAutocompleteType'                 => $this->helper->getConfig(
                'filoblu_storelocator_section/search/gmaps_search_autocomplete_type'
            ) ? $this->helper->getConfig('filoblu_storelocator_section/search/gmaps_search_autocomplete_type') : '',
            'gmapSearchAutocompleteZoom'                 => (int)$this->helper->getConfig(
                'filoblu_storelocator_section/search/gmaps_search_autocomplete_zoom'
            ),
            'gmapSearchCountryId'                        => 'gmapCountry',
            'gmapSearchRegionId'                         => 'gmapRegion',
            'gmapSearchCityId'                           => 'gmapCity',
            'gmapSearchCountry'                          => (bool)$this->helper->getConfig(
                'filoblu_storelocator_section/search/gmaps_search_country_enabled'
            ),
            'gmapSearchCity'                             => (bool)$this->helper->getConfig(
                'filoblu_storelocator_section/search/gmaps_search_city_enabled'
            ),
            'gmapSearchTags'                             => (bool)$this->helper->getConfig(
                'filoblu_storelocator_section/search/gmaps_search_tag_enabled'
            ),
            'gmapSearchTagsContainerClass'               => 'tag-info',
            'gmapStoresListId'                           => 'gmapStoresList',
            'gmapWorkingTimes'                           => (bool)$this->helper->getConfig(
                'filoblu_storelocator_section/workingtimes/gmaps_working_times_enabled'
            ),
            'baseUrl'                                    => $this->helper->getBaseUrl(),
            'pickup_in_store'                            => 1,
            'allowedCountries'                           => $this->allowedCountryModel->getAllowedCountries()
        ];

        if ($this->helper->getConfig('filoblu_storelocator_section/map_options/gmaps_style')) {
            $styleMapConfig = str_replace(
                "'",
                '"',
                $this->helper->getConfig('filoblu_storelocator_section/map_options/gmaps_style')
            );
            $googleMapConfig['styles'] = $this->jsonHelper->deserialize(str_replace('styles:', '', $styleMapConfig));
        }

        $allAvailableTagHtml = '';

        foreach ($this->tagsFactory->create()->getAllAvailableTags() as $tag) {
            $allAvailableTagHtml .= '<div class="tag-info" data-tag-id="' . $tag->getTagId() . '">';

            if ($tag->getImageUrl()) {
                $allAvailableTagHtml .= '<div class="tag-image"><img src="' . $tag->getImageUrl(
                    ) . '" title="' . strip_tags($tag->getDescription()) . '" alt="' . $tag->getName() . '" /></div>';
            }

            $allAvailableTagHtml .= '<div class="tag-name">' . $tag->getName() . '</div></div>';
        }

        // Current Customer Store Data
        $quote = $this->checkoutSession->getQuote();

        $currentSelectedStoreData = [];

        if ($quote) {
            $currentSelectedStoreId = ($quote->getPickupInStoreId() ?: 0);
            $model = $this->storeFactory->create()->load($currentSelectedStoreId);
            if ($model->getId()) {
                $currentSelectedStoreData = $model->getData();
                $region = '';
                if ($currentSelectedStoreData['region']) {
                    $region = ', ' . $currentSelectedStoreData['region'];
                }
                $currentSelectedStoreData['address'] = '</br>' . $currentSelectedStoreData['street'] . '</br>' . $currentSelectedStoreData['postcode'] . ' ' . $currentSelectedStoreData['city'] . $region . ' (' . $currentSelectedStoreData['country'] . ')';
            }
        }

        return [
            'pickup_in_store' => [
                'enabled'                                 => true,
                'current_selected_store_data'             => $currentSelectedStoreData,
                'google_map_script_src'                   => $this->helper->getConfig(
                        'filoblu_storelocator_section/general/gmaps_api_url'
                    ) . '?language=' . explode(
                        '_',
                        $this->localeResolver->getLocale()
                    )[0] . '&key=' . $this->helper->getConfig(
                        'filoblu_storelocator_section/general/gmaps_api_key'
                    ) . $googleIncludePlaces,
                'google_map_config'                       => $googleMapConfig,
                'gmaps_search_country_enabled'            => (bool)$this->helper->getConfig(
                    'filoblu_storelocator_section/search/gmaps_search_country_enabled'
                ),
                'gmaps_search_city_enabled'               => (bool)$this->helper->getConfig(
                    'filoblu_storelocator_section/search/gmaps_search_city_enabled'
                ),
                'gmaps_search_autocomplete_enabled'       => (bool)$this->helper->getConfig(
                    'filoblu_storelocator_section/search/gmaps_search_autocomplete_enabled'
                ),
                'gmaps_search_tag_enabled'                => (bool)$this->helper->getConfig(
                    'filoblu_storelocator_section/search/gmaps_search_tag_enabled'
                ),
                'gmaps_geolocation_enabled'               => (bool)$this->helper->getConfig(
                    'filoblu_storelocator_section/search/gmaps_geolocation_enabled'
                ),
                'gmaps_geolocation_getdirections_enabled' => (bool)$this->helper->getConfig(
                    'filoblu_storelocator_section/search/gmaps_geolocation_getdirections_enabled'
                ),
                'gmaps_all_available_tags'                => $allAvailableTagHtml
            ]
        ];
    }

}
