<?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\LucideIcons;
use Hyva\Theme\ViewModel\StoreConfig;
use Magento\Framework\Escaper;
use Magento\GiftMessage\Block\Cart\GiftOptions;

/** @var Escaper $escaper */
/** @var GiftOptions $block */
/** @var ViewModelRegistry $viewModels */
/** @var StoreConfig $storeConfigViewModel */

$storeConfigViewModel = $viewModels->require(StoreConfig::class);

$isOrderLevelGiftOptionsEnabled = $storeConfigViewModel->getStoreConfig('sales/gift_options/allow_order');
$isItemLevelGiftOptionsEnabled = $storeConfigViewModel->getStoreConfig('sales/gift_options/allow_items');
// Gift Wrapping is a feature for Adobe Commerce Only. On Magento Open Source these config values will always return null.
$isOrderLevelGiftWrappingEnabled = $storeConfigViewModel->getStoreConfig('sales/gift_options/wrapping_allow_order');
$isItemLevelGiftWrappingEnabled = $storeConfigViewModel->getStoreConfig('sales/gift_options/wrapping_allow_items');

if (! $isOrderLevelGiftOptionsEnabled && ! $isItemLevelGiftOptionsEnabled &&
    ! $isOrderLevelGiftWrappingEnabled && ! $isItemLevelGiftWrappingEnabled) {
    return;
}

/** @var LucideIcons $lucideIcons */
$lucideIcons = $viewModels->require(LucideIcons::class);
?>
<script>
    window.giftOptionsConfig = <?= /* @noEscape */ $block->getGiftOptionsConfigJson() ?>;

    function initGiftOptions() {
        return {
            formBlockVisibility: false,
            resultBlockVisibility: false,
            hasActiveOptions: false,
            itemId: 'orderLevel',
            isGiftMsgEnabled: window.giftOptionsConfig.isOrderLevelGiftOptionsEnabled,
            <?php
                // Gift Wrapping is a feature for Adobe Commerce Only.
                // On Magento Open Source this condition will always return false.
            ?>
            isGiftWrapEnabled: window.giftOptionsConfig.giftWrapping && window.giftOptionsConfig.giftWrapping.allowForOrder,
            formMessage: {
                recipient: null,
                sender: null,
                message: null,
                alreadyAdded: null,
            },
            savedFormMessage: {
                recipient: null,
                sender: null,
                message: null,
                alreadyAdded: null,
            },
            extensionAttributes: {},
            isLoading: false,
            getMessage() {
                return window.giftOptionsConfig.giftMessage.hasOwnProperty(this.itemId)
                    ? window.giftOptionsConfig.giftMessage[this.itemId]
                    : null;
            },
            init() {
                const message = this.getMessage();
                const isObject = Object.prototype.toString.call(message) === '[object Object]';

                if (isObject) {
                    this.savedFormMessage.recipient = message.recipient;
                    this.savedFormMessage.sender = message.sender;
                    this.savedFormMessage.message = message.message;
                    this.savedFormMessage.alreadyAdded = true;
                    this.formMessage = Object.assign({}, this.savedFormMessage);
                    this.resultBlockVisibility = true;
                }

                this.initEventListeners();
            },
            initEventListeners() {
                window.addEventListener('additional-gift-options-loaded-' + this.itemId, (event) => {
                    if (this.hasActiveOptions) return;

                    if (event.detail.isOrderLevelGiftOptionsEnabled) this.hasActiveOptions = true;
                });

                window.addEventListener('additional-gift-options-results-' + this.itemId, (event) => {
                    if (this.resultBlockVisibility) return;

                    this.resultBlockVisibility = event.detail.hasResults;
                });

                window.addEventListener('update-gift-options-extension-attributes-' + this.itemId, (event) => {
                    this.extensionAttributes = Object.assign({}, this.extensionAttributes, event.detail);
                });
            },
            getRestEndpoint() {
                const restBaseUrl = BASE_URL + 'rest/' + CURRENT_STORE_CODE + '/V1/';
                return window.giftOptionsConfig.isCustomerLoggedIn
                    ? restBaseUrl + 'carts/mine/gift-message'
                    : restBaseUrl + 'guest-carts/' + window.checkoutConfig.quoteData.entity_id + '/gift-message';
            },
            clearGiftOption() {
                this.formMessage = {
                    recipient: null,
                    sender: null,
                    message: null,
                    alreadyAdded: null,
                };
            },
            submitGiftOption() {
                window.dispatchEvent(new CustomEvent('before-gift-options-submit-' + this.itemId, {
                    detail: {}
                }))

                window.dispatchEvent(new Event('gift-message-loading-start'));

                fetch(this.getRestEndpoint(), {
                    method: 'post',
                    headers: {
                        'Content-Type': 'application/json',
                        'X-Requested-With': 'XMLHttpRequest'
                    },
                    body: JSON.stringify({
                        gift_message: {
                            recipient: this.formMessage.recipient,
                            sender: this.formMessage.sender,
                            message: this.formMessage.message,
                            extension_attributes: this.extensionAttributes
                        }
                    }),
                }).then(response => {
                    if (response.ok) {
                        return response.json();
                    } else {
                        console.warn("GET request failed", response);
                    }
                }).then(() => {
                    this.savedFormMessage = Object.assign({}, this.formMessage);
                    document.querySelector('form[action*="checkout/cart/updatePost/"]').submit()
                });
            },
            openDialog(event) {
                this.formBlockVisibility = true
            },
            closeDialog() {
                this.formBlockVisibility = false
            },
            eventListeners: {
                ['@gift-message-loading-start.window']() {
                    this.isLoading = true;
                },
                ['@gift-message-loading-end.window']() {
                    this.isLoading = false;
                }
            }
        }
    }

    function initGiftItemOptions() {
        const itemId = this.$root.dataset.itemId;
        return Object.assign({}, initGiftOptions(), {
            itemId: itemId,
            isGiftMsgEnabled: window.giftOptionsConfig.isItemLevelGiftOptionsEnabled &&
                window.giftOptionsConfig.giftMessage.itemLevel[`${itemId}`].is_available !== false,
            <?php
                // Gift Wrapping is a feature for Adobe Commerce Only.
                // On Magento Open Source this condition will always return false.
            ?>
            isGiftWrapEnabled: window.giftOptionsConfig.giftWrapping && window.giftOptionsConfig.giftWrapping.allowForItems &&
                window.giftOptionsConfig.giftWrapping.itemsInfo[`${itemId}`].is_available !== false,
            getMessage() {
                return window.giftOptionsConfig.giftMessage.hasOwnProperty('itemLevel') &&
                window.giftOptionsConfig.giftMessage.itemLevel.hasOwnProperty(itemId)
                    ? window.giftOptionsConfig.giftMessage.itemLevel[itemId].message
                    : null;
            },
            initEventListeners() {
                window.addEventListener('additional-gift-options-loaded-' + itemId, (event) => {
                    if (this.hasActiveOptions) return;

                    if (event.detail.isItemLevelGiftOptionsEnabled) this.hasActiveOptions = true;
                });

                window.addEventListener('additional-gift-options-results-' + itemId, (event) => {
                    if (this.resultBlockVisibility) return;

                    this.resultBlockVisibility = event.detail.hasResults;
                });

                window.addEventListener('update-gift-options-extension-attributes-' + itemId, (event) => {
                    this.extensionAttributes = Object.assign({}, this.extensionAttributes, event.detail);
                });
            },
            getRestEndpoint() {
                const restBaseUrl = BASE_URL + 'rest/' + CURRENT_STORE_CODE + '/V1/';
                return window.giftOptionsConfig.isCustomerLoggedIn
                    ? restBaseUrl + 'carts/mine/gift-message/' + itemId
                    : restBaseUrl + 'guest-carts/' + window.checkoutConfig.quoteData.entity_id + '/gift-message/' + itemId;
            }
        })
    }

    window.addEventListener('alpine:init', () => {
        Alpine.data('initGiftOptions', initGiftOptions);
        Alpine.data('initGiftItemOptions', initGiftItemOptions);
    }, { once: true })
</script>
<?php $hyvaCsp->registerInlineScript() ?>

<?php

if (! $isOrderLevelGiftOptionsEnabled && ! $isOrderLevelGiftWrappingEnabled) {
    return;
}
// Only render the DOM elements for order level gift options if either or both gift messages or gift wrapping are enabled
?>
<div x-data="initGiftOptions" x-bind="eventListeners">
    <button
        type="button"
        class="btn w-full"
        aria-label="<?= $escaper->escapeHtml(__('Add Gift Options for the Entire Order')) ?>"
        @click="openDialog"
    >
        <span class="relative">
            <span
                class="absolute -top-2 -right-2 rounded-full p-1 bg-primary text-on-primary"
                x-show="savedFormMessage.message"
                x-cloak
            >
                <?= $lucideIcons->mailHtml('', 12, 12, ['aria-hidden' => 'true']) ?>
            </span>
            <?= $lucideIcons->giftHtml('', 20, 20, ['aria-hidden' => 'true']) ?>
        </span>
        <?= $escaper->escapeHtml(__('Gift options')) ?>
    </button>

    <dialog
        class="w-xl"
        x-show="formBlockVisibility"
        x-transition
        x-htmldialog="closeDialog"
    >
        <p class="text-xl mb-4">
            <strong><?= $escaper->escapeHtml(__('Add Gift Options for the Entire Order')) ?></strong>
        </p>
        <?= $block->getChildHtml('gift-options-body') ?>
    </dialog>
</div>
