<?php

if (! defined('ABSPATH')) {
    exit;
} require_once __DIR__ . '/trait-puffergo-hierarchical-taxonomy-nav.php';
class PufferGo_Archive_Data
{
    use PufferGo_Hierarchical_Taxonomy_Nav;

    public $page_title;

    public $page_description = '';

    public $is_category_page = false;

    public $active_category_id = 0;

    public $archive_url;

    public $hero_bg_image = '';

    public $hero_bg_image_mobile = '';

    public $hero_enabled = true;

    public $categories = array();

    public $category_tree = array();

    public $products = array();

    public $paged = 1;

    public $max_pages = 0;

    public $current_url = '';

    public static function from_current_query()
    {
        return new self();
    }

    public function __construct()
    {
        $this->load_page_context();
        $this->load_categories();
        $this->load_category_tree();
        $this->load_products();
        $this->load_pagination();
    }

    private function load_page_context()
    {
        $this->is_category_page = is_tax('puffergo_product_cat');
        $this->page_title = $this->is_category_page ? single_term_title('', false) : __('Products', 'puffergo');
        $this->page_description = $this->is_category_page ? term_description() : '';
        $this->active_category_id = $this->is_category_page ? get_queried_object_id() : 0;
        $this->archive_url = get_post_type_archive_link('puffergo_product');

        if ($this->is_category_page) {
            $term_link = get_term_link(get_queried_object());
            $this->current_url = is_wp_error($term_link) ? $this->archive_url : $term_link;
        } else {
            $this->current_url = $this->archive_url;
        } $config = function_exists('puffergo_get_template_config_values') ? puffergo_get_template_config_values('product-archive') : array();
        $hero = isset($config['hero-block']) && is_array($config['hero-block']) ? $config['hero-block'] : array();

        if (! empty($hero)) {
            $this->hero_enabled = 'off' !== ($hero['enabled'] ?? 'on');

            if (! empty($hero['title']) && ! $this->is_category_page) {
                $this->page_title = $hero['title'];
            }

if (! empty($hero['bg_image']['url'])) {
                $this->hero_bg_image = $hero['bg_image']['url'];
            }

if (! empty($hero['bg_image_mobile']['url'])) {
                $this->hero_bg_image_mobile = $hero['bg_image_mobile']['url'];
            }
        }
    }

    private function load_categories()
    {
        $terms = get_terms(array('taxonomy' => 'puffergo_product_cat', 'hide_empty' => true, ));

        if (is_wp_error($terms) || empty($terms)) {
            return;
        }

foreach ($terms as $term) {
            $this->categories[] = array('id' => $term->term_id, 'name' => $term->name, 'url' => get_term_link($term), );
        }
    }

    private function load_category_tree()
    {
        $cat_orderby = get_option('puffergo_product_cat_orderby', 'name');

        if ('manual' === $cat_orderby) {
            $query_args = array('taxonomy' => 'puffergo_product_cat', 'hide_empty' => false, 'orderby' => 'name', 'order' => 'ASC', );
        } elseif ('count' === $cat_orderby) {
            $query_args = array('taxonomy' => 'puffergo_product_cat', 'hide_empty' => false, 'orderby' => 'count', 'order' => 'DESC', );
        } else {
            $query_args = array('taxonomy' => 'puffergo_product_cat', 'hide_empty' => false, 'orderby' => 'name', 'order' => 'ASC', );
        } $terms = get_terms($query_args);

        if (is_wp_error($terms) || empty($terms)) {
            return;
        }

if ('manual' === $cat_orderby || 'count' === $cat_orderby) {
            usort($terms, function ($a, $b) use ($cat_orderby) {
                if ('manual' === $cat_orderby) {
                    $order_a = (int) get_term_meta($a->term_id, '_puffergo_cat_order', true);
                    $order_b = (int) get_term_meta($b->term_id, '_puffergo_cat_order', true);

                    if ($order_a !== $order_b) {
                        return $order_a <=> $order_b;
                    }
                } else {
                    if ((int) $a->count !== (int) $b->count) {
                        return (int) $b->count <=> (int) $a->count;
                    }
                }

return strcasecmp($a->name, $b->name);
            });
        } $ancestors = $this->active_category_id ? array_map('intval', get_ancestors($this->active_category_id, 'puffergo_product_cat', 'taxonomy')) : array();
        $term_posts = $this->collect_term_product_ids($terms);
        $by_parent = array();

        foreach ($terms as $term) {
            $by_parent[ (int) $term->parent ][] = $term;
        } $subtree_cache = array();
        $subtree_ids = function ($term_id) use (&$subtree_ids, $by_parent, $term_posts, &$subtree_cache) {
            $term_id = (int) $term_id;

            if (isset($subtree_cache[ $term_id ])) {
                return $subtree_cache[ $term_id ];
            } $ids = isset($term_posts[ $term_id ]) ? $term_posts[ $term_id ] : array();

            if (! empty($by_parent[ $term_id ])) {
                foreach ($by_parent[ $term_id ] as $child) {
                    $ids = array_merge($ids, $subtree_ids((int) $child->term_id));
                }
            } $ids = array_values(array_unique($ids));
            $subtree_cache[ $term_id ] = $ids;

            return $ids;
        };
        $this->category_tree = $this->build_category_nodes($by_parent, 0, $ancestors, $subtree_ids);
    }

    private function collect_term_product_ids(array $terms)
    {
        $published = get_posts(array('post_type' => 'puffergo_product', 'post_status' => 'publish', 'posts_per_page' => -1, 'fields' => 'ids', 'no_found_rows' => true, ));

        if (empty($published)) {
            return array();
        } $published = array_flip(array_map('intval', $published));
        $map = array();

        foreach ($terms as $term) {
            $object_ids = get_objects_in_term((int) $term->term_id, 'puffergo_product_cat');

            if (is_wp_error($object_ids) || empty($object_ids)) {
                continue;
            } $map[ (int) $term->term_id ] = array_values(array_filter(array_map('intval', $object_ids), function ($id) use ($published) { return isset($published[ $id ]); }));
        }

return $map;
    }

    private function build_category_nodes(array $by_parent, $parent_id, array $ancestors, $subtree_ids)
    {
        if (empty($by_parent[ (int) $parent_id ])) {
            return array();
        } $nodes = array();

        foreach ($by_parent[ (int) $parent_id ] as $term) {
            $id = (int) $term->term_id;
            $count = count($subtree_ids($id));

            if (0 === $count) {
                continue;
            } $link = get_term_link($term);
            $children = $this->build_category_nodes($by_parent, $id, $ancestors, $subtree_ids);
            $nodes[] = array('id' => $id, 'name' => $term->name, 'url' => is_wp_error($link) ? '' : $link, 'count' => $count, 'is_active' => $id === (int) $this->active_category_id, 'is_open' => $id === (int) $this->active_category_id || in_array($id, $ancestors, true), 'children' => $children, );
        }

return $nodes;
    }

    private function load_products()
    {
        $use_formatter = class_exists('PufferGo_Unit_Formatter');

        if (! have_posts()) {
            return;
        }

while (have_posts()) {
            the_post();
            $this->products[] = self::build_product_card(get_the_ID(), $use_formatter);
        }
    }

    private static function build_product_card($product_id, $use_formatter)
    {
        $card = PufferGo_Product_CPT::get_card_data($product_id, $use_formatter);
        $short_description = $card['short_description'];

        return array('id' => $product_id, 'title' => get_the_title($product_id), 'url' => get_permalink($product_id), 'image_id' => (int) $card['display_id'], 'is_video' => $card['is_video'], 'price' => $card['price_display'], 'description' => $short_description ?: wp_trim_words(get_the_excerpt($product_id), 15), );
    }

    private function load_pagination()
    {
        $this->paged = isset($_GET['paged']) ? absint(wp_unslash($_GET['paged'])) : max(1, (int) get_query_var('paged'));
        $this->max_pages = (int) $GLOBALS['wp_query']->max_num_pages;
    }

    public function get_breadcrumb_items()
    {
        $items = array();
        $items[] = array('url' => $this->archive_url, 'label' => __('Products', 'puffergo'), );

        if ($this->is_category_page) {
            $items = array_merge($items, $this->get_term_ancestor_breadcrumb_items('puffergo_product_cat', $this->active_category_id));
            $items[] = array('url' => null, 'label' => $this->page_title, );
        }

return $items;
    }
}
