<?php
/**
 * Hyvä Themes - https://hyva.io
 * Copyright © Hyvä Themes. All rights reserved.
 * See COPYING.txt for license details.
 */

/**
 * @deprecated
 * @see hyva-themes/magento2-default-theme/Hyva_Theme/templates/elements/slider.phtml
 *
 * GraphQL product sliders are deprecated in favor of server side rendered ones.
 * This file will remain for backward compatibility, but no new features will be added.
 */

declare(strict_types=1);

use Hyva\GraphqlViewModel\ViewModel\GraphqlViewModel;
use Hyva\Theme\Model\ViewModelRegistry;
use Hyva\Theme\ViewModel\Cart\Items;
use Hyva\Theme\ViewModel\Currency;
use Hyva\Theme\ViewModel\HeroiconsOutline;
use Hyva\Theme\ViewModel\ProductCompare;
use Hyva\Theme\ViewModel\Store;
use Hyva\Theme\ViewModel\Wishlist;
use Magento\Framework\Escaper;
use Magento\Framework\View\Element\Template;

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

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

/** @var Wishlist $wishlistViewModel */
$wishlistViewModel = $viewModels->require(Wishlist::class);

/** @var ProductCompare $compareViewModel */
$compareViewModel = $viewModels->require(ProductCompare::class);

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

/** @var GraphqlViewModel $gqlViewModel */
$gqlViewModel = $viewModels->require(GraphqlViewModel::class);

/** @var Currency $currencyViewModel */
$currencyViewModel = $viewModels->require(Currency::class);
$currencySymbol = $currencyViewModel->getCurrentCurrencySymbol();

/** @var Escaper $escaper */
/** @var Template $block */
$uniqueId = '_' . uniqid();
$query = $block->getGraphqlQuery();
/**
 * Can be a custom filter, like  "color: { in: [\"yellow\",\"orange\"] },"
 * @var string $productFilters
 */
$productFilters = $block->getProductFilters();
$categoryIds = $block->getCategoryIds();
$priceFrom = $block->getPriceFrom();
$priceTo = $block->getPriceTo();
$pageSize = $block->getPageSize() ?: '8';
$sortAttribute = $block->getSortAttribute() ?: 'position';
$sortDirection = $block->getSortDirection() ?: 'ASC';
$title = $block->getTitle();
$type = $block->getType() ?: "";

$linkedProduct = (in_array($type, ['related', 'crosssell', 'upsell']));

if ($linkedProduct) {
    if ($type === 'crosssell') {
        /** @var Items $cartItemsViewModel */
        $cartItemsViewModel = $viewModels->require(Items::class);
        $productSkus = $cartItemsViewModel->getCartItemsSkus();
    } elseif ($product = $block->getProduct()) {
        $productSkus = $block->getProduct()->getSku();
    } else {
        $productSkus = '';
    }
} else {
    $productSkus = $block->getProductSkus();
}

$productSkuFilter = $productSkus ?
    sprintf("sku: { in: [\"%s\"] },", join("\",\"", explode(',', $productSkus))) :
    "";

$categoryFilter = $categoryIds ?
    sprintf("category_id: { in: [\"%s\"] }", join("\",\"", explode(',', $categoryIds))) :
    "";
$priceFilter = $priceFrom || $priceTo ? "price: { from: \"$priceFrom\", to: \"$priceTo\" }," : "";

$productAttributes = "
      sku
      id
      name
      small_image {
        label
        url
      }
      url_key
      url_suffix
      visibility
      status
      price_range {
        minimum_price {
          regular_price {
            value
            currency
          }
          final_price {
            value
            currency
          }
        }
      }";

$items = $linkedProduct ?
    "{$type}_products {
        $productAttributes
    }" :
    $productAttributes;

$graphqlQuery = $gqlViewModel->query("slider_products_query", $query ?: "
{
  products(
    filter: {
      $productFilters
      $productSkuFilter
      $categoryFilter
      $priceFilter
      }
    pageSize: {$pageSize},
    sort: {{$sortAttribute}: {$sortDirection}}
    ) {
    items {
        $items
    }
  }
}", ['is_linked_product' => $linkedProduct, 'type' => $type]);
?>
<script>
    function initSliderComponent<?= /** @noEscape */ $uniqueId ?>() {
        return {
            active: 0,
            products: [],
            currency: [],
            loading: true,
            minHeight() {
                return 'min-height: ' + ((this.loading && '650px') || 0);
            },
            query: <?= /** @noEscape */ json_encode($graphqlQuery) ?>,
            getProducts($nextTick) {
                fetch('<?= $escaper->escapeUrl($block->getBaseUrl()) ?>graphql?query=' + encodeURIComponent(
                    this.query
                ), {
                    method: 'GET',
                    headers: {
                        'Content-Type': 'application/json',
                        'Store': '<?= /* @noEscape */ $viewModelStore->getStoreCode() ?>'
                    },
                })
                    .then((response) =>  response.json())
                    .then((data) => {
                            this.currency = (data &&
                                data.data &&
                                data.data.currency);
                            <?php if ($linkedProduct): ?>
                            return this.products = (
                                data &&
                                data.data &&
                                data.data.products &&
                                data.data.products.items &&
                                data.data.products.items[0] &&
                                data.data.products.items[0]['<?= $escaper->escapeHtml($type) ?>_products'] &&
                                // only use products with visibility set to `Catalog` or `Catalog, Search` (2 or 4)
                                // with status set to '1' (enabled)
                                data.data.products.items[0]['<?= $escaper->escapeHtml($type) ?>_products']
                                    .filter(product => {
                                        return (
                                            [2,4].includes(product.visibility) &&
                                            product.status.toString() === '1'
                                        )
                                    })
                            ) || [];
                            <?php else: ?>
                            return this.products = (
                                data &&
                                data.data &&
                                data.data.products &&
                                data.data.products.items
                            ) || [];
                            <?php endif; ?>
                        }
                    ).finally(() => {
                    this.loading = false
                    $nextTick(() => this.calcPageSize());
                });
            },
            addToWishlist(productId) {
                const formKey = hyva.getFormKey();
                const postUrl = BASE_URL + 'wishlist/index/add/';

                fetch(postUrl, {
                    "headers": {
                        "content-type": "application/x-www-form-urlencoded; charset=UTF-8",
                    },
                    "body": "form_key=" + formKey + "&product=" + productId + "&uenc=" + hyva.getUenc(),
                    "method": "POST",
                    "mode": "cors",
                    "credentials": "include"
                }).then(function (response) {
                    if (response.redirected) {
                        window.location.href = response.url;
                    } else if (response.ok) {
                        return response.json();
                    } else {
                        typeof window.dispatchMessages !== "undefined" && window.dispatchMessages(
                            [{
                                type: "warning",
                                text: "<?= $escaper->escapeHtml(__('Could not add item to wishlist.')) ?>"
                            }], 5000
                        );
                    }
                }).then(function (response) {
                    if (!response) { return }
                    typeof window.dispatchMessages !== "undefined" && window.dispatchMessages(
                        [{
                            type: (response.success) ? "success" : "error",
                            text: (response.success)
                                ? "<?= $escaper->escapeHtml(
                                    __("%1 has been added to your Wish List.", __("Product"))
                                ) ?>" : response.error_message
                        }], 5000
                    );
                    const reloadCustomerDataEvent = new CustomEvent("reload-customer-section-data");
                    window.dispatchEvent(reloadCustomerDataEvent);
                }).catch(function (error) {
                    typeof window.dispatchMessages !== "undefined" && window.dispatchMessages(
                        [{
                            type: "error",
                            text: error
                        }], 5000
                    );
                });
            },
            addToCompare(productId) {
                const formKey = hyva.getFormKey();
                const postUrl = BASE_URL + 'catalog/product_compare/add/';

                fetch(postUrl, {
                    "headers": {
                        "content-type": "application/x-www-form-urlencoded; charset=UTF-8",
                    },
                    "body": "form_key=" + formKey + "&product=" + productId + "&uenc=" + hyva.getUenc(),
                    "method": "POST",
                    "mode": "cors",
                    "credentials": "include"
                }).then(function (response) {
                    if (response.redirected) {
                        window.location.href = response.url;
                    }
                }).catch(function (error) {
                    typeof window.dispatchMessages !== "undefined" && window.dispatchMessages(
                        [{
                            type: "error",
                            text: error
                        }], 5000
                    );
                });
            },
            getSlider() {
                return this.$root.querySelector('.js_slides');
            },
            pageSize: 4,
            pageFillers: 0,
            calcPageSize() {
                const slider = this.getSlider();
                if (slider) {
                    this.pageSize = Math.round(slider.clientWidth / slider.querySelector('.js_slide').clientWidth);
                    this.pageFillers = (
                        this.pageSize * Math.ceil(this.products.length / this.pageSize)
                    ) - this.products.length;
                }
            },
            calcActive(event) {
                const slider = this.getSlider();
                if (slider) {
                    this.active = Math.ceil(
                        Math.round(
                            slider.scrollLeft / (slider.scrollWidth / this.products.length)
                        ) / this.pageSize
                    ) * this.pageSize;
                }
            }
        }
    }

</script>
<section class="my-12 text-gray-700 body-font"
         x-data="initSliderComponent<?= /** @noEscape */ $uniqueId?>()"
         x-init="getProducts($nextTick);"
         :style="minHeight()"
         @resize.window.debounce="calcPageSize(); $nextTick( function() { calcActive() })"
>
    <template x-if="products && products.length">
        <div class="relative">
            <?php if ($title): ?>
                <div class="container flex flex-col items-center pt-6 pb-3 mx-auto mb-6 border-b-2
                    border-gray-300 md:flex-row">
                    <h3 class="text-2xl font-medium text-gray-900 title-font">
                        <?= $escaper->escapeHtml($title); ?>
                    </h3>
                </div>
            <?php endif; ?>
            <div class="relative w-full overflow-x-hidden focus-within:ring-1 active:ring-0 ring-blue-500/50">
                <div class="relative flex flex-nowrap w-full overflow-auto js_slides snap"
                    <?php if ($title): ?>
                        id="<?= $escaper->escapeHtmlAttr(strtolower(str_replace(' ', '-', trim($title)))) ?>"
                    <?php endif; ?>
                     @scroll.debounce="calcActive"
                >
                    <template x-for="product in products">
                        <div class="flex-none w-full py-1 js_slide md:w-1/2 lg:w-1/3 xl:w-1/4">
                            <div class="mx-1 card card-interactive">
                                <a :href="'<?= $escaper->escapeUrl($block->getBaseUrl()) ?>' +
                                    product.url_key + (product.url_suffix || '')"
                                   class="relative flex items-center bg-white product photo product-item-photo"
                                   style="padding-top:100%"
                                   tabindex="-1">
                                    <span class="absolute top-0 left-0 flex flex-wrap content-center w-full h-full p-2
                                        overflow-hidden align-center hover:shadow-sm">
                                        <img class="self-center w-full h-auto"
                                             :src="product.small_image.url"
                                             :alt="product.small_image.label"
                                             loading="lazy"
                                             width="500"
                                             height="500"
                                        >
                                    </span>
                                </a>

                                <p class="flex items-center justify-center px-1 pt-3">
                                    <a class="truncate product-item-link"
                                       :href="'<?= $escaper->escapeUrl($block->getBaseUrl()) ?>' +
                                            product.url_key + (product.url_suffix || '')"
                                    >
                                        <span x-html="product.name"></span>
                                    </a>
                                </p>
                                <p class="pt-1 text-lg text-center text-gray-900"
                                   x-text="hyva.formatPrice(product.price_range.minimum_price.final_price.value)"></p>
                                <p class="flex flex-wrap gap-2 px-1 pt-3">
                                    <a class="justify-center w-auto mr-auto btn btn-primary"
                                       :href="'<?= $escaper->escapeUrl($block->getBaseUrl()) ?>' +
                                            product.url_key + (product.url_suffix || '')">
                                        <span class="inline"><?= $escaper->escapeHtml(__('View Product')) ?></span>
                                    </a>
                                    <span class="inline-flex gap-2 ml-auto">
                                        <?php if ($compareViewModel->showInProductList()): ?>
                                            <button @click.prevent="addToCompare(product.id)"
                                                    aria-label="<?= $escaper->escapeHtmlAttr(__('Add to Compare')) ?>"
                                                    class="rounded-full w-10 h-10 bg-gray-200 p-0 border-0 inline-flex
                                                    items-center justify-center text-gray-500 hover:text-yellow-500"
                                                    data-addto="compare"
                                            >
                                            <?= $heroicons->scaleHtml('', 20, 20, ['aria-hidden' => 'true']) ?>
                                        </button>
                                        <?php endif; ?>
                                        <?php if ($wishlistViewModel->isEnabled()): ?>
                                            <button
                                                aria-label="<?= $escaper->escapeHtml(__('Add to Wish List')) ?>"
                                                @click.prevent="addToWishlist(product.id)"
                                                class="inline-flex items-center justify-center w-10 h-10 p-0 ml-auto
                                            text-gray-500 bg-gray-200 border-0 rounded-full hover:text-red-600"
                                                data-addto="wishlist"
                                            >
                                            <?= $heroicons->heartHtml('', 20, 20, ['aria-hidden' => 'true']) ?>
                                        </button>
                                        <?php endif; ?>
                                    </span>
                                </p>
                            </div>
                        </div>
                    </template>
                    <div :class="{
                        'js_dummy_slide w-full md:w-1/2 lg:w-1/3 xl:w-1/4 flex-none 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-none 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-none py-1' : pageFillers > 2
                        }"></div>
                </div>
            </div>
            <div style="min-height: 76px">
            <template x-if="products.length && products.length > pageSize">
                <div class="flex items-center justify-center flex-1 p-4">
                    <button
                        aria-label="<?= $escaper->escapeHtml(__('Previous')) ?>"
                        tabindex="-1"
                        class="w-8 h-8 mx-4 text-black rounded-full outline-none focus:outline-none"
                        :class="{ 'invisible' : active === 0 }"
                        @click="getSlider().scrollLeft =
                            (getSlider().scrollWidth / products.length) * (active-pageSize); active=active-pageSize;">
                        <?= $heroicons->chevronLeftHtml('', 20, 20, ['aria-hidden' => 'true']) ?>
                    </button>
                    <template x-for="(product, index) in products" :key="index">
                        <span class="shrink-0 block w-3 h-3 mx-1 bg-black bg-opacity-25 rounded-full shadow cursor-pointer"
                              tabindex="-1"
                              :class="{
                                    'bg-opacity-100': active === index,
                                    'bg-opacity-25': active !== index,
                                    'hidden': (pageSize !== 1 && !!(index % pageSize)),
                                    }"
                              @click="getSlider().scrollLeft =
                                    (getSlider().scrollWidth / products.length) * index; active=index;">
                        </span>
                    </template>
                    <button
                        aria-label="<?= $escaper->escapeHtml(__('Next')) ?>"
                        tabindex="-1"
                        class="w-8 h-8 mx-4 text-black rounded-full outline-none focus:outline-none"
                        :class="{ 'invisible' : active >= products.length-pageSize }"
                        @click="getSlider().scrollLeft =
                            (getSlider().scrollWidth / products.length) * (active+pageSize); active=active+pageSize">
                        <?= $heroicons->chevronRightHtml('', 20, 20, ['aria-hidden' => 'true']) ?>
                    </button>
                </div>
            </template>
            </div>
        </div>
    </template>
</section>
