<?php
/**
 * Hyvä Themes - https://hyva.io
 * Copyright © Hyvä Themes 2020-present. All rights reserved.
 * This product is licensed per Magento install
 * See https://hyva.io/license
 */

declare(strict_types=1);

use Hyva\Theme\Model\ViewModelRegistry;
use Hyva\Theme\ViewModel\BlockCache;
use Hyva\Theme\ViewModel\HeroiconsOutline;
use Hyva\Theme\ViewModel\ProductPage;
use Hyva\Theme\ViewModel\Store;
use Magento\Catalog\Block\Product\ReviewRendererInterface as ProductReviewRenderer;
use Magento\Framework\Escaper;
use Magento\Framework\View\Element\Template;

// phpcs:disable Generic.Files.LineLength.TooLong

/** @var Template $block */
/** @var Escaper $escaper */
/** @var ViewModelRegistry $viewModels */

/** @var Store $viewModelStore */
$viewModelStore = $viewModels->require(Store::class);

/** @var ProductPage $productViewModel */
$productViewModel = $viewModels->require(ProductPage::class);

/** @var HeroiconsOutline $heroicons */
$heroicons = $viewModels->require(HeroiconsOutline::class);

/** @var BlockCache $blockCacheViewModel */
$blockCacheViewModel = $viewModels->require(BlockCache::class);

$viewMode = 'grid';
$imageDisplayArea = 'category_page_grid';
$showDescription = false;

$title = (string) $block->getTitle();
$items = $block->getItems() ?? [];
if (is_object($items) && $items instanceof Iterator) {
    $items = iterator_to_array($items);
}
if (!$itemCount = count($items)) {
    return '';
}

$sliderItemRenderer = $block->getLayout()->getBlock('product_list_item')
    ?: $block->getChildBlock('slider.item.template')
        ?: $block->getLayout()->createBlock(Template::class);

$hideRatingSummary = (bool) $block->getData('hide_rating_summary');
$hideDetails       = (bool) $block->getData('hide_details');

$sliderItemRenderer->setData('hide_details', $hideDetails);
$sliderItemRenderer->setData('hide_rating_summary', $hideRatingSummary);

// The slider item renderer block is often a shared instance.
// If a specific item template is set for this slider, the previously set template must be reset later
// so the item template is only replaced for the one slider it is specified on.
$sharedItemRendererTemplate = null;
$isSharedItemRenderer       = $sliderItemRenderer !== $block->getChildBlock('slider.item.template');
if ($isSharedItemRenderer && $block->getChildBlock('slider.item.template')) {
    $sharedItemRendererTemplate = $sliderItemRenderer->getTemplate();
    $sliderSpecificItemTemplate = $block->getChildBlock('slider.item.template')->getTemplate();
    $sliderItemRenderer->setTemplate($sliderSpecificItemTemplate);
}

?>
<script>
    'use strict';

    function initSliderComponent() {
        return {
            active: 0,
            itemCount: 0,
            getSlider() {
                return this.$el.querySelector('.js_slides');
            },
            pageSize: 4,
            pageFillers: 0,
            calcPageSize() {
                const slider = this.getSlider();
                if (slider) {
                    this.itemCount = slider.querySelectorAll('.js_slide').length;
                    this.pageSize = Math.round(slider.clientWidth / slider.querySelector('.js_slide').clientWidth);
                    this.pageFillers = (
                        this.pageSize * Math.ceil(this.itemCount / this.pageSize)
                    ) - this.itemCount;
                }
            },
            calcActive() {
                const slider = this.getSlider();
                if (slider) {
                    const sliderItems = this.itemCount + this.pageFillers;
                    const calculatedActiveSlide = slider.scrollLeft / (slider.scrollWidth / sliderItems);
                    this.active = Math.round(calculatedActiveSlide / this.pageSize) * this.pageSize;
                }
            },
            scrollPrevious() {
                this.scrollTo(this.active - this.pageSize);
            },
            scrollNext() {
                this.scrollTo(this.active + this.pageSize);
            },
            scrollTo(idx) {
                const slider = this.getSlider();
                if (slider) {
                    const slideWidth = slider.scrollWidth / (this.itemCount + this.pageFillers);
                    slider.scrollLeft = Math.floor(slideWidth) * idx;
                    this.active = idx;
                }
            }
        }
    }
</script>
<section class="<?=
$escaper->escapeHtmlAttr($block->getData('maybe_purged_tailwind_section_classes'))
    ?: 'mt-8 text-gray-700 body-font';
?>"
         x-data="initSliderComponent()"
         x-init="calcPageSize();"
         @resize.window.debounce="calcPageSize(); $nextTick( function() { calcActive() })"
>
    <?php if ($items): ?>
        <div class="relative">
            <?php if ($title): ?>
                <div class="flex flex-col items-center md:flex-row">
                    <h3 class="text-xl title-font font-bold mb-4 uppercase w-full text-center bg-secondary-lighter p-2 shadow-md">
                        <?= $escaper->escapeHtml($title); ?>
                    </h3>
                </div>
            <?php endif; ?>
            <div class="flex-none relative w-full overflow-x-hidden">
                <div class="relative flex flex-nowrap w-full overflow-auto transition-all js_slides snap md:px-1 xl:px-2"
                     @scroll.debounce="calcActive"
                >
                    <?php foreach ($items as $product): ?>
                        <div class="relative flex flex-shrink-0 w-full mr-1 p-1 js_slide md:w-1/2 lg:w-1/3 xl:w-1/4">
                            <?php
                            $itemCacheKeyInfo = [
                                $product->getId(),
                                $viewMode,
                                ProductReviewRenderer::SHORT_VIEW,
                                $block->getTemplate(),
                                $product->getStoreId(),
                                $productViewModel->getCurrencyData()['code'],
                                (int) $hideDetails,
                                (int) $hideRatingSummary,
                                /* category id */ '0'
                            ];
                            echo $sliderItemRenderer
                                ->setData('product', $product)
                                ->setData('view_mode', $viewMode)
                                ->setData('image_display_area', $imageDisplayArea)
                                ->setData('show_description', $showDescription)
                                ->setData('template_type', ProductReviewRenderer::SHORT_VIEW)
                                ->setData('cache_lifetime', 3600)
                                ->setData('cache_tags', $product->getIdentities())
                                ->setData('cache_key', $blockCacheViewModel->hashCacheKeyInfo($itemCacheKeyInfo))
                                ->toHtml();
                            ?>
                        </div>
                    <?php endforeach; ?>
                    <div :class="{
                        'js_dummy_slide w-full md:w-1/2 lg:w-1/3 xl:w-1/4 flex flex-shrink-0 py-1' : pageFillers > 0
                        }"></div>
                    <div :class="{
                        'js_dummy_slide w-full md:w-1/2 lg:w-1/3 xl:w-1/4 flex flex-shrink-0 py-1' : pageFillers > 1
                        }"></div>
                    <div :class="{
                        'js_dummy_slide w-full md:w-1/2 lg:w-1/3 xl:w-1/4 flex flex-shrink-0 py-1' : pageFillers > 2
                        }"></div>
                </div>
            </div>
            <div>
                <template x-if="itemCount > pageSize">
                    <div class="flex items-center justify-center py-4">
                        <button
                            aria-label="<?= $escaper->escapeHtml(__('Previous')) ?>"
                            tabindex="-1"
                            class="hidden mr-4 text-black rounded-full outline-none focus:outline-none flex-none"
                            :class="{ 'opacity-25 pointer-events-none' : active === 0 }"
                            @click="scrollPrevious">
                            <?= $heroicons->chevronLeftHtml("w-5 h-5", 25, 25) ?>
                        </button>
                        <div class="flex flex-wrap w-full md:w-auto justify-center">
                            <?php for ($i=0; $i < $itemCount; $i++): ?>
                                <span class="flex-shrink-0 block w-3 h-3 m-1 bg-black bg-opacity-25 rounded-full shadow cursor-pointer"
                                      :class="{
                                    'bg-opacity-100': active === <?= (int) $i ?>,
                                    'hidden': (pageSize !== 1 && !!(<?= (int) $i ?> % pageSize))
                                    }"
                                      @click="scrollTo(<?= (int) $i ?>)">
                        </span>
                            <?php endfor; ?>
                        </div>
                        <button
                            aria-label="<?= $escaper->escapeHtml(__('Next')) ?>"
                            tabindex="-1"
                            class="hidden ml-4 text-black rounded-full outline-none focus:outline-none flex-none"
                            :class="{ 'opacity-25 pointer-events-none' : active >= itemCount-pageSize }"
                            @click="scrollNext">
                            <?= $heroicons->chevronRightHtml("w-5 h-5", 25, 25) ?>
                        </button>
                    </div>
                </template>
            </div>
        </div>
    <?php endif; ?>
</section>
<?php
if ($sharedItemRendererTemplate) {
    $sliderItemRenderer->setTemplate($sharedItemRendererTemplate);
}
?>
