<?php

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

namespace Virtueplanet\Plugin\System\Prime\Object;

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

use Joomla\CMS\Factory;
use Joomla\Registry\Registry;
use stdClass;

/**
 * VirtuemartCategory class of VP Prime Framework.
 */
class VirtuemartCategoryMenu extends stdClass
{
    /**
     * Dummy Primary key to mimic Joomla menu
     *
     * @var    string
     */
    public $id;

    /**
     * Primary key
     *
     * @var    integer
     */
    public $virtuemart_category_id;

    /**
     * The type of menu this item belongs to
     *
     * @var    integer
     */
    public $menutype;

    /**
     * The display title of the category item
     *
     * @var    string
     */
    public $title;

    /**
     * The display title of the category item
     *
     * @var    string
     */
    public $category_name;

    /**
     * The display title of the category item
     *
     * @var    string
     */
    public $category_description;

    /**
     * The SEF alias of the category item
     *
     * @var    string
     */
    public $alias;

    /**
     * The SEF alias of the category item
     *
     * @var    string
     */
    public $slug;

    /**
     * A note associated with the category item
     *
     * @var    string
     */
    public $note;

    /**
     * The computed path of the category item based on the alias field, this is populated from the `path` field in the `#__menu` table
     *
     * @var    string
     */
    public $route;

    /**
     * The actual link the category item refers to
     *
     * @var    string
     */
    public $link;

    /**
     * The type of link
     *
     * @var    string
     */
    public $type = 'vmcategory';

    /**
     * The relative level in the tree
     *
     * @var    integer
     */
    public $level;

    /**
     * The assigned language for this item
     *
     * @var    string
     */
    public $language = '*';

    /**
     * The click behaviour of the link
     *
     * @var    integer
     */
    public $browserNav;

    /**
     * The access level required to view the category item
     *
     * @var    integer
     */
    public $access;

    /**
     * The category item parameters
     *
     * @var    string|Registry
     * @note   This field is protected to require reading this field to proxy through the getter to convert the params to a Registry instance
     */
    protected $params;

    /**
     * Indicates if this category item is the home or default page
     *
     * @var    integer
     */
    public $home;

    /**
     * The image of the category item
     *
     * @var    string
     */
    public $img;

    /**
     * The optional template style applied to this category item
     *
     * @var    integer
     */
    public $template_style_id;

    /**
     * The extension ID of the component this category item is for
     *
     * @var    integer
     */
    public $component_id;

    /**
     * The parent category item in the menu tree
     *
     * @var    string
     */
    public $parent_id;

    /**
     * The called menu item Id
     *
     * @var    string
     */
    public $called_menu_id;

    /**
     * The parent category item in the menu tree
     *
     * @var    integer
     */
    public $category_parent_id;

    /**
     * Active category flag.
     *
     * @var    boolean
     */
    public $active;

    /**
     * The name of the component this category item is for
     *
     * @var    string
     */
    public $component = 'com_virtuemart';

    /**
     * The tree of parent category items
     *
     * @var    array
     */
    public $tree = [];

    /**
     * An array of the query string values for this item
     *
     * @var    array
     */
    public $query = [];

    /**
     * Parent category item/menu item
     *
     * @var   Virtueplanet\Plugin\System\Prime\Object\VirtuemartCategory|Joomla\CMS\Menu\MenuItem
     */
    protected $_parent;

    /**
     * An array of active category ids.
     *
     * @var    array
     */
    protected static $activeCategories = null;

    /**
     * Class constructor
     *
     * @param   array  $data  The category item data to load
     */
    public function __construct($data = [], $calledMenuItem = null)
    {
        foreach ((array) $data as $key => $value) {
            $this->{$key} = $value;
        }

        $this->id        = 'vmc-' . $this->virtuemart_category_id;
        $this->title     = htmlspecialchars($this->category_name, ENT_COMPAT, 'UTF-8', false);
        $this->link      = 'index.php?option=com_virtuemart&view=category&virtuemart_category_id=' . $this->virtuemart_category_id;
        $this->active    = in_array($this->virtuemart_category_id, $this->getActiveCategories());
        $this->level     = (int) $this->level;
        $this->parent_id = 'vmc-' . $this->category_parent_id;
        $this->alias     = $this->slug;

        if ($calledMenuItem) {
            $this->id             = $calledMenuItem->id . '-' . $this->id;
            $this->parent_id      = $calledMenuItem->id . '-' . $this->parent_id;
            $this->level         += $calledMenuItem->level;
            $this->menutype       = $calledMenuItem->menutype;
            $this->called_menu_id = $calledMenuItem->id;
        } else {
            $this->level += 1;
        }
    }

    /**
     * Returns the category item parameters
     *
     * @return  Registry
     */
    public function getParams()
    {
        if (!($this->params instanceof Registry)) {
            try {
                $this->params = new Registry($this->params);
            } catch (\RuntimeException $e) {
                /*
                 * Joomla shipped with a broken sample json string for 4 years which caused fatals with new
                 * error checks. So for now we catch the exception here - but one day we should remove it and require
                 * valid JSON.
                 */
                $this->params = new Registry();
            }
        }

        return $this->params;
    }

    /**
     * Sets the category item parameters
     *
     * @param   Registry|string  $params  The data to be stored as the parameters
     *
     * @return  void
     */
    public function setParams($params)
    {
        $this->params = $params;
    }

    /**
     * Get the list of active categories.
     *
     * @return  array
     */
    public function getActiveCategories()
    {
        if (self::$activeCategories === null) {
            $app    = Factory::getApplication();
            $model  = \VmModel::getModel('Category');

            $activeCategoryIds = $app->input->get('virtuemart_category_id', [0], 'ARRAY');
            $activeCategoryIds = array_filter(array_map('intval', $activeCategoryIds));

            self::$activeCategories = [];

            if (!empty($activeCategoryIds)) {
                foreach ($activeCategoryIds as $activeCategoryId) {
                    $activeCategories = $model->getCategoryRecurse($activeCategoryId, 0);

                    self::$activeCategories = array_merge(self::$activeCategories, $activeCategories);
                }
            }

            self::$activeCategories = array_merge(self::$activeCategories, $activeCategoryIds);
            self::$activeCategories = array_unique(self::$activeCategories);
        }

        return static::$activeCategories;
    }

    /**
     * Set parent item
     *
     * @return   void
     */
    public function setParent($parent)
    {
        if ($parent instanceof \Joomla\CMS\Menu\MenuItem || $parent instanceof \Virtueplanet\Plugin\System\Prime\Object\VirtuemartCategoryMenu) {
            $this->_parent = $parent;
        }
    }

    /**
     * Get parent item
     *
     * @return Virtueplanet\Plugin\System\Prime\Object\VirtuemartCategory|Joomla\CMS\Menu\MenuItem object
     */
    public function getParent()
    {
        return $this->_parent;
    }

    public function buildTree()
    {
        $this->tree = [$this->id];

        if ($this->_parent) {
            $this->tree = array_merge($this->tree, $this->_parent->tree);
        }
    }
}
