<?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 Hyva\Theme\ViewModel\HeroiconsSolid;
use Hyva\Theme\ViewModel\ProductAttributes;
use Hyva\Theme\ViewModel\Wishlist;
use Magento\Catalog\Block\Product\Compare\ListCompare;
use Magento\Catalog\Helper\Product\Compare;
use Magento\Catalog\Model\Product;
use Magento\Framework\Escaper;
use Magento\Wishlist\Helper\Data as WishlistHelper;
use Hyva\BssAjaxCart\ViewModels\Helper as ModuleViewModel;
use Hyva\Theme\ViewModel\SvgIcons;

// phpcs:disable PSR2.ControlStructures.SwitchDeclaration
// phpcs:disable Generic.WhiteSpace.ScopeIndent
// phpcs:disable Magento2.Templates.ThisInTemplate.FoundHelper

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

/** @var Compare $compareHelper */
$compareHelper = $this->helper(Compare::class);

/** @var WishlistHelper $wishlistHelper */
$wishlistHelper = $this->helper(WishlistHelper::class);

/** @var ProductAttributes $attributesViewModel */
$attributesViewModel = $viewModels->require(ProductAttributes::class);

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

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

/** @var HeroiconsSolid $heroiconsSolid */
$heroiconsSolid = $viewModels->require(HeroiconsSolid::class);

$moduleViewModel = $viewModels->require(ModuleViewModel::class);
$helperAjaxCart = $moduleViewModel->getHelper();
$hyvaicons = $viewModels->require(SvgIcons::class);
?>
<?php $total = $block->getItems()->getSize(); ?>
<?php if ($total): ?>
    <script>
        function initPrint() {
            return {
                print() {
                    window.print();
                }
            };
        }

        function initCompareOnCompareList() {
            return {
                removeFromCompare(productId, productName) {
                    const formKey = hyva.getFormKey();
                    const postUrl = BASE_URL + 'catalog/product_compare/remove/';
                    const confirmMessage = "<?= $escaper->escapeHtml(
                        __('Are you sure you want to remove this item from your Compare Products list?')
                    ) ?>";
                    if (!window.confirm(confirmMessage)) {
                        return;
                    }

                    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 remove item from compare.')) ?>"
                                }], 5000
                            );
                        }
                    }).then(function (response) {
                        if (!response) { return; }
                        typeof window.dispatchMessages !== "undefined" && window.dispatchMessages(
                            [{
                                type: (response.success) ? "success" : "error",
                                text: (response.success)
                                    ? "<?= $escaper->escapeHtml(
                                        __("You removed product %1 from the comparison list")
                                    ) ?>".replace('%1', productName)
                                    : response.error_message
                            }], 5000
                        );
                        let reloadCustomerDataEvent = new CustomEvent("reload-customer-section-data");
                        window.dispatchEvent(reloadCustomerDataEvent);
                    }).catch(function (error) {
                        typeof window.dispatchMessages !== "undefined" && window.dispatchMessages(
                            [{
                                type: "error",
                                text: error
                            }], 5000
                        );
                    });
                }
            };
        }

        function initWishlist() {
            return {
                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
                        );
                    });
                }
            }
        }
    </script>
    <section>
        <div class="container">
            <button x-data="initPrint()"
                    @click.prevent="print()"
                    class="mb-2"
                    title="<?= $escaper->escapeHtmlAttr(__('Print This Page')) ?>">
                <?= $heroicons->printerHtml('inline'); ?>
                <span><?= $escaper->escapeHtml(__('Print This Page')) ?></span>
            </button>
        </div>
        <div class="table-wrapper container md:mx-auto md:px-6 overflow-x-auto py-4">
            <table class="table-auto">
                <caption class="sr-only"><?= $escaper->escapeHtml(__('Compare Products')); ?></caption>
                <tbody>
                <tr>
                    <?php $index = 0; ?>
                    <?php /** @var Product $product */ ?>
                    <?php foreach ($block->getItems() as $product): ?>
                        <?php if ($index++ === 0): ?>
                            <th scope="row" class="w-44 border border-gray-300 py-2 px-3 text-left align-top">
                                <span><?= $escaper->escapeHtml(__('Product')) ?></span>
                            </th>
                        <?php endif; ?>
                        <td class="relative w-60 bg-gray-100 border border-gray-300 py-2 px-3 align-top compare-product-info">
                            <div class="flex flex-col">
                                <a href="<?= $escaper->escapeUrl($block->getProductUrl($product)) ?>"
                                   class="block mb-3"
                                   title="<?= $escaper->escapeHtmlAttr($product->getName()) ?>">
                                    <?= $block->getImage(
                                        $product,
                                        'product_comparison_list'
                                    )->setTemplate('Magento_Catalog::product/image.phtml')->toHtml() ?>
                                </a>
                                <strong>
                                    <a href="<?= $escaper->escapeUrl($block->getProductUrl($product)) ?>"
                                       title="<?= $escaper->escapeHtmlAttr($product->getName()) ?>">
                                        <?= $escaper->escapeHtml($product->getName()) ?>
                                    </a>
                                </strong>
                                <?= /* @noEscape */ $block->getProductPrice($product, '-compare-list-top') ?>
                                <div class="flex mt-auto pt-3 items-center">
                                    <?php if ($product->isSaleable()): ?>
                                        <form data-role="tocart-form"
                                              action="<?= $escaper
                                                  ->escapeUrl($compareHelper->getAddToCartUrl($product)) ?>"
                                              method="post"
                                              class="mr-auto">
                                            <?= $block->getBlockHtml('formkey') ?>
                                            <?php if ($helperAjaxCart->isEnabled()): ?>
                                                <script>
                                                    'use strict';

                                                    function initAjaxCart<?= $product->getId() ?>() {
                                                        return {
                                                            isLoading: false,
                                                            flyToCart: <?= $moduleViewModel->getConfigFlyToCart()?>,
                                                            action: "<?= $escaper->escapeJs($block->getUrl('ajaxcart')) ?>",
                                                            productId: <?= $product->getId() ?>,
                                                            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-image-photo');

                                                                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 productInfo = this.$el.closest('.compare-product-info');

                                                                this.isLoading = true;

                                                                if (this.flyToCart.enable == 1) {
                                                                    setTimeout(function () {
                                                                        self.isLoading = false;
                                                                        self.ajaxFlyToCart(productInfo);
                                                                    }, 1000);
                                                                }
                                                                let postData = {};
                                                                if (!postData?.form_key) {
                                                                    postData.form_key = hyva.getFormKey();
                                                                }
                                                                postData.id = this.productId;
                                                                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<?= $product->getId() ?>()"
                                                    form="product_addtocart_form"
                                                    title="<?= $escaper->escapeHtmlAttr(__('Add to Cart')) ?>"
                                                    class="w-auto mr-auto btn btn-primary justify-center text-sm px-2"
                                                    @click.prevent="addToCartSubmit()"
                                                >
                                                    <div class="flex flex-row justify-center items-center w-full h-full fixed select-none z-30"
                                                         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('border-current'); ?>
                                                    <span><?= $escaper->escapeHtml(__('Add to Cart')) ?></span>
                                                </button>
                                            <?php else: ?>
                                                <button type="submit"
                                                        class="w-auto mr-auto btn btn-primary justify-center text-sm px-2"
                                                        aria-label="<?= $escaper->escapeHtmlAttr(__('Add to Cart')) ?>"
                                                >
                                                    <?= $heroicons->shoppingCartHtml('border-current inline'); ?>
                                                    <span class="sr-only">
                                                    <?= $escaper->escapeHtml(__('Add to Cart')) ?>
                                                </span>
                                                </button>
                                            <?php endif ?>
                                        </form>
                                    <?php endif; ?>
                                    <?php if ($wishlistViewModel->isEnabled()): ?>
                                        <button x-data="initWishlist()"
                                                @click.prevent="addToWishlist(<?= (int)$product->getId() ?>)"
                                                aria-label="<?= $escaper->escapeHtmlAttr(__('Add to Wish List')) ?>"
                                                class="rounded-full w-9 h-9 bg-gray-200 p-0 border-0 inline-flex
                                            flex-shrink-0 items-center justify-center text-gray-500 hover:text-red-600
                                            ml-2"
                                        >
                                            <?= $heroiconsSolid->heartHtml('', 20, 20); ?>
                                        </button>
                                    <?php endif; ?>
                                    <button x-data="initCompareOnCompareList()"
                                            @click.prevent="removeFromCompare(<?= (int)$product->getId() ?>, '<?= $escaper
                                                ->escapeJs($product->getName()) ?>')"
                                            aria-label="<?= $escaper->escapeHtmlAttr(__('Remove Product')) ?>"
                                            class="rounded-full w-9 h-9 bg-gray-200 p-0 border-0 inline-flex flex-shrink-0
                                        items-center justify-center text-gray-500 hover:text-black ml-2"
                                            title="<?= $escaper->escapeHtmlAttr(__('Remove Product')) ?>">
                                        <?= $heroicons->xHtml('', 20, 20); ?>
                                    </button>
                                </div>
                            </div>
                        </td>
                    <?php endforeach; ?>
                </tr>
                <tr>
                    <?php $index = 0; ?>
                    <?php /** @var Product $product */ ?>
                    <?php foreach ($block->getItems() as $product): ?>
                        <?php if ($index++ === 0): ?>
                            <th scope="row" class="min-w-40 border border-gray-300 py-2 px-3 text-left align-top">
                                <span><?= $escaper->escapeHtml(__('Review score')) ?></span>
                            </th>
                        <?php endif; ?>
                        <td class="relative min-w-48 border border-gray-300 py-2 px-3 align-top">
                            <?= $block->getReviewsSummaryHtml($product, 'short') ?>
                        </td>
                    <?php endforeach; ?>
                </tr>
                <?php foreach ($block->getAttributes() as $attribute): ?>
                    <?php $index = 0; ?>
                    <?php if ($block->hasAttributeValueForProducts($attribute)): ?>
                        <tr>
                            <?php /** @var Product $product */ ?>
                            <?php foreach ($block->getItems() as $product): ?>
                                <?php if ($index++ === 0): ?>
                                    <th scope="row" class="border border-gray-300 py-2 px-3 text-left align-top">
                                        <span>
                                            <?= $escaper
                                                ->escapeHtml(
                                                    $attribute->getStoreLabel() ?:
                                                        __($attribute->getFrontendLabel())
                                                ) ?>
                                        </span>
                                    </th>
                                <?php endif; ?>
                                <td class="border border-gray-300 py-2 px-3 align-top">
                                    <div>
                                        <?php switch ($attribute->getAttributeCode()) {
                                            case 'price': ?>
                                                <?=
                                                /* @noEscape */ $block->getProductPrice(
                                                    $product,
                                                    '-compare-list-' . $attribute->getCode()
                                                )
                                                ?>
                                                <?php break;
                                            case 'small_image': ?>
                                                <?= $block->getImage($product, 'product_small_image')->toHtml(); ?>
                                                <?php break;
                                            case 'short_description':
                                            case 'description': ?>
                                                <?php
                                                $attributeData = $attributesViewModel->getAttributeData(
                                                    $attribute,
                                                    $product
                                                )
                                                ?>
                                                <?= /* @noEscape */ $attributeData['value'] ?>
                                                <?php break;
                                            default :?>
                                                <?php
                                                $attributeData = $attributesViewModel->getAttributeData(
                                                    $attribute,
                                                    $product
                                                )
                                                ?>
                                                <?= $escaper->escapeHtml($attributeData['value'], ['p', 'br']) ?>
                                                <?php break;
                                        } ?>
                                    </div>
                                </td>
                            <?php endforeach; ?>
                        </tr>
                    <?php endif; ?>
                <?php endforeach; ?>
                </tbody>
            </table>
        </div>
    </section>
<?php else: ?>
    <section>
        <div class="container"><?= $escaper->escapeHtml(__('You have no items to compare.')) ?></div>
    </section>
<?php endif; ?>
