<?php

namespace auctionforge\inc\shortcodes;

use auctionforge\inc\helpers\LotHelper;
use auctionforge\inc\helpers\SettingsHelper;
use auctionforge\inc\helpers\View;
use auctionforge\inc\model\Auction;
use auctionforge\inc\model\Lot;
use auctionforge\inc\model\LotMetaData;

class LotsByCategory
{
    public function init()
    {
        add_shortcode('bp_lots_by_category', array($this, 'render_shortcode'));
    }

    /**
     * Look up category ID(s) by name from auction _auction_tags term meta.
     * Returns an array of matching category IDs.
     *
     * @param string $categoryName
     * @return array
     */
    private function getCategoryIdsByName($categoryName)
    {
        global $wpdb;

        $table = $wpdb->termmeta;
        $sql = $wpdb->prepare(
            "SELECT meta_value FROM {$table} WHERE meta_key = %s",
            Auction::META_FIELD_TAGS
        );
        $results = $wpdb->get_col($sql);

        $categoryIds = array();
        $searchName = strtolower(trim($categoryName));

        if (!empty($results)) {
            foreach ($results as $jsonStr) {
                $data = json_decode($jsonStr, true);
                if (is_array($data)) {
                    foreach ($data as $id => $name) {
                        if (strtolower(trim($name)) === $searchName) {
                            $categoryIds[intval($id)] = true;
                        }
                    }
                }
            }
        }

        return array_keys($categoryIds);
    }

    /**
     * Render the shortcode output.
     *
     * @param array $atts
     * @return string
     */
    public function render_shortcode($atts)
    {
        $atts = shortcode_atts(array(
            'category'    => '',
            'title'       => '',
            'limit'       => 20,
            'loadmore'    => 1,
            'tmp'         => 'list',
            'mobile_cols' => 2,
        ), $atts);

        $categoryName = trim($atts['category']);
        if (empty($categoryName)) {
            return '<!-- bp_lots_by_category: no category specified -->';
        }

        $categoryIds = $this->getCategoryIdsByName($categoryName);
        if (empty($categoryIds)) {
            return '<!-- bp_lots_by_category: category "' . esc_html($categoryName) . '" not found -->';
        }

        $limit = intval($atts['limit']);
        $numberposts = ($limit == -1) ? -1 : $limit;

        // Query lots for each category ID and merge results (the same category
        // name may have different numeric IDs across different auctions)
        $allLots = array();
        $seenIds = array();

        foreach ($categoryIds as $catId) {
            $postsToFetch = ($numberposts == -1) ? -1 : ($numberposts - count($allLots));
            if ($numberposts > 0 && $postsToFetch <= 0) {
                break;
            }

            $args = array(
                'numberposts'      => $postsToFetch,
                'post_status'      => array('publish'),
                'post_type'        => 'lot',
                LotMetaData::BP_QUERY => array(
                    'bp_index' => array(1),
                    'bp_field' => array(
                        array(
                            'field'   => 'categoryId',
                            'value'   => intval($catId),
                            'compare' => '=',
                        ),
                    ),
                ),
                'bp_orderby'       => Lot::VALUE_NUM_BS,
                'order'            => 'ASC',
                'suppress_filters' => false,
            );

            $result = get_posts($args);
            if (!empty($result)) {
                foreach ($result as $lot) {
                    if (!isset($seenIds[$lot->ID])) {
                        $seenIds[$lot->ID] = true;
                        $allLots[] = $lot;
                    }
                }
            }

            // Stop early if we have reached the limit
            if ($numberposts > 0 && count($allLots) >= $numberposts) {
                $allLots = array_slice($allLots, 0, $numberposts);
                break;
            }
        }

        $lots = $allLots;

        if (empty($lots)) {
            return '<!-- bp_lots_by_category: no lots found for category "' . esc_html($categoryName) . '" -->';
        }

        $showEstimatedPriceInItemsList = false;
        $showEstimatedPrice = SettingsHelper::isChecked('force_show_estimated_price');
        if ($showEstimatedPrice) {
            $showEstimatedPriceInItemsList = $showEstimatedPrice;
        }

        $displayStartPriceInCatalog = true;
        $hiddenPrice = false;

        $title = $atts['title'];
        $total = count($lots);
        $loadMoreBtn = true;

        if (!intval($atts['loadmore']) || ($limit == -1 || $limit > $total)) {
            $loadMoreBtn = false;
        }

        if ($atts['tmp'] == 'slider') {
            $template = 'widgets.slider';
        } else {
            $template = 'shortcodes.lots';
        }

        return View::render('templates.' . $template, array(
            'title'                        => $title,
            'lots'                         => $lots,
            'limit'                        => $limit,
            'hiddenPrice'                  => $hiddenPrice,
            'showEstimatedPriceInItemsList' => $showEstimatedPriceInItemsList,
            'displayStartPriceInCatalog'   => $displayStartPriceInCatalog,
            'loadmore'                     => intval($atts['loadmore']),
            'mobile_cols'                  => intval($atts['mobile_cols']),
        ));
    }
}

$lotsByCategory = new LotsByCategory();
$lotsByCategory->init();
