<?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\HeroiconsOutline;
use Hyva\Theme\ViewModel\ProductPrice;
use Magento\Downloadable\Block\Catalog\Product\Links as DownloadableLinks;
use Magento\Framework\Escaper;

/** @var DownloadableLinks $block */
/** @var Escaper $escaper */
/** @var ViewModelRegistry $viewModels */
/** @var ProductPrice $productPriceViewModel */
/** @var HeroiconsOutline $iconViewModel */

if (!$block->getProduct()->isSaleable() && $block->hasLinks()) {
    return;
}

$productPriceViewModel    = $viewModels->require(ProductPrice::class);
$iconViewModel            = $viewModels->require(HeroiconsOutline::class);
$displayTax               = $productPriceViewModel->displayPriceIncludingTax();
$linksPurchasedSeparately = $block->getLinksPurchasedSeparately();
$links                    = $block->getLinks();
$configuredValues         = $block->getProduct()->getPreconfiguredValues();
$configuredLinks          = $configuredValues->getLinks() ?? [];
?>
<?php if ($linksPurchasedSeparately): ?>
<script>
    'use strict';
    function initDownloadableLinks(config) {

        const optionPrices = Object.keys(config.links).reduce((priceMap, optionId) => {
            const key = '<?= /** @noEscape  */ $displayTax ? 'finalPrice' : 'basePrice' ?>'
            priceMap[optionId] = config.links[optionId][key];
            return priceMap;
        }, {});

        return {
            selectedOptions: [],
            init() {
                this.$nextTick(() => {
                    window.dispatchEvent(new CustomEvent('update-custom-option-prices', {detail: optionPrices}));
                    [<?= /** @noEscape */ join(',', $configuredLinks)?>].map(linkId => {
                       this.toggleOption(linkId, true);
                    })
                    this.validate();
                })
            },
            toggleOption(optionId, value = true) {
                const elementToSelect = this.$root.querySelector('#links_' + optionId);
                if (elementToSelect) {
                    elementToSelect.checked = value;
                    elementToSelect.dispatchEvent(new Event('change'));
                }
            },
            validate() {
                const message = this.selectedOptions.length === 0
                    ? '<?= $escaper->escapeJs(__('Please select one of the options.')) ?>'
                    : ''
                const fields = this.$root.querySelectorAll('input[name="links[]"]');
                fields[fields.length - 1].setCustomValidity(message);
            },
            linkSelectionChange(checkbox)
            {
                const payload = {
                    customOptionId: checkbox.value,
                    active: checkbox.checked
                }
                window.dispatchEvent(new CustomEvent('update-custom-option-active', {detail: payload}));
                this.validate();
            },
            areAllSelected() {
                /**
                 * The way x-model works it can have duplicates, so we create a new set with unique values only.
                 */
                return new Set(this.selectedOptions).size === Object.keys(config.links).length
            },
            toggleAll() {
                const targetValue = !this.areAllSelected();
                Object.keys(config.links).map(link => {
                    this.toggleOption(link, targetValue)
                });
            }
        };
    }
</script>
<?php endif; ?>
<legend class="text-gray-900 text-xl title-font font-medium mb-4">
    <span><?= $escaper->escapeHtml($block->getLinksTitle()) ?></span>
</legend>
<div class="field downloads"
    <?php if ($linksPurchasedSeparately): ?>
     x-data="initDownloadableLinks(<?= $escaper->escapeHtmlAttr($block->getJsonConfig()) ?>)"
    <?php endif; ?>
>
    <div class="control" id="downloadable-links-list">
        <?php foreach ($links as $link): ?>
            <div class="flex flow-row justify-between">
                <div>
                    <?php if ($linksPurchasedSeparately): ?>
                        <input type="checkbox"
                               form="product_addtocart_form"
                               class="mr-2"
                               name="links[]"
                               id="links_<?= $escaper->escapeHtmlAttr($link->getId()) ?>"
                               value="<?= $escaper->escapeHtmlAttr($link->getId()) ?>"
                               <?= $escaper->escapeHtml($block->getLinkCheckedValue($link)) ?>
                               x-model="selectedOptions"
                               @change="linkSelectionChange($event.target)"
                        >
                        <label class="inline-block" for="links_<?= $escaper->escapeHtmlAttr($link->getId()) ?>">
                    <?php endif; ?>
                        <span><?= $escaper->escapeHtml($link->getTitle()) ?></span>
                    <?php if ($linksPurchasedSeparately): ?>
                            <?= /* @noEscape */ $block->getLinkPrice($link) ?>
                        </label>
                    <?php endif; ?>
                </div>
                <?php if ($link->getSampleFile() || $link->getSampleUrl()): ?>
                    <a class="item-link samples-item-link"
                       href="<?= $escaper->escapeUrl($block->getLinkSampleUrl($link)) ?>"
                       <?= $block->getIsOpenInNewWindow() ? 'target="_blank" rel="noopener"' : '' ?>>
                       <?= $iconViewModel->documentDownloadHtml('inline-block mr-1', 24, 24) ?>
                       <?= $escaper->escapeHtml(__('sample')) ?>
                    </a>
                <?php endif; ?>
            </div>
        <?php endforeach; ?>
        <?php if ($linksPurchasedSeparately && count($links) > 1): ?>
            <div class="field choice downloads-all">
                <button type="button" class="" @click="toggleAll">
                    <?= $iconViewModel->checkCircleHtml('inline-flex mr-1', 24, 24, ['aria-hidden' => 'true']) ?>
                    <span x-text="
                        areAllSelected()
                            ? '<?= $escaper->escapeJs(__('Unselect all')) ?>'
                            : '<?= $escaper->escapeJs(__('Select all')) ?>'
                    "><?= $escaper->escapeHtml(__('Select all')) ?></span>
                </button>
            </div>
        <?php endif; ?>
    </div>
</div>
