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

declare(strict_types=1);

use Hyva\Theme\Model\ViewModelRegistry;
use Hyva\Theme\ViewModel\Cart\CheckoutConfig;
use Hyva\Theme\ViewModel\HyvaCsp;
use Magento\Checkout\Block\Cart;
use Magento\Framework\Escaper;

/** @var Cart $block */
/** @var Escaper $escaper */
/** @var HyvaCsp $hyvaCsp */
/** @var ViewModelRegistry $viewModels */

/** @var CheckoutConfig $checkoutConfigViewModel */
$checkoutConfigViewModel = $viewModels->require(CheckoutConfig::class);
$serializedCheckoutConfig =  $block->getItemsCount() ? $checkoutConfigViewModel->getSerializedCheckoutConfig() : 'false';

?>
<script>
    window.checkoutConfig = null;
    window.customerData = {};
    window.isCustomerLoggedIn = false;

    (function( hyva, undefined ) {

        let controller = new AbortController();

        /**
         * Takes a form element and submits it through fetch,
         * then replaces the result into the document without
         * refreshing the page
         */
        hyva.postCart = (form) => {
            if (!form.action) {
                return;
            }
            window.dispatchEvent(new CustomEvent("cart-is-loading", { detail: {
                isLoading: true
            }}));
            controller.abort();
            controller = new AbortController();

            const action = form.action;
            const formData = new FormData(form);

            if (!formData.uenc) {
                formData.append('uenc', hyva.getUenc());
            }

            formData.append('form_key', hyva.getFormKey());

            window.fetch(action, {
                method: 'POST',
                body: formData,
                signal: controller.signal
            }).then((result) => {
                return result.text()
            }).then((content) => {

                hyva.replaceDomElement('#maincontent', content)

            }).catch((error) => {
                if (error.name !== 'AbortError') {
                    console.error(error);
                    typeof window.dispatchMessages !== "undefined" && window.dispatchMessages(
                        [{
                            type: "error",
                            text: "<?= $escaper->escapeJs(__("Something went wrong. Please try again.")) ?>"
                        }], 10000
                    );
                }
            }).finally(() => {
                window.dispatchEvent(new CustomEvent('cart-is-loading', {
                    detail: {isLoading: false}
                }))
            })
        }
    }( window.hyva = window.hyva || {} ));

    function initCartForm() {
        let cartIsReloading = false;

        return {
            cartIsEmpty: true,
            isLoading: false,
            init() {
                window.checkoutConfig = JSON.parse(this.$root.dataset.checkoutConfig);
                window.customerData = window.checkoutConfig.customerData;
                window.isCustomerLoggedIn = window.checkoutConfig.isCustomerLoggedIn;

                this.cartIsEmpty = window.checkoutConfig === false;
            },
            checkCartShouldUpdate() {
                const cart = this.$event.detail.data.cart;
                if (!cart) return;

                const cartIsEmptyState = window.checkoutConfig === false;
                if (this.cartIsEmpty !== cartIsEmptyState) {
                    this.cartIsEmpty = cartIsEmptyState;
                    this.reloadCartContent();
                    return;
                }

                if (this.cartIsEmpty) return;

                if (!cart.items) {
                    this.reloadCartContent();
                    return;
                }

                if (!window.checkoutConfig && cart.items.length) {
                    this.reloadCartContent();
                    return;
                }

                const roundUp = (number) => Math.round(number * 1000);
                const decimalNumbersAreEqual = (number1, number2) => roundUp(number1) === roundUp(number2);

                if (decimalNumbersAreEqual(
                    cart.items.reduce((totalQty, cartItem) => totalQty + cartItem.qty, 0),
                        window.checkoutConfig.quoteData.items_qty
                    ) &&
                    decimalNumbersAreEqual(
                        cart.subtotalAmount,
                        window.checkoutConfig.totalsData.total_segments.find((segment) => segment.code === "subtotal").value
                    )
                ) {
                    return;
                }

                this.reloadCartContent();
            },
            reloadCartContent() {
                if (cartIsReloading) return;
                cartIsReloading = true;

                window.fetch(window.location.href, {
                    method: "GET"
                })
                .then((result) => result.text())
                .then((body) => {
                    hyva.setCookie('mage-cache-sessid', '', -1, true);
                    window.checkoutConfig = null;
                    hyva.replaceDomElement('#maincontent', body)

                })
                .catch(() => {
                    if (window.location.search.indexOf('reload=1') > -1) return;
                    window.location = window.location + (window.location.search.length < 1 ? '?' : '&') + 'reload=1'
                })
                .finally(() => {
                    cartIsReloading = false;
                })
            },
            onStorageChange() {
                if (this.$event.key === 'private_content_version') {
                    window.dispatchEvent(new CustomEvent("reload-customer-section-data"));
                }
            },
            onCartIsLoading() {
                this.isLoading = (this.$event.detail && this.$event.detail.isLoading) || false
            },
            proceedToCheckout() {
                this.$dispatch('toggle-authentication', { url: this.$el.href });
            },
            postCart() {
                hyva.postCart(this.$event.target)
            },
            removeItem() {
                hyva.postForm(JSON.parse(this.$el.dataset.deletePostJson));
                this.$dispatch('cart-item-removed', [JSON.parse(this.$el.dataset.cartItemRemovedPayload)]);
            },
            moveToWishlist() {
                hyva.postForm(JSON.parse(this.$el.dataset.postForm));
            }
        }
    }
    window.addEventListener('alpine:init', () => Alpine.data('initCartForm', initCartForm), { once: true })
</script>
<?php $hyvaCsp->registerInlineScript() ?>
<section
    x-data="initCartForm"
    class="cart-form"
    aria-label="<?= $escaper->escapeHtmlAttr(__('Shopping Cart')) ?>"
    @private-content-loaded.window="checkCartShouldUpdate"
    @storage.window="onStorageChange"
    @cart-is-loading.window="onCartIsLoading"
    data-checkout-config="<?= $escaper->escapeHtmlAttr($serializedCheckoutConfig) ?>"
>
    <?php if ($block->getItemsCount()): ?>
        <?= $block->getChildHtml('with-items') ?>
    <?php else: ?>
        <?= $block->getChildHtml('no-items') ?>
    <?php endif; ?>
    <?= $block->getChildHtml('loading') ?>
</section>
