<?php

/**
 * @package     VP Prime Framework
 *
 * @author      Abhishek Das <info@virtueplanet.com>
 * @link        https://www.virtueplanet.com
 * @copyright   Copyright (C) 2023-2025 Virtueplanet Services LLP. All Rights Reserved.
 * @license     GNU General Public License version 2 or later; see LICENSE.txt
 */

namespace Virtueplanet\Module\VirtueMartCategory\Site\Helper;

// phpcs:disable PSR1.Files.SideEffects
\defined('_JEXEC') or die;
// phpcs:enable PSR1.Files.SideEffects

use Joomla\CMS\Cache\CacheControllerFactoryInterface;
use Joomla\CMS\Cache\Controller\OutputController;
use Joomla\CMS\Factory;
use Joomla\CMS\Language\Multilanguage;
use Joomla\CMS\Router\Route;
use Virtueplanet\Plugin\System\Prime\Helper\VirtuemartHelper;

/**
 * Helper for mod_vpprime_mega_menu
 */
class MenuHelper
{
    /**
     * Active Virtuemart category ID
     *
     * @param   string
     */
    protected static $activeVirtuemartCategory;

    /**
     * Get a list of the menu items.
     *
     * @param   \Joomla\Registry\Registry  &$params  The module options.
     *
     * @return  array
     */
    public static function getList(&$params)
    {
        /** @var \Joomla\CMS\Application\SiteApplication $app */
        $app  = Factory::getApplication();
        $lang = $app->getLanguage();

        // Get active menu item
        $base   = self::getBase($params, true);
        $levels = $app->getIdentity()->getAuthorisedViewLevels();

        asort($levels);

        // Virtuemart Category Id
        $virtuemartCategoryId = $app->input->getInt('virtuemart_category_id', 0);

        if (is_array($virtuemartCategoryId)) {
            $virtuemartCategoryId = array_map('intval', array_values($virtuemartCategoryId));
        } else {
            $virtuemartCategoryId = [(int) $virtuemartCategoryId];
        }

        $virtuemartCategoryId = isset($virtuemartCategoryId[0]) ? $virtuemartCategoryId[0] : 0;
        $virtuemartCategoryId = $virtuemartCategoryId > 0 ? 'vmc-' . $virtuemartCategoryId : 0;

        // Reset active Virtuemart category Id
        self::$activeVirtuemartCategory = null;

        // Virtuemart Category end level
        $virtuemartCategoryEndLevel = 0;

        // Compose cache key
        $cacheKey = 'category_items:' . $params . implode(',', $levels) . '.' . $base->id . '.lang:' . $lang->getTag() . '.category:' . $virtuemartCategoryId;

        // Compose cache key for active Virtuemart category
        $cacheKeyForActiveCategory = 'category_active:' . $params . implode(',', $levels) . '.' . $base->id . '.lang:' . $lang->getTag() . '.category:' . $virtuemartCategoryId;

        /** @var OutputController $cache */
        $cache = Factory::getContainer()->get(CacheControllerFactoryInterface::class)
            ->createCacheController('output', ['defaultgroup' => 'mod_vpprime_virtuemart_category']);

        // Disable caching if disabled in module options
        if ($params->get('caching', 1) == 0) {
            $cache->setCaching(0);
        }

        // Check if we have a cache hit
        if ($cache->contains($cacheKey) && $cache->contains($cacheKeyForActiveCategory)) {
            // Get items from cache
            $items = $cache->get($cacheKey);

            // Get active Virtuemart category from cache
            self::$activeVirtuemartCategory = $cache->get($cacheKeyForActiveCategory);
        } else {
            $start    = 0;
            $parentId = (int) $params->get('category_parent', 1);
            $endLevel = (int) $params->get('category_end_level', 0);
            $items    = [];
            $lastitem = 0;

            $items = VirtuemartHelper::getCategoriesForMenu($parentId, $endLevel, 1, false, null);

            if (!empty($items)) {
                $start = $items[0]->level;

                foreach ($items as $i => $item) {
                    $item->parent     = false;
                    $item->menu_level = $item->level;
                    $itemParams       = $item->getParams();

                    if (isset($items[$lastitem]) && $items[$lastitem]->id == $item->parent_id && $itemParams->get('menu_show', 1) == 1) {
                        $items[$lastitem]->parent = true;
                    }

                    if ($virtuemartCategoryId === $item->id && $item->level > $virtuemartCategoryEndLevel) {
                        self::$activeVirtuemartCategory = clone $item;
                        $virtuemartCategoryEndLevel     = $item->level;
                    }

                    $item->deeper     = false;
                    $item->shallower  = false;
                    $item->level_diff = 0;

                    if (isset($items[$lastitem])) {
                        $items[$lastitem]->deeper     = ($item->level > $items[$lastitem]->level);
                        $items[$lastitem]->shallower  = ($item->level < $items[$lastitem]->level);
                        $items[$lastitem]->level_diff = ($items[$lastitem]->level - $item->level);
                    }

                    $lastitem      = $i;
                    $item->flink   = $item->link;
                    $item->current = $item->active;

                    if ((strpos($item->flink, 'index.php?') !== false) && strcasecmp(substr($item->flink, 0, 4), 'http')) {
                        $item->flink = Route::_($item->flink, true, $itemParams->get('secure'));
                    } else {
                        $item->flink = Route::_($item->flink);
                    }

                    // We prevent the double encoding because for some reason the $item is shared for menu modules and we get double encoding
                    // when the cause of that is found the argument should be removed
                    $item->title          = htmlspecialchars($item->title, ENT_COMPAT, 'UTF-8', false);
                    $item->menu_icon      = htmlspecialchars($itemParams->get('menu_icon_css', ''), ENT_COMPAT, 'UTF-8', false);
                    $item->anchor_css     = htmlspecialchars($itemParams->get('menu-anchor_css', ''), ENT_COMPAT, 'UTF-8', false);
                    $item->anchor_title   = htmlspecialchars($itemParams->get('menu-anchor_title', ''), ENT_COMPAT, 'UTF-8', false);
                    $item->anchor_rel     = htmlspecialchars($itemParams->get('menu-anchor_rel', ''), ENT_COMPAT, 'UTF-8', false);
                    $item->menu_image     = htmlspecialchars($itemParams->get('menu_image', ''), ENT_COMPAT, 'UTF-8', false);
                    $item->menu_image_css = htmlspecialchars($itemParams->get('menu_image_css', ''), ENT_COMPAT, 'UTF-8', false);

                    if ($start > 1) {
                        $item->menu_level = ($item->menu_level - $start) + 1;
                    }
                }

                if (isset($items[$lastitem])) {
                    $items[$lastitem]->deeper     = (($start ?: 1) > $items[$lastitem]->level);
                    $items[$lastitem]->shallower  = (($start ?: 1) < $items[$lastitem]->level);
                    $items[$lastitem]->level_diff = ($items[$lastitem]->level - ($start ?: 1));
                }
            }

            // Store items in cache
            $cache->store($items, $cacheKey);

            // Store active Virtuemart category in cache
            $cache->store(self::$activeVirtuemartCategory, $cacheKeyForActiveCategory);
        }

        return $items;
    }

    /**
     * Get base menu item.
     *
     * @param   \Joomla\Registry\Registry  &$params  The module options.
     * @param   boolean  Ignore active Virtuemart category if needed.
     *
     * @return  object
     */
    public static function getBase(&$params, $ignoreVirtuemartCategory = false)
    {
        // Get base menu item from parameters
        if ($params->get('base')) {
            /** @var \Joomla\CMS\Application\SiteApplication $app */
            $app  = Factory::getApplication();
            $base = $app->getMenu()->getItem($params->get('base'));
        } else {
            $base = false;
        }

        // Use active menu item if no base found
        if (!$base) {
            if (self::$activeVirtuemartCategory && !$ignoreVirtuemartCategory) {
                $base = self::$activeVirtuemartCategory;
            } else {
                $base = self::getActive($params);
            }
        }

        return $base;
    }

    /**
     * Get active menu item.
     *
     * @param   \Joomla\Registry\Registry  &$params  The module options.
     *
     * @return  object
     */
    public static function getActive(&$params)
    {
        /** @var \Joomla\CMS\Application\SiteApplication $app */
        $app  = Factory::getApplication();
        $menu = $app->getMenu();

        return $menu->getActive() ?: self::getDefault();
    }

    /**
     * Get default menu item (home page) for current language.
     *
     * @return  object
     */
    public static function getDefault()
    {
        /** @var \Joomla\CMS\Application\SiteApplication $app */
        $app  = Factory::getApplication();
        $menu = $app->getMenu();

        // Look for the home menu
        if (Multilanguage::isEnabled()) {
            return $menu->getDefault($app->getLanguage()->getTag());
        }

        return $menu->getDefault();
    }

    public static function getActiveVirtuemartCategoryId()
    {
        return self::$activeVirtuemartCategory ? self::$activeVirtuemartCategory->id : null;
    }
}
