<?php
/**
 * @var string $customDateFormat
 * @var DateTime $newDateTime
 * @var string $timeZoneLabel
 * @var boolean $postAuctionSaleOpenedUntil
 * @var string $auctionCatalog
 * @var string $dateTime
 * @var string $part
 * @var string $hiddenPrice
 * @var string $countLots
 * @var string $auctionBg
 * @var string $showEstimatedPriceInItemsList
 * @var string $displayStartPriceInCatalog
 * @var string $bgStyle
 * @var WP_Term $auction
 * @var stdClass $auctionDay
 * @var WP_Post $post
 * @var string $usePagination
 * @var array $categoryList
 * @var string $possibleBids
 * @var bool $isArchived
 * @var string $timeZoneName
 * @var array $linksDays
 * @var string $catalogLayout
 */

use auctionforge\inc\abs\ImageModel;
use auctionforge\inc\controllers\Settings;
use auctionforge\inc\helpers\LotHelper;
use auctionforge\inc\helpers\SettingsHelper;
use auctionforge\inc\helpers\View;
use auctionforge\inc\model\Auction;
use auctionforge\inc\model\LotImage;

if (!defined('ABSPATH')) {
    exit;
}

$auction = apply_filters('auctionforge_prepare_auction_object', $auction);
$auctionId = SettingsHelper::getTermOption($auction->term_id, 'auction_id');
$auctionTitle = apply_filters('auctionforge_auction_name_build', $auction->name, $auction);

$auctionAddress = SettingsHelper::getTermOption($auction->term_id, 'auction_address');
$auctionInfo = SettingsHelper::getTermOption($auction->term_id, 'auction_info');

$isShop = Auction::isAuctionShop($auction->term_id);
// A real BidSpirit Shop, as opposed to an auction merely presented as one.
// The front end needs to tell them apart: a shop has no auction behind it, so
// the auction endpoints must not be called for it.
$isBsShop = \auctionforge\inc\model\Shop::isShopTerm($auction->term_id);

if (!empty($auctionDay->details) && $auctionDay->details != "") {
    $auctionInfo = $auctionDay->details;
}

if ($auctionInfo == "") {
    $auctionInfo = $auctionDay->name;
}

if (preg_match('/^\[.+\]$/', $auction->description)) {
    $auctionInfo = $auction->description;
}

$layoutStyle = SettingsHelper::getOption(Settings::LAYOUT_STYLE, 'classic');
$catalogLayout = isset($catalogLayout) ? $catalogLayout : SettingsHelper::getOption(Settings::CATALOG_LAYOUT, 'standard');
$filterCategoryBy = isset($_GET['category_by']) ? $_GET['category_by'] : '';

get_header(); ?>
<div class="bp-container-fluid">

<?php if ($layoutStyle === 'minimal') { ?>
    <?php
    $auctionCoverImage = '';
    if (!empty($auctionDay->image)) {
        $auctionCoverImage = $auctionDay->image;
    } elseif (!empty($bgImage)) {
        $auctionCoverImage = $bgImage;
    }
    ?>
    <div class="bp-header__content-minimal">
        <?php if (!empty($auctionCoverImage)) { ?>
            <div class="minimal-header-thumb">
                <img src="<?= esc_url($auctionCoverImage) ?>" alt="<?= esc_attr($auctionTitle) ?>">
            </div>
        <?php } ?>
        <div class="minimal-header-left">
            <h1 class="title title-sm">
                <?= $auctionTitle ?>
            </h1>
            <?php if (!$isShop) { ?>
                <p id="dateTimeField" class="bp-item-header__time"
                   data-custom-format="<?= $customDateFormat ?>"
                   data-custom-format-time="<?= date_i18n($customDateFormat, $newDateTime->getTimestamp()) . " " . $timeZoneLabel ?>"
                   data-time="<?= $dateTime ?>"
                   data-unknown-exact-date="<?= $auctionDay->unknownExactDate ?>"
                   data-time-zone="<?= $timeZoneName ?>"
                   data-unknown-date="<?= date_i18n("F Y", strtotime($dateTime)) ?>">
                </p>
            <?php } ?>
        </div>
    </div>
<?php } else { ?>
    <?php if (!empty($bgImage)) { ?>
        <div class="bp-header bp-row bp-single-page" style="background-image: url('<?= $bgImage ?>')">
    <?php } else { ?>
        <div class="bp-header bp-row bp-single-page">
    <?php } ?>
        <div class="bp-header__overlay"></div>
        <div class="bp-header__content">
            <h1><?= $auctionTitle ?></h1>
            <?php if (!$isShop) { ?>
                <p id="dateTimeField" class="bp-header__time" data-custom-format="<?= $customDateFormat ?>"
                   data-custom-format-time="<?= date_i18n($customDateFormat, $newDateTime->getTimestamp()) . " " . $timeZoneLabel ?>"
                   data-time="<?= $dateTime ?>"
                   data-unknown-exact-date="<?= $auctionDay->unknownExactDate ?>"
                   data-time-zone="<?= $timeZoneName ?>"
                   data-unknown-date="<?= date_i18n("F Y", strtotime($dateTime)) ?>"></p>
            <?php } ?>
            <div class="bp-d-flex bp-sm-f-wrap bp-sm-f-center">
                <div id="userFront" class="bp-header__btn-group bp-d-flex bp-sm-f-wrap bp-sm-f-center"></div>
                <?php do_action('bp_user_front_action') ?>
            </div>
        </div>
        </div>
<?php } ?>

    </div>
    <div id="bp-notice-block" class="bp-main-container"></div>
    <?php do_action('bp_notice_action') ?>
    <?php do_action('bp_before_content_auction') ?>
    <div class="bp-container bp-fix-width-lot">
        <?php do_action('bp_before_inner_content_auction') ?>
        <div class="bp-content bp-justify-between bp-row bp-no-margin bp-add-padding bp-auction-content">
            <div class="bp-col bp-d-flex bp-md-f-wrap">
                <?php if ($auctionInfo != "") { ?>
                <style>
                .af-auction-accordion {
                    border: 1px solid #e0e0e0;
                    border-radius: 6px;
                    margin-bottom: 15px;
                    overflow: hidden;
                    background: #fafafa;
                    width: 100%;
                }
                .af-auction-accordion__header {
                    display: flex;
                    align-items: center;
                    justify-content: space-between;
                    padding: 14px 20px;
                    cursor: pointer;
                    user-select: none;
                    background: #f5f5f5;
                    border: none;
                    width: 100%;
                    text-align: left;
                    font-family: inherit;
                    transition: background 0.2s ease;
                }
                .af-auction-accordion__header:hover {
                    background: #ebebeb;
                }
                .af-auction-accordion__title {
                    font-size: 16px;
                    font-weight: 600;
                    color: #333;
                    margin: 0;
                    line-height: 1.4;
                }
                .af-auction-accordion__chevron {
                    width: 28px;
                    height: 28px;
                    transition: transform 0.3s ease;
                    flex-shrink: 0;
                    margin-left: 12px;
                }
                .af-auction-accordion__chevron svg {
                    width: 100%;
                    height: 100%;
                    fill: #555;
                }
                .af-auction-accordion.is-open .af-auction-accordion__chevron {
                    transform: rotate(180deg);
                }
                .af-auction-accordion__body {
                    max-height: 0;
                    overflow: hidden;
                    transition: max-height 0.4s ease;
                }
                .af-auction-accordion.is-open .af-auction-accordion__body {
                    max-height: 2000px;
                }
                .af-auction-accordion__content {
                    padding: 18px 20px;
                    border-top: 1px solid #e0e0e0;
                }
                </style>
                <?php
                    $af_accordion_open = SettingsHelper::isChecked('auction_info_default_open', 'off');
                    $af_accordion_heading = SettingsHelper::getOption('auction_info_heading', '');
                    if (empty($af_accordion_heading)) {
                        $af_accordion_heading = __('View Auction Information', 'auctionforge');
                    }
                ?>
                <div class="af-auction-accordion<?= $af_accordion_open ? ' is-open' : '' ?>" id="af-auction-info-accordion">
                    <button type="button" class="af-auction-accordion__header" id="af-auction-info-toggle" aria-expanded="<?= $af_accordion_open ? 'true' : 'false' ?>" aria-controls="af-auction-info-body">
                        <span class="af-auction-accordion__title"><?= esc_html($af_accordion_heading) ?></span>
                        <span class="af-auction-accordion__chevron">
                            <svg viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path d="M7.41 8.59L12 13.17l4.59-4.58L18 10l-6 6-6-6z"/></svg>
                        </span>
                    </button>
                    <div class="af-auction-accordion__body" id="af-auction-info-body">
                        <div class="af-auction-accordion__content bp-content__text bp-justify-between">
                            <?php do_action('bp_before_description_auction', $auction, $auctionTitle, $auctionDay) ?>
                            <?php
                            // BidSpirit details may arrive as HTML (with <p>/<br> tags) or plain text.
                            // If already HTML, output directly (skip wpautop which corrupts existing tags).
                            // If plain text, convert newlines and run through the_content filter.
                            if (preg_match('/<(p|br|div|ul|ol|li|h[1-6])\b/i', $auctionInfo)) {
                                echo wp_kses_post($auctionInfo);
                            } else {
                                echo apply_filters('the_content', nl2br($auctionInfo));
                            }
                            ?>
                            <?php
                            // Render display hours / collection hours with spacing
                            // Only show displayHours if not already mentioned in the description
                            if (!empty($auctionDay->displayHours) && $auctionDay->displayHours != ''
                                && stripos(strip_tags($auctionInfo), strip_tags($auctionDay->displayHours)) === false) { ?>
                                <div style="margin-top:1.2em"><?= wp_kses_post($auctionDay->displayHours) ?></div>
                            <?php }
                            if (!empty($auctionDay->collectionHours) && $auctionDay->collectionHours != '') { ?>
                                <div style="margin-top:0.8em"><?= wp_kses_post($auctionDay->collectionHours) ?></div>
                            <?php } ?>
                            <?php do_action('bp_after_description_auction', $auction, $auctionTitle, $auctionDay) ?>
                        </div>
                    </div>
                </div>
                <script>
                (function(){
                    var toggle = document.getElementById('af-auction-info-toggle');
                    var accordion = document.getElementById('af-auction-info-accordion');
                    if (toggle && accordion) {
                        toggle.addEventListener('click', function() {
                            var isOpen = accordion.classList.contains('is-open');
                            accordion.classList.toggle('is-open');
                            toggle.setAttribute('aria-expanded', !isOpen);
                        });
                    }
                })();
                </script>
                <?php } ?>
                <div class="bp-content__wrp-tools bp-d-flex bp-f-wrap bp-gap-2">
                    <?php if ($auctionCatalog != '') { ?>
                        <div class="bp-content__tool bp-d-flex bp-f-end bp-md-f-start">
                            <?= View::render('templates.parts.download-catalog', array('auction_download_link' => $auctionCatalog)); ?>
                        </div>
                    <?php } ?>
                    <?php if (!empty($linksDays)) { ?>
                    <div class="bp-content-days">
                        <?php
                        $options = "";
                        $domain = get_site_url();
                        $url = parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH);
                        $page = get_query_var('paged');
                        foreach($linksDays as $key => $link) {
                            $currentLink = $link;
                            if ($page > 0) {
                                $currentLink .= "page/" . $page . "/";
                            }
                            $currentLink = str_replace([$domain, "page/1/"], "", $currentLink);
                            $selected = selected($currentLink, $url, false);

                            $label = sprintf(__("Day %s", "auctionforge"), $key);
                            $options .= "<option " . $selected . " value=\"$link\">$label</option>\n";
                        }
                        echo "<select class='bp-select2 bp-select2__simple bp-select2-days bp-day-switcher' name=\"auction-day\">\n$options\n</select>";
                        ?>
                    </div>
                    <?php } ?>
                </div>
                <?php do_action('bp_auction_content_block'); ?>
            </div>
            <?= View::render('templates.parts.search-in-auction', array(
                'usePagination' => $usePagination,
                'displayStartPriceInCatalog' => $displayStartPriceInCatalog,
                'showEstimatedPriceInItemsList' => $showEstimatedPriceInItemsList,
                'categoryList' => ($catalogLayout === 'side_categories') ? array() : $categoryList,
                'isArchived' => $isArchived,
                'isShop' => $isShop
            )) ?>
        </div>
        <div class="bp-row bp-fix-width-lot<?= ($catalogLayout === 'side_categories') ? ' af-catalog-with-sidebar' : '' ?>">
            <?php if ($catalogLayout === 'side_categories' && !empty($categoryList)) { ?>
            <div class="af-catalog-sidebar" id="af-catalog-sidebar">
                <h4 class="af-sidebar-title af-sidebar-title-desktop"><?= __('Categories', 'auctionforge') ?></h4>
                <button type="button" class="af-sidebar-toggle-btn" id="af-sidebar-toggle">
                    <?= __('Categories', 'auctionforge') ?> <span id="af-toggle-arrow">&#9660;</span>
                </button>
                <div id="af-sidebar-body">
                    <?php if (!empty($filterCategoryBy)) { ?>
                        <a href="<?= esc_url(remove_query_arg('category_by')) ?>" class="af-sidebar-clear"><?= __('Clear', 'auctionforge') ?></a>
                    <?php } ?>
                    <?php $activeCats = !empty($filterCategoryBy) ? array_map('trim', explode(',', $filterCategoryBy)) : array(); ?>
                    <ul class="af-sidebar-categories">
                        <?php foreach ($categoryList as $catId => $catName) { ?>
                            <li>
                                <label class="af-cat-label<?= in_array((string)$catId, $activeCats) ? ' af-cat-active' : '' ?>">
                                    <input type="checkbox" class="af-cat-checkbox" value="<?= esc_attr($catId) ?>" <?= in_array((string)$catId, $activeCats) ? 'checked' : '' ?>>
                                    <?= esc_html($catName) ?>
                                </label>
                            </li>
                        <?php } ?>
                    </ul>
                </div>
            </div>
            <script>
            (function(){
                var checkboxes = document.querySelectorAll('.af-cat-checkbox');
                checkboxes.forEach(function(cb) {
                    cb.addEventListener('change', function() {
                        var selected = [];
                        document.querySelectorAll('.af-cat-checkbox:checked').forEach(function(el) {
                            selected.push(el.value);
                        });
                        var url = new URL(window.location.href);
                        if (selected.length > 0) {
                            url.searchParams.set('category_by', selected.join(','));
                        } else {
                            url.searchParams.delete('category_by');
                        }
                        url.searchParams.delete('paged');
                        window.location.href = url.toString();
                    });
                });
                var arrow = document.getElementById('af-toggle-arrow');
                var body = document.getElementById('af-sidebar-body');
                var toggle = document.getElementById('af-sidebar-toggle');
                var isMobile = window.innerWidth <= 768;
                if (isMobile && toggle && body && arrow) {
                    body.style.display = 'none';
                    toggle.addEventListener('click', function() {
                        if (body.style.display === 'none') {
                            body.style.display = '';
                            arrow.innerHTML = '&#9650;';
                        } else {
                            body.style.display = 'none';
                            arrow.innerHTML = '&#9660;';
                        }
                    });
                }
            })();
            </script>
            <?php } ?>
            <div class="af-catalog-main">
            <div id="catalog-section"
                 data-auction-part="<?= $part ?>"
                 data-hidden-price="<?= $hiddenPrice ?>"
                 data-lot-count="<?= $countLots ?>"
                 data-bg-color="<?=$auctionBg?>"
                 data-showEstimatedPrice="<?= $showEstimatedPriceInItemsList ?>"
                 data-displayStartPrice="<?= $displayStartPriceInCatalog ?>"
                 data-auction-index="<?= $auctionId ?>"
                 data-post-auction-sale-opened-until="<?= (!empty($postAuctionSaleOpenedUntil)) ?: 0; ?>"
                 data-auction-id="<?= $auctionId ?>"
                 data-term-id="<?= $auction->term_id ?>"
                 data-is-shop="<?= $isShop ? 1 : 0 ?>"
                 <?php if ($isBsShop) { ?>data-bs-shop="1"<?php } ?>

                 class="bp-lots bp-d-flex bp-f-wrap bp-f-center bp-md-f-around bp-possible-bids-<?= $possibleBids ?>">
                <?php if ( have_posts() ) : while ( have_posts() ) : the_post(); ?>
                    <?php
                    $post = get_post();
                    $lotHelper = new LotHelper($post->ID);

                    $featureImage = $lotHelper->getFeatureImage();

                    $lotName = $lotHelper->getOptionValue('lot_name', 0);
                    $lotIndex = $lotHelper->getOptionValue('lot_itemIndex', 0);
                    $lotIsLarge = $lotHelper->getOptionValue('largeDisplay', false);

                    $title = $lotHelper->getOptionValue('lot_name', '');
                    $content = get_the_content();
                    $title = LotHelper::getLotTitle($title, $content);
                    $estimatedPrice = $lotHelper->getOptionValue('lot_estimated_price', 0);
                    $fullPriceVat = $lotHelper->getOptionValue('lot_fullPriceVat', '0');

                    $isRemovedItem = $lotHelper->getOptionValue('removedFromAuction', 0);

                    $isEroticContent = (int)$lotHelper->getOptionValue('eroticContent', 0);
                    $isCriminalContent = (int)$lotHelper->getOptionValue('criminalContent', 0);

                    $itemData = new stdClass();
                    $itemData->title = $title;
                    $itemData->content = $content;
                    ?>
                    <div id="lot-<?= $lotHelper->getOptionValue('lot_itemIndex', 0) ?>" class="bp-lot <?= ($lotIsLarge) ? "bp-lot__large" : "" ?>" data-estimated-price="<?= $estimatedPrice ?>"
                         data-content="<?= urlencode(json_encode($itemData)) ?>"
                         data-lot-index="<?= $lotHelper->getOptionValue('lot_itemIndex', 0) ?>"
                         data-full-price-vat="<?= $fullPriceVat ?>"
                         data-lot-id="<?= $lotHelper->getOptionValue('lot_id', 0) ?>"
                    >
                        <?php if ($isRemovedItem == "1") { ?>
                            <div class="bp-alert bp-alert-small bp-alert-radius-0 bp-alert-absolute alert bp-alert-danger alert-primary" role="alert">
                                <p><?= __("Lot was removed from auction", "auctionforge") ?></p>
                            </div>
                        <?php } ?>
                        <?php if ($isEroticContent || $isCriminalContent) { ?>
                            <style>
                                .bp-lots #lot-<?= $lotIndex ?>.bp-lot .bp-lot__image {
                                    background-color: #444;
                                }
                                .bp-login.bp-approved-user .bp-lots #lot-<?= $lotIndex ?>.bp-lot .bp-lot__image {
                                    background-color: #444;
                                    background-image: url(<?= $featureImage ?>);
                                    background-size: 0 0;
                                }
                                .bp-login.bp-approved-user .bp-lots #lot-<?= $lotIndex ?>.bp-lot:hover .bp-lot__image,
                                .bp-login.bp-approved-user .bp-lots #lot-<?= $lotIndex ?>.bp-lot:active .bp-lot__image {
                                    background-color: #fff;
                                    background-size: contain;
                                }
                            </style>
                        <?php } ?>
                        <a href="<?= get_the_permalink() ?>" class="bp-lot__wrp-image" <?= $bgStyle ?>>
                            <span class="bp__wishlist<?= ($isRemovedItem == "1") ? "-removed" : ""  ?>"></span>
                            <?php if ($isEroticContent) { ?>
                                <div class="bp-lot__image bp-lot__eroticContent"
                                     data-text="<?= __("This lot's image may contain nudity or sexual content", "auctionforge") ?>"></div>
                            <?php } elseif ($isCriminalContent) { ?>
                                <div class="bp-lot__image bp-lot__criminalContent"
                                     data-text="<?= __("The image of this item is not displayed in accordance with Section 86a of the German Criminal Code (StGB)", "auctionforge") ?>"></div>
                            <?php } else { ?>
                                <div class="bp-lot__image" style="background-image:url(<?= $featureImage ?>);"></div>
                            <?php } ?>
                        </a>
                        <div id="lot-<?= $lotHelper->getOptionValue('lot_itemIndex', 0) ?>-content"
                             class="bp-lot__content lot-<?= ($isRemovedItem == "1") ? "removed" : "isset" ?>">
                            <div class="bp-lot__title">
                                <a href="<?= get_the_permalink() ?>"><span class="bp-title"><?=
                                        LotHelper::printTranslateLot($lotIndex) ?>:</span><?= $title ?></a>
                            </div>
                            <?php if ($showEstimatedPriceInItemsList == '1' && $isRemovedItem == "0") { ?>
                                <div class="bp-lot__message"></div>
                            <?php } ?>
                            <?php $redClass = (!$hiddenPrice || ($showEstimatedPriceInItemsList == '1' && $estimatedPrice != '')) ? "bp-bg-red" : "" ?>
                            <div class="bp-lot__tool" data-entry="0.2">
                                <?php if (!$hiddenPrice) { ?>
                                    <?php if ($isShop) { ?>
                                        <?php
                                        $buyoutPrice = $lotHelper->getOptionValue('lot_buyoutPrice', 0);
                                        // A sold BidSpirit Shop item must read as sold — "Purchase
                                        // Price" alone looks like it is still on offer. Scoped to the
                                        // BidSpirit Shop so the legacy "Auctions as shop" presentation
                                        // on live sites is unchanged.
                                        $bsShopSoldPrice = $isBsShop ? (float) $lotHelper->getOptionValue('lot_soldBid', 0) : 0;
                                        ?>
                                        <?php if ($bsShopSoldPrice > 0) { ?>
                                            <p class="bp-subtitle" data-entry="0.2.6"><?= __('Sold for', 'auctionforge') ?>:</p>
                                            <p class="bp-price bp-shop-sold"><?= LotHelper::formattedPrice($bsShopSoldPrice) ?></p>
                                        <?php } elseif ($buyoutPrice > 0) { ?>
                                            <p class="bp-subtitle" data-entry="0.2.5"><?= __('Purchase Price', 'auctionforge') ?>:</p>
                                            <p class="bp-price"><?= LotHelper::formattedPrice($buyoutPrice) ?></p>
                                        <?php } ?>
                                    <?php } elseif ($showEstimatedPriceInItemsList == '1' && $estimatedPrice != '') { ?>
                                        <p class="bp-subtitle" data-entry="0.2.1"><?= __('Estimated price', 'auctionforge') ?>:</p>
                                        <p class="bp-price"><?= $estimatedPrice ?></p>
                                    <?php } elseif ($showEstimatedPriceInItemsList == '0') { ?>
                                        <?php if ($displayStartPriceInCatalog == '1') { ?>
                                            <p class="bp-subtitle" data-entry="0.2.3"><?= __('Start price', 'auctionforge') ?>:</p>
                                            <p class="bp-price"><?= LotHelper::formattedPrice($lotHelper->getOptionValue('lot_start_price', 0)) ?></p>
                                        <?php } ?>
                                    <?php } ?>
                                <?php } else { ?>
                                    <?php if ($showEstimatedPriceInItemsList == '1' && $estimatedPrice != '') { ?>
                                        <p class="bp-subtitle" data-entry="0.2.2"><?= __('Estimated price', 'auctionforge') ?>:</p>
                                        <p class="bp-price"><?= $estimatedPrice ?></p>
                                    <?php } else { ?>
                                        <p class="bp-subtitle" data-entry="0.2.4"><?= __('Not available', 'auctionforge') ?></p>
                                    <?php } ?>
                                <?php } ?>
                            </div>
                        </div>
                    </div>
                <?php endwhile; ?>
                    <?php if ($usePagination == 'on') { ?>
                        <?= get_the_posts_pagination(apply_filters('lots_pagination_settings', Auction::$pagingSettings)); ?>
                    <?php } ?>
                <?php else: ?>
                    <div class="bp-d-flex bp-mb-30 bp-padding-text">
                        <p><?= __('Lots not found', 'auctionforge') ?>.</p>
                    </div>
                <?php endif;  ?>
                <div id="bsLoader" class="bs-loader"></div>
            </div>
            </div><!-- .af-catalog-main -->
        </div>
        <?php do_action('bp_after_inner_content_auction') ?>
    </div>
    <?php do_action('bp_after_content_auction') ?>
<?php
// Hot Lot badge: output hot lot post_ids for this auction
$hotLotEnabled = SettingsHelper::getOption('show_popular_badge', 'off');
if ($hotLotEnabled === 'on') {
    $hotLotThreshold = intval(SettingsHelper::getOption('hot_lot_threshold', 5));
    if ($hotLotThreshold < 1) $hotLotThreshold = 5;
    $hotPostIds = \auctionforge\inc\model\LotAnalytics::getHotLots($hotLotThreshold, $auction->term_id);
    if (!empty($hotPostIds)) {
        // Map post_ids to itemIndex
        $metaTable = \auctionforge\inc\model\LotMetaData::getTableName();
        global $wpdb;
        $ids = implode(",", array_map("intval", $hotPostIds));
        $hotItems = $wpdb->get_col("SELECT itemIndex FROM `{$metaTable}` WHERE postId IN ({$ids})");
        if (!empty($hotItems)) {
            ?>
            <script>
            (function($){
                var hotItems = <?= json_encode(array_map("intval", $hotItems)) ?>;
                function addHotBadges() {
                    $(".bp-lot").each(function() {
                        var idx = parseInt($(this).attr("data-lot-index"));
                        if (hotItems.indexOf(idx) !== -1 && !$(this).find(".af-hot-badge").length) {
                            $(this).find(".bp-lot__wrp-image").append('<span class="af-hot-badge">' + String.fromCodePoint(0x1F525) + ' Popular</span>');
                        }
                    });
                }
                $(document).ready(function() {
                    addHotBadges();
                    $(window).on("bp:get-auction-item", function() { setTimeout(addHotBadges, 500); });
                    var obs = new MutationObserver(function() { addHotBadges(); });
                    var target = document.getElementById("catalog-section");
                    if (target) obs.observe(target, { childList: true, subtree: true });
                });
            })(jQuery);
            </script>
            <style>
            .af-hot-badge { position:absolute; top:8px; right:8px; background:rgba(220,53,69,0.9); color:#fff; font-size:11px; font-weight:700; padding:3px 8px; border-radius:3px; z-index:5; pointer-events:none; }
            .bp-lot__wrp-image { position:relative; }
            </style>
            <?php
        }
    }
}
?>
<?php get_footer(); ?>
