<?php
/**
 * BSS Commerce Co.
 *
 * NOTICE OF LICENSE
 *
 * This source file is subject to the EULA
 * that is bundled with this package in the file LICENSE.txt.
 * It is also available through the world-wide-web at this URL:
 * http://bsscommerce.com/Bss-Commerce-License.txt
 *
 * @category  BSS
 * @package   Bss_AjaxCart
 * @author    Extension Team
 * @copyright Copyright (c) 2022 BSS Commerce Co. ( http://bsscommerce.com )
 * @license   http://bsscommerce.com/Bss-Commerce-License.txt
 */

declare(strict_types=1);

use Hyva\Theme\Model\ViewModelRegistry;
use Hyva\Theme\ViewModel\HeroiconsOutline;
use Magento\Framework\Escaper;
use Magento\Framework\View\Element\Template;
use Hyva\BssAjaxCart\ViewModels\Helper as ModuleViewModel;
use Hyva\Theme\ViewModel\SvgIcons;

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

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

$moduleViewModel = $viewModels->require(ModuleViewModel::class);
$helperAjaxCart = $moduleViewModel->getHelper();

$hyvaicons = $viewModels->require(SvgIcons::class);

$product = $block->getData('product');
$viewIsGrid = $block->getData('view_is_grid');
$uniqueId = "_" . uniqid();
?>
<?php if ($helperAjaxCart->isEnabled()): ?>
    <script>
        'use strict';

        function initAjaxCart<?= $escaper->escapeHtmlAttr($uniqueId) ?>() {
            return {
                isLoading: false,
                flyToCart: <?= $moduleViewModel->getConfigFlyToCart()?>,
                action: "<?= $escaper->escapeJs($block->getUrl('ajaxcart')) ?>",
                getOffset(element) {
                    if (!element.getClientRects().length) {
                        return { top: 0, left: 0 };
                    }
                    var rect = element.getBoundingClientRect();
                    var win = element.ownerDocument.defaultView;
                    return ({
                        top: rect.top + win.pageYOffset,
                        left: rect.left + win.pageXOffset
                    });
                },
                ajaxFlyToCart(element) {
                    var speed = this.flyToCart.speed,
                        transparent = this.flyToCart.transparent,
                        miniCart = document.getElementById('menu-cart-icon'),
                        imgElement = element.querySelector('.product-item-photo img');

                    var imgclone = imgElement.cloneNode();
                    imgclone.style.top = this.getOffset(imgElement).top + 'px';
                    imgclone.style.left = this.getOffset(imgElement).left + 'px';
                    imgclone.style.height = imgElement.offsetHeight + 'px';
                    imgclone.style.width  = imgElement.offsetWidth + 'px';
                    imgclone.className = 'clone-image';
                    document.body.appendChild(imgclone);
                    var translateX = this.getOffset(miniCart).left - this.getOffset(imgclone).left;
                    var translateY = this.getOffset(miniCart).top - this.getOffset(imgclone).top;

                    imgclone.style.height = "30px";
                    imgclone.style.width = "30px";
                    imgclone.style.transform = `translate(${translateX}px,${translateY}px)`;
                    imgclone.style.transition = `all ${speed}s`;
                    if (transparent) {
                        imgclone.style.opacity = "0.5";
                    }

                    setTimeout(function () {
                        imgclone.remove();
                    }, (parseInt(speed) + 0.5)*1000);

                },
                addToCartSubmit() {
                    var self = this;
                    const form = this.$el.closest('.product_addtocart_form');

                    this.isLoading = true;

                    if (this.flyToCart.enable == 1) {
                        setTimeout(function () {
                            self.isLoading = false;
                            self.ajaxFlyToCart(form);
                        }, 1000);
                    }

                    let postData = {};
                    if (form) {
                        const formData = new FormData(form);
                        for (let field of formData.entries()) {
                            postData[field[0]] = field[1];
                        }
                    }

                    if (!postData?.form_key) {
                        postData.form_key = hyva.getFormKey();
                    }
                    postData.id = postData.product;
                    var requestConfigs = {
                        method: "POST",
                        headers: {
                            'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8',
                            'X-Requested-With': 'XMLHttpRequest'
                        },
                        mode: 'cors',
                        credentials: 'include',
                        dataType: 'json',
                        body: new URLSearchParams(postData)
                    };
                    const addToCartRequesting = fetch(this.action, requestConfigs);
                    addToCartRequesting
                        .then(response => responseSerialize(response))
                        .then(response => {
                            if (response.backUrl) {
                                window.location.href = response.backUrl;
                            } else if (response?.messages && !response.view) {
                                response.messages.map((msg) => {
                                    if (msg.type !== 'error') {
                                        return null;
                                    }
                                    window.dispatchMessages([
                                        {
                                            type: msg.type,
                                            text: msg.text
                                        }
                                    ], 3000);
                                });
                            } else if (response.error && response.view) {
                                this.isLoading = false;
                                window.dispatchEvent(
                                    new CustomEvent(
                                        "ajax-cart-popup-iframe",
                                        {
                                            detail: {
                                                open: true,
                                                url: response.url,
                                            }
                                        }
                                    )
                                );
                            } else if (response.popup) {
                                const popupContent = document.getElementById("popup-content");
                                popupContent.textContent ="";
                                popupContent.insertAdjacentHTML("beforeend", response.popup);
                                let scripts = popupContent.getElementsByTagName("script");
                                while (scripts.length) {
                                    const script = scripts[0];
                                    script.parentNode.removeChild(script);
                                    const newScript = document.createElement("script");
                                    newScript.setAttribute('type', 'text/javascript');

                                    const scriptId = script.getAttribute('id');
                                    if (scriptId) {
                                        const existedSript = document.getElementById(scriptId);
                                        if (existedSript) {
                                            continue;
                                        }
                                        newScript.setAttribute('id', scriptId);
                                    }
                                    if (script.src) {
                                        newScript.src = script.src;
                                    } else if (script.textContent) {
                                        newScript.textContent = script.textContent;
                                    } else if (script.innerText) {
                                        newScript.innerText = script.innerText;
                                    }
                                    document.body.appendChild(newScript);
                                }

                                this.isLoading = false;
                                window.dispatchEvent(new CustomEvent("ajax-cart-popup"));
                            }
                            window.dispatchEvent(new CustomEvent("reload-customer-section-data"));
                        }).catch(err => {
                        window.dispatchMessages([
                            {
                                type: 'error',
                                text: err
                            }
                        ], 3000);
                    });
                    return false;
                }
            }
        }
    </script>
    <button
        type="button" x-cloak
        x-data="initAjaxCart<?= $escaper->escapeHtmlAttr($uniqueId) ?>()"
        title="<?= $escaper->escapeHtmlAttr(__('Add to Cart')) ?>"
        class="w-auto btn btn-primary justify-center text-sm
            <?= $viewIsGrid ? 'mr-auto' : 'mr-auto md:mr-0' ?>"
        aria-label="<?= $escaper->escapeHtmlAttr(__('Add to Cart')) ?>"
        @click.prevent="addToCartSubmit()"
    >
        <div class="flex flex-row justify-center items-center w-full h-full fixed select-none"
             style="left: 50%;top: 50%;transform: translateX(-50%) translateY(-50%);background: rgba(255,255,255,0.7);"
             x-show="isLoading"
             x-transition:enter="ease-out duration-200"
             x-transition:enter-start="opacity-0"
             x-transition:enter-end="opacity-100"
             x-transition:leave="ease-in duration-200"
             x-transition:leave-start="opacity-100"
             x-transition:leave-end="opacity-0">
            <?= $hyvaicons->loaderHtml('text-primary', 57, 57); ?>
            <div class="ml-10 text-primary text-xl">
                <?= $escaper->escapeHtml(__('Loading...')) ?>
            </div>
        </div>
        <?= $heroicons->shoppingCartHtml("h-6 w-6 border-current inline", 25, 25) ?>
        <span class="ml-2 inline <?= $viewIsGrid ? 'md:ml-0 md:hidden lg:ml-2 lg:inline' : '' ?>">
            <?= $escaper->escapeHtml(__('Add to Cart')) ?>
        </span>
    </button>
<?php else: ?>
    <?php if ($product->isSaleable()): ?>
        <button class="w-auto btn btn-primary justify-center text-sm
            <?= $viewIsGrid ? 'mr-auto' : 'mr-auto md:mr-0' ?>"
                aria-label="<?= $escaper->escapeHtmlAttr(__('Add to Cart')) ?>"
        >
            <?= $heroicons->shoppingCartHtml("h-6 w-6 border-current inline", 25, 25) ?>
            <span class="ml-2 inline <?= $viewIsGrid ? 'md:ml-0 md:hidden lg:ml-2 lg:inline' : '' ?>">
            <?= $escaper->escapeHtml(__('Add to Cart')) ?>
        </span>
        </button>
    <?php endif; ?>
<?php endif ?>
<?= $block->getChildHtml('', true) ?>
