<?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\Helper;

use Joomla\CMS\Component\ComponentHelper;
use Joomla\CMS\Factory;
use Joomla\Database\DatabaseInterface;
use Virtueplanet\Plugin\System\Prime\Object\VirtuemartCategoryMenu;
use VmConfig;

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

/**
 * Virtuemart Helper class of VP Prime Framework.
 */
abstract class VirtuemartHelper
{
    /**
     * VirtueMart installation status.
     *
     * @var bool
     */
    protected static $isInstalled = null;

    /**
     * VirtueMart currencies.
     *
     * @var array
     */
    protected static $currencies = null;

    /**
     * VirtueMart menu items.
     *
     * @var array
     */
    protected static $menuItems = null;

    /**
     * Check if VirtueMart is installed.
     *
     * @return bool
     */
    public static function isInstalled()
    {
        if (self::$isInstalled === null) {
            if (ComponentHelper::isEnabled('com_virtuemart')) {
                \JLoader::register('VmConfig', JPATH_ADMINISTRATOR . '/components/com_virtuemart/helpers/config.php');

                if (!class_exists('VmConfig')) {
                    self::$isInstalled = false;
                } else {
                    \VmConfig::loadConfig();

                    self::$isInstalled = true;
                }
            } else {
                self::$isInstalled = false;
            }
        }

        return self::$isInstalled;
    }

    /**
     * Get VirtueMart category tree.
     *
     * @param  int     $parentId        The parent category ID
     * @param  int     $endLevel        The end level
     * @param  int     $vendorId        The vendor ID
     * @param  bool    $addImage        Add image
     * @param  object  $calledMenuItem  The called menu item
     *
     * @return array  The categories
     */
    public static function getCategoriesForMenu($parentId = 0, $endLevel = null, $vendorId = 1, $addImage = false, $calledMenuItem = null)
    {
        if (!self::isInstalled()) {
            return [];
        }

        if ($endLevel === null || $endLevel === 0) {
            $endLevel = 20;
        }

        // Disable VirtueMart caching.
        if (property_exists(\VirtueMartModelCategory::class, 'catsTree') && is_array(\VirtueMartModelCategory::$catsTree)) {
            \VirtueMartModelCategory::$catsTree = [];
        }

        $ordering   = \VmConfig::get('browse_cat_orderby_field', 'c.ordering,category_name');
        $direction  = \VmConfig::get('cat_brws_orderby_dir', 'ASC');
        $categories = \VirtueMartModelCategory::getCatsTree(false, $vendorId, $parentId, $endLevel, $addImage, true, $ordering, $direction);
        $items      = [];

        foreach ($categories as $category) {
            if ($category->level >= $endLevel) {
                continue;
            }

            $item     = new VirtuemartCategoryMenu($category, $calledMenuItem);
            $itemId   = $item->id;
            $parentId = $item->parent_id;

            if ($calledMenuItem && $item->level == $calledMenuItem->level) {
                $params = clone $calledMenuItem->getParams();

                $params->set('menu_show', 1);

                $item->setParams($params);

                $item->parent_id = $calledMenuItem->parent_id;

                $item->setParent($calledMenuItem->getParent());
            } elseif ($parentId && isset($items[$parentId])) {
                $item->setParent($items[$parentId]);
            }

            $item->buildTree();

            $items[$itemId] =  $item;
        }

        return array_values($items);
    }

    /**
     * Get category names by IDs.
     *
     * @param  int  $categoryId  The category ID
     *
     * @return array  The category names
     */
    public static function getCategoryNames($categoryIds)
    {
        $model = \VmModel::getModel('category');
        $names = [];

        foreach ($categoryIds as $categoryId) {
            $category = $model->getCategory($categoryId, false, true);

            if (!empty($category->category_name)) {
                $names[] = $category->category_name;
            }
        }

        return $names;
    }

    /**
     * Clean display data.
     *
     * @param  array  $displayData  The display data
     *
     * @return array  The cleaned display data
     */
    public static function getCleanDisplayContent($displayData)
    {
        foreach ($displayData as $key => $contents) {
            $contents = !is_array($contents) ? [$contents] : $contents;
            $contents = array_filter($contents);

            if (empty($contents)) {
                unset($displayData[$key]);
            } else {
                $displayData[$key] = $contents;
            }
        }

        return $displayData;
    }

    /**
     * Get VirtueMart currencies.
     *
     * @return array
     */
    public static function getCurrencies()
    {
        if (static::$currencies === null) {
            $db    = Factory::getContainer()->get(DatabaseInterface::class);
            $query = $db->getQuery(true);

            $query->select($db->quoteName(['virtuemart_currency_id', 'currency_name', 'currency_code_3']))
                ->from($db->quoteName('#__virtuemart_currencies'))
                ->where($db->quoteName('published') . ' = 1')
                ->order($db->quoteName('ordering') . ' ASC, ' . $db->quoteName('virtuemart_currency_id') . ' ASC');

            $db->setQuery($query);
            $currencies = $db->loadObjectList('virtuemart_currency_id');

            if (empty($currencies)) {
                static::$currencies = [];
            } else {
                static::$currencies = $currencies;
            }
        }

        return static::$currencies;
    }

    /**
     * Search products.
     *
     * @param  string  $searchTerm  The search term
     *
     * @return array  The search results
     */
    public static function searchProducts($searchTerm)
    {
        if (!self::isInstalled()) {
            return false;
        }

        $db    = Factory::getContainer()->get(DatabaseInterface::class);
        $query = $db->getQuery(true);

        $query->select('DISTINCT ' . $db->quoteName('a.product_name') . ' AS ' . $db->quoteName('text'))
            ->select($db->quoteName('a.virtuemart_product_id') . ' AS ' . $db->quoteName('value'))
            ->from($db->quoteName('#__virtuemart_products_' . \VmConfig::$vmlang) . ' AS a')
            ->join('LEFT', $db->quoteName('#__virtuemart_products') . ' AS p ON ' . $db->quoteName('p.virtuemart_product_id') . ' = ' . $db->quoteName('a.virtuemart_product_id'))
            ->where($db->quoteName('p.published') . ' = 1')
            ->where('(' . $db->quoteName('a.product_name') . ' LIKE ' . $db->quote('%' . $searchTerm . '%') . ' OR ' . $db->quoteName('p.product_sku') . ' LIKE ' . $db->quote('%' . $searchTerm . '%') . ')');

        $db->setQuery($query);

        return $db->loadObjectList();
    }

    /**
     * Finalize VirtueMart assets.
     */
    public static function finalizeAssets()
    {
        if (!self::isInstalled()) {
            return false;
        }

        if (!class_exists('\vmJsApi')) {
            return false;
        }

        if (method_exists(\vmJsApi::class, 'jPrice')) {
            \vmJsApi::jPrice();
        }

        /** @var \Joomla\CMS\Application\SiteApplication $app */
        $app      = Factory::getApplication();
        $document = $app->getDocument();
        $buffer   = $document->getBuffer('component');

        if ($buffer && trim($buffer) !== '' && method_exists(\vmJsApi::class, 'writeJS')) {
            $buffer .= "\n" . \vmJsApi::writeJS();

            $document->setBuffer($buffer, 'component');
        }
    }

    /**
     * Method to set VirtueMart Category Product Listing View Mode
     *
     * @return void
     */
    public static function setProductListMode()
    {
        if (!self::isInstalled()) {
            return false;
        }

        /** @var \Joomla\CMS\Application\SiteApplication $app */
        $app          = Factory::getApplication();
        $template     = $app->getTemplate(true);
        $params       = $template->params;
        $input        = $app->input;
        $option       = strtolower($input->getCmd('option', ''));
        $view         = strtolower($input->getCmd('view', ''));
        $categoryPage = $option === 'com_virtuemart' && $view === 'category';
        $filterPage   = $option === 'com_customfilters' && $view === 'products';

        if (!$categoryPage && !$filterPage) {
            return;
        }

        $menus          = $app->getMenu();
        $menu           = $menus->getActive();
        $sublayout      = isset($menu->query['productsublayout']) ? $menu->query['productsublayout'] : \VmConfig::get('productsublayout', 'products');
        $categoryId     = \vRequest::getInt('virtuemart_category_id', -1);
        $manufacturerId = \vRequest::getInt('virtuemart_manufacturer_id', -1);

        if ($categoryId === -1 && !empty($menu->query['virtuemart_category_id'])) {
            $categoryId = $menu->query['virtuemart_category_id'];
        } elseif ($categoryId === -1 && $manufacturerId === -1) {
            $categoryId = \shopFunctionsF::getLastVisitedCategoryId();
        }

        $categoryId  = ($categoryId === -1) ? 0 : $categoryId;
        $paramPrefix = (isset($menu->query['virtuemart_category_id']) && $menu->query['virtuemart_category_id'] != $categoryId) ? 'stf_' : '';
        $menuParams  = null;

        if (is_object($menu)) {
            $menuParams = $menu->getParams();
        }

        $sublayout      = !empty($menuParams) && $menuParams->get($paramPrefix . 'productsublayout', 0) ? $menuParams->get($paramPrefix . 'productsublayout', 0) : $sublayout;
        $modeMap        = ['products' => 'grid', 'products_horizon' => 'list', 'products_slim' => 'list'];
        $defaultMode    = array_key_exists($sublayout, $modeMap) ? $modeMap[$sublayout] : null;
        $categoryIds    = $app->input->get('virtuemart_category_id', [0], 'ARRAY');
        $categoryIds    = array_map('intval', $categoryIds);
        $categoryIdHash = ($option == 'com_customfilters' && $view == 'products') ? 'customfilters' : md5(serialize($categoryIds));
        $viewMode       = $app->getUserStateFromRequest('vpprime.vm.viewmode.category.' . $categoryIdHash, 'viewmode', $defaultMode, 'CMD');

        if ($defaultMode) {
            if ($sublayout == 'products_horizon') {
                unset($modeMap['products_slim']);
            } elseif ($sublayout == 'products_slim') {
                unset($modeMap['products_horizon']);
            }
        }

        $activeSublayout = in_array($viewMode, $modeMap) ? array_search($viewMode, $modeMap) : $sublayout;
        $viewModeInput   = strtolower($input->getCmd('viewmode', ''));

        if (array_key_exists($activeSublayout, $modeMap) && $sublayout != $activeSublayout) {
            $menu->query['productsublayout'] = $activeSublayout;

            if ($menuParams) {
                $menuParams->set('productsublayout', $activeSublayout);
                $menuParams->set('stf_productsublayout', $activeSublayout);
            }

            if (empty($viewModeInput)) {
                $app->setUserState('vpprime.vm.productsublayout.category.' . $categoryIdHash, $activeSublayout);
            }
        } else {
            $app->setUserState('vpprime.vm.productsublayout.category.' . $categoryIdHash, $sublayout);
        }

        if ($categoryId > 0 && $params->get('normalize_product_list', 1) && $menuParams) {
            $menuParams->set('featured', 0);
            $menuParams->set('stf_featured', 0);
            $menuParams->set('discontinued', 0);
            $menuParams->set('stf_discontinued', 0);
            $menuParams->set('latest', 0);
            $menuParams->set('stf_latest', 0);
            $menuParams->set('topten', 0);
            $menuParams->set('stf_topten', 0);
            $menuParams->set('recent', 0);
            $menuParams->set('stf_recent', 0);

            $menu->setParams($menuParams);
        }
    }

    /**
     * Prepare HTML image element for lazy loading.
     *
     * @param   string  $html
     * @param   bool    $lazyLoad
     * @param   int     $circleDiameter
     * @param   int     $circleMargin
     * @param   string  $backgroundColor
     * @param   string  $fillColor
     *
     * @return  string
     */
    public static function prepareLazyImageHTML($html, $lazyLoad = false, $circleDiameter = 10, $circleMargin = 10, $backgroundColor = '#f7f7f7', $fillColor = '#222')
    {
        $defaultWidth  = VmConfig::get('img_width', 0);
        $defaultHeight = VmConfig::get('img_height', 0);

        return TemplateHelper::prepareLazyImageHTML($html, $lazyLoad, $circleDiameter, $circleMargin, $defaultWidth, $defaultHeight, $backgroundColor, $fillColor);
    }

    /**
     * Get product URL.
     *
     * @param  object $product  The product object
     *
     * @return string
     */
    public static function getProductUrl($product): string
    {
        $url = 'index.php?option=com_virtuemart&view=productdetails&virtuemart_product_id=' . $product->virtuemart_product_id . '&virtuemart_category_id=' . $product->virtuemart_category_id;

        if (property_exists($product, 'canonical') && !empty($product->canonical)) {
            $url = $product->canonical;
        } elseif (property_exists($product, 'link') && !empty($product->link)) {
            $url = $product->link;
        }

        $queryString = parse_url($url, PHP_URL_QUERY);

        if (empty($queryString)) {
            return $url;
        }

        $queries = [];

        parse_str($queryString, $queries);

        if (empty($queries['option']) || empty($queries['view']) || $queries['option'] !== 'com_virtuemart' || $queries['view'] !== 'productdetails') {
            return $url;
        }

        if (!empty($queries['Itemid'])) {
            return $url;
        }

        $menuItems          = self::getMenuItems();
        $model              = \VmModel::getModel('Category');
        $productId          = !empty($queries['virtuemart_product_id']) ? $queries['virtuemart_product_id'] : 0;
        $categoryId         = !empty($queries['virtuemart_category_id']) ? $queries['virtuemart_category_id'] : 0;
        $categoryIds        = $categoryId > 0 ? $model->getCategoryRecurse($categoryId, 0) : [];
        $productPageMenuId  = 0;
        $categoryPageMenuId = 0;
        $lastPosKey         = null;
        $Itemid             = null;

        foreach ($menuItems as $item) {
            if (isset($item->query['view']) && isset($item->query['virtuemart_product_id']) && $item->query['view'] === 'productdetails' && $item->query['virtuemart_product_id'] == $productId) {
                $productPageMenuId = $item->id;
                break;
            }

            if (!empty($categoryIds) && isset($item->query['view']) && isset($item->query['virtuemart_category_id']) && $item->query['view'] === 'category') {
                $posKey = array_search($item->query['virtuemart_category_id'], $categoryIds);

                if ($posKey !== false && ($lastPosKey === null || $lastPosKey > $posKey)) {
                    $lastPosKey = $posKey;

                    $categoryPageMenuId = $item->id;
                }
            }
        }

        if ($productPageMenuId) {
            $Itemid = $productPageMenuId;
        } elseif ($categoryPageMenuId) {
            $Itemid = $categoryPageMenuId;
        }

        if (!$Itemid) {
            $app                    = Factory::getApplication();
            $option                 = $app->input->getCmd('option', '');
            $view                   = $app->input->getCmd('view', '');
            $virtuemart_category_id = $app->input->getInt('virtuemart_category_id', 0);
            $currentItemid          = $app->input->getInt('Itemid', 0);

            if ($option === 'com_virtuemart' && $view === 'category' && $virtuemart_category_id === $categoryId && $currentItemid) {
                $Itemid = $currentItemid;
            }
        }

        if ($Itemid) {
            $url .= '&Itemid=' . $Itemid;
        }

        return $url;
    }


    /**
     * Get all VirtueMart menu items
     *
     * @return array
     */
    public static function getMenuItems(): array
    {
        if (self::$menuItems === null) {
            /** @var \Joomla\CMS\Application\SiteApplication $app */
            $app       = Factory::getApplication();
            $menu      = $app->getMenu();
            $component = ComponentHelper::getComponent('com_virtuemart');
            $items     = $menu->getItems('component_id', $component->id);

            // If no items found, set to empty array.
            if (!$items) {
                $items = [];
            }

            self::$menuItems = $items;
        }

        return self::$menuItems;
    }
}
