<?php

namespace FiloBlu\Storelocator\Block;

use FiloBlu\Storelocator\Model\ResourceModel\Stores\CollectionFactory;
use FiloBlu\Storelocator\Model\StoresFactory;
use FiloBlu\Storelocator\Model\WorkingTimes;
use Magento\Catalog\Api\ProductRepositoryInterface;
use Magento\Catalog\Helper\ImageFactory;
use Magento\Framework\Pricing\Helper\Data;
use Magento\Framework\View\Element\Template;
use Magento\Framework\View\Element\Template\Context;
use Magento\Wishlist\Controller\WishlistProviderInterface;

class Shop extends Template
{

    protected $storesFactory;
    protected $workingTimes;
    protected $productRepository;
    protected $_imageHelperFactory;
    protected $_pricingHelper;
    protected $wishlistProvider;
    protected $_helper;
    /**
     * @var CollectionFactory
     */
    private $storesCollectionFactory;

    public function __construct(
        CollectionFactory $storesCollectionFactory,
        StoresFactory $storesFactory,
        WorkingTimes $workingTimes,
        \FiloBlu\Storelocator\Helper\Data $helper,
        ProductRepositoryInterface $productRepository,
        ImageFactory $imageHelperFactory,
        Data $pricingHelper,
        WishlistProviderInterface $wishlistProvider,
        Context $context
    ) {
        parent::__construct($context);

        $this->storesCollectionFactory = $storesCollectionFactory;
        $this->storesFactory = $storesFactory;
        $this->workingTimes = $workingTimes;
        $this->_helper = $helper;
        $this->productRepository = $productRepository;
        $this->_imageHelperFactory = $imageHelperFactory;
        $this->_pricingHelper = $pricingHelper;
        $this->wishlistProvider = $wishlistProvider;
    }

    public function getProduct()
    {
        $productId = $this->getRequest()->getParam('product');
        if ($productId) {
            return $this->productRepository->getById($productId);
        }

        return false;
    }

    public function getProductImg($product)
    {
        if ($product) {
            return $this->_imageHelperFactory->create()->init($product, 'cart_page_product_thumbnail')->getUrl();
        }
        return false;
    }

    public function getProductPrice($product)
    {
        if ($product) {
            $productPrice = $product->getFinalPrice();
            return $this->_pricingHelper->currency($productPrice, true, false);
        }

        return false;
    }

    public function getShopWorkingTimeArray()
    {
        $hoursArray = $this->getShopWorkingTimes();
        $workingDays = [];
        foreach ($hoursArray as $day) {
            if ($day['continued']) {
                if ($day['closed']) {
                    $workingDays[$day['dayStr']] = __('Closed');
                } else {
                    $workingDays[$day['dayStr']] = $day['openTime'] . ' - ' . $day['closeTime'];
                }
            } elseif (!$day['continued']) {
                if ($day['period'] == 1) {
                    if ($day['closed']) {
                        $workingDays[$day['dayStr']] = __('Closed');
                    } else {
                        $workingDays[$day['dayStr']] = $day['openTime'] . ' - ' . $day['closeTime'];
                    }
                } elseif ($day['period'] == 2) {
                    if ($day['closed']) {
                        $workingDays[$day['dayStr']] .= ' ' . __('Closed');
                    } else {
                        $workingDays[$day['dayStr']] .= ' ' . $day['openTime'] . ' - ' . $day['closeTime'];
                    }
                }
            }
        }
        return $workingDays;
    }

    public function getShopWorkingTimes()
    {
        $shopId = $this->getRequest()->getParam('id');
        $workingTimes = $this->workingTimes->loadByStoreId($shopId);
        $workingTimesData = $workingTimes->getData();
        $wtIndex = 0;
        $skipNextForContinuedTimetable = false;

        foreach ($workingTimesData as $workingTime) {
            if ($skipNextForContinuedTimetable) {
                $skipNextForContinuedTimetable = false;
                $wtIndex++;
                continue;
            }
//            $isClosed = $workingTime["closed"];

//            if ($isClosed || (!$workingTime["from"] && !$workingTime["to"])) {
//                $wtIndex++;
//                continue;
//            }

            $continuedTime = false;

            $fromHH = '00';
            $fromMM = '00';
            $fromSS = '00';

            if ($workingTime['from']) {
                $timeFrom = explode(':', explode(' ', $workingTime['from'])[1]);
                $fromHH = $timeFrom[0];
                $fromMM = $timeFrom[1];
                $fromSS = $timeFrom[2];

                // Closed day
                if ($fromHH == '00' && $fromMM == '00' && isset($workingTimesData[$wtIndex + 1])) {
                    $wtNext = $workingTimesData[$wtIndex + 1];
                    if ($wtNext['day'] == $workingTime['day']) {
                        if ($wtNext['to']) {
                            $timeToNext = explode(':', explode(' ', $wtNext['to'])[1]);
                            $toHHNext = $timeToNext[0];
                            $toMMNext = $timeToNext[1];
                            $toSSNext = $timeToNext[2];
                            if ($toHHNext == '00' && $toMMNext == '00') {
                                $workingTime['closed'] = 1;
                            }
                        }
                    }
                }
            }

            $toHH = '00';
            $toMM = '00';
            $toSS = '00';

            if ($workingTime['to']) {
                $timeTo = explode(':', explode(' ', $workingTime['to'])[1]);
                $toHH = $timeTo[0];
                $toMM = $timeTo[1];
                $toSS = $timeTo[2];

                // Closed day
                if ($toHH == '00' && $toMM == '00' && isset($workingTimesData[$wtIndex - 1])) {
                    $wtPrev = $workingTimesData[$wtIndex - 1];
                    if ($wtPrev['day'] == $workingTime['day']) {
                        if ($wtPrev['from']) {
                            $timeFromPrev = explode(':', explode(' ', $wtPrev['from'])[1]);
                            $fromHHPrev = $timeFromPrev[0];
                            $fromMMPrev = $timeFromPrev[1];
                            $fromSSPrev = $timeFromPrev[2];
                            if ($fromHHPrev == '00' && $fromMMPrev == '00') {
                                $workingTime['closed'] = 1;
                            }
                        }
                    }
                }

                // Continued timetable
                if ($toHH == '00' && $toMM == '00' && isset($workingTimesData[$wtIndex + 1])) {
                    $continuedTime = true;
                    $wtNext = $workingTimesData[$wtIndex + 1];
                    if ($wtNext['day'] == $workingTime['day']) {
                        if ($wtNext['to']) {
                            $timeToNext = explode(':', explode(' ', $wtNext['to'])[1]);
                            $toHHNext = $timeToNext[0];
                            $toMMNext = $timeToNext[1];
                            $toSSNext = $timeToNext[2];
                        } else {
                            $toHHNext = '00';
                            $toMMNext = '00';
                            $toSSNext = '00';
                        }

                        if (!$wtNext['from']) {
                            $toHH = $toHHNext;
                            $toMM = $toMMNext;
                            $toSS = $toSSNext;

                            $skipNextForContinuedTimetable = true;
                        }

                        if ($wtNext['from']) {
                            $timeFromNext = explode(':', explode(' ', $wtNext['from'])[1]);
                            $fromHHNext = $timeFromNext[0];
                            $fromMMNext = $timeFromNext[1];
                            $fromSSNext = $timeFromNext[2];
                            if ($fromHHNext == '00' && $fromMMNext == '00') {
                                $skipNextForContinuedTimetable = true;
                                $toHH = $toHHNext;
                                $toMM = $toMMNext;
                                $toSS = $toSSNext;
                            }
                        }
                    }
                }
            }

            $dayStr = '';

            switch ($workingTime['day']) {
                case 1:
                    $dayStr = 'Mon';
                    break;
                case 2:
                    $dayStr = 'Tue';
                    break;
                case 3:
                    $dayStr = 'Wed';
                    break;
                case 4:
                    $dayStr = 'Thu';
                    break;
                case 5:
                    $dayStr = 'Fri';
                    break;
                case 6:
                    $dayStr = 'Sat';
                    break;
                case 7:
                    $dayStr = 'Sun';
                    break;

                default:
                    $dayStr = 'DAY_OF_WEEK_UNSPECIFIED';
                    break;
            }

            $hoursArray[] = [
                'day'       => $workingTime['day'],
                'period'    => $workingTime['period'],
                'continued' => $continuedTime,
                'closed'    => $workingTime['closed'],
                'dayStr'    => $dayStr,
                'openTime'  => $fromHH . ':' . $fromMM,
                'closeTime' => $toHH . ':' . $toMM
            ];

            $wtIndex++;
        }

        return $hoursArray ? $hoursArray : false;
    }

    public function getFormAction()
    {
        $shopId = $this->getRequest()->getParam('id');
        return $this->_storeManager->getStore()->getBaseUrl() . 'storelocator/index/appointment/id/' . $shopId;
    }

    public function getTimeSlots()
    {
//        $timeSlots = [
//            '09:00 - 09:30',
//            '09:30 - 10:00',
//            '10:00 - 10:30',
//            '10:30 - 11:00',
//            '11:00 - 11:30',
//            '11:30 - 12:00',
//            '12:00 - 12:30',
//            '12:30 - 13:00',
//            '13:00 - 13:30',
//            '13:30 - 14:00',
//            '14:00 - 14:30',
//            '14:30 - 15:00',
//            '15:00 - 15:30',
//            '15:30 - 16:00',
//            '16:00 - 16:30',
//            '16:30 - 17:00',
//            '17:00 - 17:30',
//            '17:30 - 18:00',
//        ];

        $hoursArray = $this->getShopWorkingTimes();

        $timeSlostsArray = array();

        foreach ($hoursArray as $day) {
            if ($day['continued']) {
                if ($day['closed']) {
                    $timeSlostsArray[$day['dayStr']] = __('Closing day');
                } else {
                    $dayTimeSlots = [];
                    date_default_timezone_set('Europe/London');
                    $range = range(strtotime($day['openTime']), strtotime($day['closeTime']), 30 * 60);
                    foreach ($range as $time) {
                        $dayTimeSlots[] = date('H:i', $time);
                    }
                    $preformattedArray = $dayTimeSlots;
                    $formattedArray = [];
                    foreach ($preformattedArray as $k => $value) {
                        if ($value != end($preformattedArray)) {
                            $toPush = $value . ' - ' . $preformattedArray[$k + 1];
                            $formattedArray[] = $toPush;
                        }
                    }
                    $timeSlostsArray[$day['dayStr']] = $formattedArray;
                }
            } elseif (!$day['continued']) {
                if ($day['period'] == 1) {
                    if ($day['closed']) {
                        continue;
                    } else {
                        $dayTimeSlots = [];
                        date_default_timezone_set('Europe/London');
                        $range = range(strtotime($day['openTime']), strtotime($day['closeTime']), 30 * 60);
                        foreach ($range as $time) {
                            $dayTimeSlots[] = date('H:i', $time);
                        }

                        $preformattedArray = $dayTimeSlots;
                        $formattedArray = [];
                        foreach ($preformattedArray as $k => $value) {
                            if ($value != end($preformattedArray)) {
                                $toPush = $value . ' - ' . $preformattedArray[$k + 1];
                                $formattedArray[] = $toPush;
                            } else {
                                continue;
                            }
                        }
                        $timeSlostsArray[$day['dayStr']] = $formattedArray;
                    }
                } elseif ($day['period'] == 2) {
                    if ($day['closed']) {
                        continue;
                    } else {
                        $dayTimeSlots = [];
                        date_default_timezone_set('Europe/London');
                        $range = range(strtotime($day['openTime']), strtotime($day['closeTime']), 30 * 60);
                        foreach ($range as $time) {
                            $dayTimeSlots[] = date('H:i', $time);
                        }

                        $previousTime = [];
                        foreach ($timeSlostsArray[$day['dayStr']] as $time) {
                            $previousTime[] = $time;
                        }
                        $preformattedArray = $dayTimeSlots;
                        $formattedArray = [];
                        foreach ($preformattedArray as $k => $value) {
                            if ($value != end($preformattedArray)) {
                                $toPush = $value . ' - ' . $preformattedArray[$k + 1];
                                $formattedArray[] = $toPush;
                            } else {
                                continue;
                            }
                        }
                        $timeSlostsArray[$day['dayStr']] = array_merge($previousTime, $formattedArray);
                    }
                }
            }
        }


        return json_encode($timeSlostsArray);
    }

    public function isAppointmentEnabled()
    {
        return $this->_helper->getConfig('filoblu_storelocator_section/general/appointment_enabled');
    }

    public function getStoreIframeExternalAppointment()
    {
        $shop = $this->getShop();
        if ($this->isEnabledExternalAppointment() && $shop['store_external_iframe_appointment']) {
            return $shop['store_external_iframe_appointment'];
        }
    }

    public function getShop()
    {
        $shopId = $this->getRequest()->getParam('id');
        $shop = $this->storesFactory->create()->load($shopId);
        $shopData = $shop->getdata();
        return $shopData;
    }

    public function isEnabledExternalAppointment()
    {
        return $this->_helper->getConfig('filoblu_storelocator_section/general/enabled_external_appointment');
    }

    public function getCustomerWhislist()
    {
        $currentUserWishlist = $this->wishlistProvider->getWishlist();
        $wishlistItems = $currentUserWishlist->getItemCollection();
        if (count($wishlistItems)) {
            return $wishlistItems;
        }
        return false;
    }
}