<?php

/**
 * @package     VP Neoteric
 *
 * @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
 *
 * @phpcs:disable PSR1.Classes.ClassDeclaration.MissingNamespace
 */

use Joomla\CMS\Factory;
use Joomla\CMS\HTML\HTMLHelper;
use Joomla\CMS\Router\Route;
use Joomla\Database\DatabaseInterface;
use Virtueplanet\Plugin\System\Prime\Helper\TemplateHelper;
use Virtueplanet\Plugin\System\Prime\Service\HTML\Virtuemart;

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

/**
 * Custom field renderer class
 */
class VirtueMartCustomFieldRenderer
{
    public static function renderCustomfieldsFE(&$product, &$customfields, $virtuemart_category_id)
    {
        static $calculator      = false;
        static $currency        = false;
        static $cssStylesLoaded = false;

        if (!$calculator) {
            /** @var object $calculator */
            $calculator = calculationHelper::getInstance();
        }

        if (!$currency) {
            /** @var \CurrencyDisplay $currency */
            $currency = CurrencyDisplay::getInstance();
        }

        $serviceRegistry = HTMLHelper::getServiceRegistry();

        if (!$serviceRegistry->hasService('vpprime_virtuemart')) {
            $serviceRegistry->register('vpprime_virtuemart', Virtuemart::class);
        }

        /** @var \Joomla\CMS\Application\SiteApplication $app */
        $app               = Factory::getApplication();
        $document          = $app->getDocument();
        $tab               = $document->_getTab();
        $lineEnd           = $document->_getLineEnd();
        $wa                = $document->getWebAssetManager();
        $template          = $app->getTemplate(true);
        $params            = $template->params;
        $btnFields         = (array) $params->get('customfields_as_button', []);
        $db                = Factory::getContainer()->get(DatabaseInterface::class);
        $productModel      = VmModel::getModel('product');
        $noPriceText       = vmText::sprintf('COM_VIRTUEMART_CART_PRICE_FREE', $calculator->_currencyDisplay->getSymbol());
        $selectList        = [];
        $dynChilds         = 1;
        $customFieldStyles = [];
        $colorData         = $params->get('customfields_color_map');

        if (!empty($colorData)) {
            foreach ($colorData as $style) {
                if (empty($style->value) || empty($style->color)) {
                    continue;
                }

                $key        = bin2hex($style->value);
                $className1 = '.vm-customfield-color-' . $key . ':not(.form-check)';
                $className2 = '.vm-customfield-color-' . $key . ' .form-check-label-text.is-color-btn';
                $color      = TemplateHelper::getReadableColour($style->color, '#ffffff', '#111111');

                $customFieldStyle = $tab . $tab . $className1 . ', ' . $className2 . ' {background-color: ' . $style->color . ' !important; color: ' . $color . ' !important; border-color: ' . $style->color . ' !important;}' . $lineEnd;

                if ($color === '#ffffff') {
                    $customFieldStyle .= $tab . $tab . '.vm-customfield-color-' . $key . ':not(.form-check) .choices__price {color: #eee !important;}' . $lineEnd;
                }

                $customFieldStyles[$key] = $customFieldStyle;
            }
        }

        if (!empty($customFieldStyles) && !$cssStylesLoaded) {
            $wa->addInlineStyle(implode('', $customFieldStyles));

            $cssStylesLoaded = true;
        }

        foreach ($customfields as $key => $customfield) {
            if (!isset($customfield->display)) {
                $customfield->display = '';
            }

            $calculator->_product = $product;

            if ($customfield->field_type == "E") {
                vDispatcher::importVMPlugins('vmcustom');
                vDispatcher::trigger('plgVmOnDisplayProductFEVM3', [&$product, &$customfields[$key]]);

                continue;
            }

            $fieldname             = 'field[' . $product->virtuemart_product_id . '][' . $customfield->virtuemart_customfield_id . '][customfield_value]';
            $customProductDataName = 'customProductData[' . $product->virtuemart_product_id . '][' . $customfield->virtuemart_custom_id . ']';

            // This is a kind of fallback, setting default of custom if there is no value of the productcustom
            $customfield->customfield_value = (!isset($customfield->customfield_value) || $customfield->customfield_value === '') ? $customfield->custom_value : $customfield->customfield_value;

            $type = $customfield->field_type;

            $idTag = 'customProductData_' . (int) $product->virtuemart_product_id . '_' . $customfield->virtuemart_customfield_id;
            $idTag = VmHtml::ensureUniqueId($idTag);

            $emptyOption        = new stdClass();
            $emptyOption->text  = vmText::_('COM_VIRTUEMART_ADDTOCART_CHOOSE_VARIANT');
            $emptyOption->value = 0;

            $isButton = false;

            if (!empty($btnFields) && in_array($customfield->virtuemart_custom_id, $btnFields)) {
                $isButton = true;
            }

            switch ($type) {
                case 'C':
                    $html        = '';
                    $dropdowns   = [];
                    $stockhandle = VmConfig::get('stockhandle_products', false) && $product->product_stockhandle ? $product->product_stockhandle : VmConfig::get('stockhandle', 'none');

                    if (isset($customfield->options->{$product->virtuemart_product_id})) {
                        $productSelection = $customfield->options->{$product->virtuemart_product_id};
                    } else {
                        $productSelection = false;
                    }

                    $extra = ' AND (' . $db->quoteName('published') . ' = 1 ';

                    if ($stockhandle == 'disableit_children') {
                        $extra .= ' AND (' . $db->quoteName('product_in_stock') . ' - ' . $db->quoteName('product_ordered') . ' > 0) ';
                    }

                    $extra .= ')';

                    $avail = $productModel->getProductChildIds($customfield->virtuemart_product_id, $extra);

                    if (!in_array($customfield->virtuemart_product_id, $avail)) {
                        array_unshift($avail, $customfield->virtuemart_product_id);
                    }

                    foreach ($customfield->options as $product_id => $variants) {
                        if (!in_array($product_id, $avail)) {
                            vmdebug('$customfield->options Product to ignore, continue ', $product_id);
                            continue;
                        }

                        foreach ($variants as $k => $variant) {
                            if (!isset($dropdowns[$k]) || !is_array($dropdowns[$k])) {
                                $dropdowns[$k] = [];
                            }

                            if (!in_array($variant, $dropdowns[$k])) {
                                if ($k == 0 || !$productSelection) {
                                    $dropdowns[$k][] = $variant;
                                } else {
                                    if ($productSelection[$k - 1] == $variants[$k - 1]) {
                                        $break = false;

                                        for ($h = 1; $h <= $k; $h++) {
                                            if ($productSelection[$h - 1] != $variants[$h - 1]) {
                                                $break = true;
                                            }
                                        }

                                        if (!$break) {
                                            $dropdowns[$k][] = $variant;
                                        }
                                    }
                                }
                            }
                        }
                    }

                    if ($isButton) {
                        $customfield->selectType = 1;
                    }

                    $class      = 'vm-customfield-choice';
                    $selectType = 'select.genericlist';

                    if (!empty($customfield->selectType)) {
                        $selectType = 'vpprime_virtuemart.radiolist';
                        $class      = '';
                        $dom        = '';
                        $attribs    = ['class' => 'cvselection cvradio no-vm-bind'];
                    } else {
                        // vmJsApi::chosenDropDowns();
                        $dom     = 'select';
                        $attribs = ['class' => $class . ' cvselection cvdrop no-vm-bind'];
                    }

                    $attribs['data-reload'] = '1';
                    $view                   = vRequest::getCmd('view', 'productdetails');
                    $option                 = strtolower($app->input->getCmd('option', ''));
                    $viewJs                 = $view;

                    if (VmConfig::get('jdynupdate', true)) {
                        if ($option === 'com_virtuemart' && ($view == 'productdetails' || ($customfield->browseajax && $view == 'category'))) {
                            $attribs['data-dynamic-update'] = '1';
                            unset($attribs['data-reload']);
                        } else {
                            $viewJs = 'productdetails';
                        }
                    } else {
                        $viewJs = 'productdetails';
                    }

                    $Itemid = vRequest::getInt('Itemid', '');

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

                    // Create array for js
                    $jsArray = [];
                    $url     = '';

                    if ($view == 'productdetails' && $customfield->withImage) {
                        $withImage = true;
                        $mediaM    = VmModel::getModel('media');
                        $tablePM   = $mediaM->getTable('product_medias');
                        $html     .= '<div class="child-image-container row">';
                    } else {
                        $withImage = false;
                    }

                    foreach ($customfield->options as $prodId => $variants) {
                        if (!in_array($prodId, $avail)) {
                            continue;
                        }

                        $url       = Route::_('index.php?option=com_virtuemart&view=' . $viewJs . '&virtuemart_category_id=' . $virtuemart_category_id . '&virtuemart_product_id=' . $prodId, false);
                        $jsArray[] = '["' . $url . '","' . implode('","', $variants) . '"]';

                        if ($withImage) {
                            if ($prodId == $product->virtuemart_product_id) {
                                continue;
                            }

                            $images = $tablePM->load($prodId);

                            if (!isset($images[0]) && isset($product->virtuemart_media_id[0])) {
                                if (!is_array($images)) {
                                    $images = [];
                                }

                                $images[0] = $product->virtuemart_media_id[0];  // If the image is missing, the parent has it
                            }

                            if (isset($images[0])) {
                                $media = $mediaM->createMediaByIds($images[0]);
                                $html .= '<div class="col-6 col-ms-4 col-md-3 col-lg-3">';
                                $html .= '<a href="' . $url . '">' . $media[0]->displayMediaThumb(['class' => 'child-Images'], false, '', true, false, false, VmConfig::get('img_width', 90), VmConfig::get('img_height', 90)) . '</a>';
                                $html .= '</div>';
                            }
                        }
                    }

                    if ($view == 'productdetails' && $customfield->withImage) {
                        $html .= '</div>';
                    }

                    foreach ($customfield->selectoptions as $k => $soption) {
                        $html    .= '<div class="custom-field-C-container">';
                        $options  = [];
                        $selected = false;
                        $idTagK   = VmHtml::ensureUniqueId($idTag);

                        if (isset($dropdowns[$k])) {
                            foreach ($dropdowns[$k] as $i => $elem) {
                                $elem = trim((string)$elem);
                                $text = $elem;

                                if ($soption->clabel != '' && in_array($soption->voption, VirtueMartModelCustomfields::$dimensions)) {
                                    $rd = $soption->clabel;

                                    if (is_numeric($rd) && is_numeric($elem)) {
                                        $text = number_format(round((float) $elem, (int) $rd), $rd);
                                    }
                                } elseif ($soption->voption === 'clabels' && $soption->clabel != '') {
                                    $text = vmText::_($elem);
                                }

                                if (empty($elem)) {
                                    $text = vmText::_('COM_VIRTUEMART_LIST_EMPTY_OPTION');
                                }

                                $className  = '';
                                $classKey   = bin2hex($text);
                                $isColorBtn = false;

                                if (!empty($elem) && array_key_exists($classKey, $customFieldStyles)) {
                                    $className  = 'vm-customfield-color-' . $classKey;
                                    $isColorBtn = $isButton;
                                }

                                $customProperty = [
                                    'className'  => $className,
                                    'price'      => '',
                                    'isColorBtn' => $isColorBtn
                                ];

                                if ($isButton) {
                                    $customProperty['className'] .= ' btn-vm-customfield';
                                }

                                $o             = new stdClass();
                                $o->value      = $elem;
                                $o->text       = $text;
                                $o->attr       = 'data-custom-properties="' . htmlspecialchars(json_encode($customProperty), ENT_QUOTES, 'UTF-8') . '"';
                                $o->customProp = $customProperty;
                                $o->id         = VmHtml::ensureUniqueId($idTagK . '-' . $i);
                                $options[]     = $o;

                                if ($productSelection && $productSelection[$k] == $elem) {
                                    $selected = $elem;
                                }
                            }
                        }

                        if (empty($selected)) {
                            $product->orderable = false;
                        }

                        if ($customfield->showlabels) {
                            if (in_array($soption->voption, VirtueMartModelCustomfields::$dimensions)) {
                                $soption->slabel = vmText::_('COM_VIRTUEMART_' . strtoupper($soption->voption));
                            } elseif (!empty($soption->clabel) && !in_array($soption->voption, VirtueMartModelCustomfields::$dimensions)) {
                                $soption->slabel = vmText::_($soption->clabel);
                            }

                            if (isset($soption->slabel)) {
                                $html .= '<span class="vm-cmv-label">' . $soption->slabel . '</span>';
                            }
                        }

                        $attribs['data-cvsel'] = 'field' . $customfield->virtuemart_customfield_id;

                        $attr                = [];
                        $attr['id']          = $idTagK;
                        $attr['list.attr']   = $attribs;
                        $attr['option.key']  = 'value';
                        $attr['option.text'] = 'text';
                        $attr['option.attr'] = 'attr';
                        $attr['list.select'] = $selected;
                        $fname               = $fieldname . '[' . $k . ']';

                        $html .= HTMLHelper::_($selectType, $options, $fname, $attr);
                        $html .= '</div>';
                    }

                    vmJsApi::addJScript('cvfind');
                    vmJsApi::addJScript('dynupdate');

                    $jsVariants      = implode(',', $jsArray);
                    $selector        = $dom . "[data-cvsel=\"" . $attribs['data-cvsel'] . "\"]";
                    $hash            = md5($selector);
                    $browserNewState = $view != 'productdetails' ? 'Virtuemart.setBrowserState = false;' : '';

                    $js  = "(function($){";
                    $js .= "$(function(){";
                    $js .= $browserNewState;
                    $js .= "$(document).on('init.cvfind', function(){";
                    $js .= "$('" . $selector . "').off('change',Virtuemart.cvFind).on('change',{variants:[" . $jsVariants . "]},Virtuemart.cvFind);";
                    $js .= "});";
                    $js .= "$(document).trigger('init.cvfind');";
                    $js .= "$('body').on('updateVirtueMartProductDetail', function(){";
                    $js .= "$(document).trigger('init.cvfind');";
                    $js .= "});";
                    $js .= "$(document).on('vm.category.page.loaded', function(){";
                    $js .= "$(document).trigger('init.cvfind');";
                    $js .= "});";
                    $js .= "});";
                    $js .= "})(jQuery);";

                    vmJsApi::addJScript('cvselvars' . $hash, $js, true, false, false, $hash);

                    $customfield->display = $html;

                    break;

                case 'A':
                    $html = '';

                    $productModel->setId($customfield->virtuemart_product_id);

                    $uncatChildren = $productModel->getUncategorizedChildren($customfield->withParent);
                    $options       = [];
                    $selected      = vRequest::getInt('virtuemart_product_id', 0);
                    $option        = strtolower($app->input->getCmd('option', ''));
                    $view          = vRequest::getCmd('view', 'productdetails');
                    $Itemid        = vRequest::getInt('Itemid', 0);
                    $selectedFound = false;
                    //$view          = 'productdetails';
                    $attribs = ['data-reload' => '1'];

                    if (VmConfig::get('jdynupdate', true)) {
                        $attribs['url'] = 'value';

                        if ($option === 'com_virtuemart' && ($view == 'productdetails' || ($customfield->browseajax && $view == 'category'))) {
                            $attribs['data-dynamic-update'] = '1';
                            unset($attribs['data-reload']);
                        } else {
                            $view = 'productdetails';
                        }
                    } else {
                        $view = 'productdetails';
                    }

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

                    if (!$customfield->withParent) {
                        $options[0]        = $emptyOption;
                        $options[0]->value = Route::_('index.php?option=com_virtuemart&view=' . $view . '&virtuemart_category_id=' . $virtuemart_category_id . '&virtuemart_product_id=' . $customfield->virtuemart_product_id, false);
                    }

                    $parentStock = 0;

                    if ($uncatChildren) {
                        foreach ($uncatChildren as $k => $child) {
                            $productChild = $productModel->getProduct((int) $child, true);

                            if (!$productChild) {
                                continue;
                            }

                            if (!isset($productChild->{$customfield->customfield_value})) {
                                vmdebug('The child has no value at index ' . $child);
                                continue;
                            }

                            $available = $productChild->product_in_stock - $productChild->product_ordered;

                            if (VmConfig::get('stockhandle', 'none') == 'disableit_children' && $available <= 0) {
                                continue;
                            }

                            $parentStock += $available;
                            $priceStr     = '';

                            if ($customfield->wPrice) {
                                $productPrices = $calculator->getProductPrices($productChild);
                                $priceStr      = $currency->priceDisplay($productPrices['salesPrice']);
                            }

                            $customProperty = [
                                'className' => 'vm-customfield-' . bin2hex($productChild->{$customfield->customfield_value}),
                                'price'     => $priceStr
                            ];

                            $options[] = [
                                'value' => Route::_('index.php?option=com_virtuemart&view=' . $view . '&virtuemart_category_id=' . $virtuemart_category_id . '&virtuemart_product_id=' . $productChild->virtuemart_product_id, false),
                                'text'  => $productChild->{$customfield->customfield_value},
                                'attr'  => 'data-custom-properties="' . htmlspecialchars(json_encode($customProperty), ENT_QUOTES, 'UTF-8') . '"'
                            ];

                            if ($selected == $child) {
                                $selectedFound = true;
                                vmdebug($customfield->virtuemart_product_id . ' $selectedFound by vRequest ' . $selected);
                            }
                        }
                    }

                    if (!$selectedFound) {
                        $pos = array_search($customfield->virtuemart_product_id, $product->allIds);

                        if (isset($product->allIds[$pos - 1])) {
                            $selected = $product->allIds[$pos - 1];
                        } elseif (isset($product->allIds[$pos])) {
                            $selected = $product->allIds[$pos];
                        } else {
                            $selected = $customfield->virtuemart_product_id;
                        }
                    }

                    $url = 'index.php?option=com_virtuemart&view=' . $view . '&virtuemart_category_id=' . $virtuemart_category_id . '&virtuemart_product_id=' . $selected;

                    $attribs['option.key.toHtml'] = false;
                    $attribs['id']                = '[';

                    $och = '';

                    if (!empty($attribs['data-reload'])) {
                        $och = ' onchange="window.top.location.href=this.options[this.selectedIndex].value" data-reload="1"';
                        unset($attribs['data-reload']);
                    } else {
                        $och = ' data-dynamic-update="1" url="value"';
                        unset($attribs['data-dynamic-update']);
                    }

                    $attribs['list.attr']      = 'class="vm-customfield-choice no-vm-bind avselection"' . $och;
                    $attribs['list.translate'] = false;
                    $attribs['option.key']     = 'value';
                    $attribs['option.text']    = 'text';
                    $attribs['option.attr']    = 'attr';
                    $attribs['list.select']    = Route::_($url, false);

                    $html .= HTMLHelper::_('select.genericlist', $options, $fieldname, $attribs);

                    //vmJsApi::chosenDropDowns();

                    if ($customfield->parentOrderable == 0) {
                        if ($product->virtuemart_product_id == $customfield->virtuemart_product_id) {
                            $product->orderable        = false;
                            $product->product_in_stock = $parentStock;
                        }
                    }

                    $dynChilds++;
                    $customfield->display = $html;

                    vmJsApi::addJScript('cvfind');
                    vmJsApi::addJScript('dynupdate');

                    $browserNewState = $view != 'productdetails' ? 'Virtuemart.setBrowserState = false;' : '';

                    if ($customfield->browseajax) {
                        $js  = "(function($){";
                        $js .= "$(function(){";
                        $js .= $browserNewState;
                        $js .= "$(document).on('init.avselect', function(){";
                        $js .= "$('select.avselection').off('change',Virtuemart.avFind).on('change',{},Virtuemart.avFind);";
                        $js .= "});";
                        $js .= "$(document).trigger('init.avselect');";
                        $js .= "$('body').on('updateVirtueMartProductDetail', function(){";
                        $js .= "$(document).trigger('init.avselect');";
                        $js .= "});";
                        $js .= "$(document).on('vm.category.page.loaded', function(){";
                        $js .= "$(document).trigger('init.avselect');";
                        $js .= "});";
                        $js .= "});";
                        $js .= "})(jQuery);";

                        vmJsApi::addJScript('avselvars', $js, true);
                    }

                    break;
                case 'D':
                    if (empty($customfield->custom_value)) {
                        $customfield->custom_value = 'LC2';
                    }
                    //Customer selects date
                    if ($customfield->is_input) {
                        $date = '';

                        if (!empty($customfield->customfield_value)) {
                            try {
                                $date = new DateTime();
                                $date->add(new DateInterval($customfield->customfield_value));
                                $date = $date->format('Y-m-d');
                            } catch (Exception $e) {
                                $date = $customfield->customfield_value;
                            }
                        }

                        $yearRange = '';

                        if (!empty($customfield->yearRangeStart)) {
                            $d = new DateTime();

                            $d->add(new DateInterval('P' . $customfield->yearRangeStart . 'Y'));

                            $d         = $d->format('Y');
                            $yearRange = $d;
                        } else {
                            $yearRange = date('Y');
                        }

                        if (!empty($customfield->yearRangePeriod)) {
                            $d = new DateTime();

                            $d->add(new DateInterval('P' . $customfield->yearRangePeriod . 'Y'));

                            $d          = $d->format('Y');
                            $yearRange .= ':' . $d;
                        } else {
                            $yearRange .= ':1';
                        }

                        $customfield->display =  '<span class="product-custom-date">' . vmJsApi::jDate($date, $customProductDataName . '[' . $customfield->virtuemart_customfield_id . ']', null, true, $yearRange) . '</span>';
                    } else {
                        // Customer just sees a date
                        $customfield->display =  '<span class="product-custom-date">' . vmJsApi::date($customfield->customfield_value, $customfield->custom_value, true) . '</span>';
                    }

                    break;
                    /* text area or editor No vmText, only displayed in BE */

                case 'X':
                    $customfield->display = $customfield->customfield_params;

                    break;
                case 'B':
                case 'Y':
                    $customfield->display =  $customfield->customfield_value;

                    break;

                    /* string or integer */
                case 'S':
                case 'M':
                case 'PB':
                    if (VmConfig::get('hideEmptyCustomfields', false) && empty($customfield->customfield_value)) {
                        break;
                    }

                    $attribs = [];

                    if ($isButton && $type === 'S') {
                        $customfield->selectType = 1;
                    }

                    if (isset($customfield->selectType)) {
                        if (empty($customfield->selectType)) {
                            $selectType = 'select.genericlist';

                            if (!empty($customfield->is_input)) {
                                // vmJsApi::chosenDropDowns();

                                $attribs['class'] = 'vm-customfield-choice';
                                $idTag            = '[';
                            }
                        } else {
                            $selectType = 'vpprime_virtuemart.radiolist';
                        }
                    } else {
                        if ($type == 'M') {
                            $selectType = 'vpprime_virtuemart.radiolist';
                        } else {
                            $selectType = 'select.genericlist';
                            if (!empty($customfield->is_input)) {
                                // vmJsApi::chosenDropDowns();

                                $attribs['class'] = 'vm-customfield-choice';
                                $idTag            = '[';
                            }
                        }
                    }

                    if ($customfield->is_list && $customfield->is_list != 2) {
                        if (!empty($customfield->is_input)) {
                            $options = [];

                            if ($customfield->addEmpty) {
                                $options[0] = $emptyOption;
                            }

                            $values = explode(';', $customfield->custom_value);

                            foreach ($values as $val) {
                                if ($type == 'M') {
                                    $tmp = ['value' => $val, 'text' => VirtueMartModelCustomfields::displayCustomMedia($val, 'product', $customfield->width, $customfield->height)];
                                } else {
                                    $tmp = ['value' => $val, 'text' => vmText::_($val)];
                                }

                                if ($type === 'S') {
                                    $className  = '';
                                    $classKey   = bin2hex($tmp['text']);
                                    $isColorBtn = false;

                                    if (array_key_exists($classKey, $customFieldStyles)) {
                                        $className  = 'vm-customfield-color-' . $classKey;
                                        $isColorBtn = $isButton;
                                    }

                                    $customProperty = [
                                        'className'  => $className,
                                        'price'      => '',
                                        'isColorBtn' => $isColorBtn
                                    ];

                                    if ($isButton) {
                                        $customProperty['className'] .= ' btn-vm-customfield';
                                    }

                                    $tmp['attr']       = 'data-custom-properties="' . htmlspecialchars(json_encode($customProperty), ENT_QUOTES, 'UTF-8') . '"';
                                    $tmp['customProp'] = $customProperty;
                                }

                                $options[] = (object) $tmp;
                            }

                            $attr                = [];
                            $attr['id']          = $idTag;
                            $attr['list.attr']   = $attribs;
                            $attr['option.key']  = 'value';
                            $attr['option.text'] = 'text';
                            $attr['option.attr'] = 'attr';
                            $attr['list.select'] = $customfield->customfield_value;

                            $customfield->display = HTMLHelper::_($selectType, $options, $customProductDataName . '[' . $customfield->virtuemart_customfield_id . ']', $attr);
                        } else {
                            if ($type == 'M') {
                                $customfield->display =  VirtueMartModelCustomfields::displayCustomMedia($customfield->customfield_value, 'product', $customfield->width, $customfield->height);
                            } else {
                                $customfield->display =  vmText::_($customfield->customfield_value);
                            }
                        }
                    } else {
                        if (!empty($customfield->is_input)) {
                            if (!isset($selectList[$customfield->virtuemart_custom_id])) {
                                $selectList[$customfield->virtuemart_custom_id] = $key;

                                if ($customfield->addEmpty) {
                                    if (empty($customfields[$selectList[$customfield->virtuemart_custom_id]]->options)) {
                                        $customfields[$selectList[$customfield->virtuemart_custom_id]]->options[0]                            = $emptyOption;
                                        $customfields[$selectList[$customfield->virtuemart_custom_id]]->options[0]->virtuemart_customfield_id = $emptyOption->value;
                                    }
                                }

                                $tmpField                                                      = clone ($customfield);
                                $tmpField->options                                             = null;
                                $customfield->options[$customfield->virtuemart_customfield_id] = $tmpField;

                                $customfield->customProductDataName = $customProductDataName;
                            } else {
                                $customfields[$selectList[$customfield->virtuemart_custom_id]]->options[$customfield->virtuemart_customfield_id] = $customfield;
                                unset($customfields[$key]);
                            }

                            if (isset($customfields[$selectList[$customfield->virtuemart_custom_id]])) {
                                $default = reset($customfields[$selectList[$customfield->virtuemart_custom_id]]->options);
                            } else {
                                $customfields[$selectList[$customfield->virtuemart_custom_id]]          = new stdClass();
                                $customfields[$selectList[$customfield->virtuemart_custom_id]]->options = [];
                                $default                                                                = new stdClass();
                            }

                            if (!isset($default->customfield_value)) {
                                $default->customfield_value = '';
                            }

                            foreach ($customfields[$selectList[$customfield->virtuemart_custom_id]]->options as $k => $productCustom) {
                                if ($k == 0) {
                                    //$productCustom->text =
                                } else {
                                    if (!isset($productCustom->customfield_price)) {
                                        $productCustom->customfield_price = 0.0;
                                    }

                                    if (!isset($productCustom->customfield_value)) {
                                        $productCustom->customfield_value = '';
                                    }

                                    $price = VirtueMartModelCustomfields::renderCustomfieldPrice($productCustom, $product, $calculator);

                                    if ($price === $noPriceText) {
                                        $price = '';
                                    }

                                    if ($type == 'M') {
                                        $productCustom->text = VirtueMartModelCustomfields::displayCustomMedia($productCustom->customfield_value, 'product', $customfield->width, $customfield->height) . ' ' . $price;
                                    } elseif ($type == 'PB') {
                                        $productB            = VmModel::getModel('product')->getProduct($productCustom->bundle_product_id);
                                        $productCustom->text = $productB->product_name . ' ' . $price;
                                    } else {
                                        $trValue    = vmText::_($productCustom->customfield_value);
                                        $className  = '';
                                        $classKey   = bin2hex($trValue);
                                        $isColorBtn = false;

                                        if (array_key_exists($classKey, $customFieldStyles)) {
                                            $className  = 'vm-customfield-color-' . $classKey;
                                            $isColorBtn = $isButton;
                                        }

                                        $customProperty = [
                                            'className'  => $className,
                                            'price'      => '',
                                            'isColorBtn' => $isColorBtn
                                        ];

                                        if ($isButton) {
                                            $customProperty['className'] .= ' btn-vm-customfield';
                                        }

                                        if ($productCustom->customfield_value != $trValue and strpos($trValue, '%1') !== false) {
                                            $productCustom->text = vmText::sprintf($productCustom->customfield_value, $price);
                                        } else {
                                            $productCustom->text     = $trValue;
                                            $customProperty['price'] = $price;

                                            $productCustom->attr       = 'data-custom-properties="' . htmlspecialchars(json_encode($customProperty), ENT_QUOTES, 'UTF-8') . '"';
                                            $productCustom->customProp = $customProperty;
                                        }
                                    }
                                }

                                $customfields[$selectList[$customfield->virtuemart_custom_id]]->options[$k] = $productCustom;
                            }

                            $attr                = [];
                            $attr['id']          = $idTag;
                            $attr['list.attr']   = $attribs;
                            $attr['option.key']  = 'virtuemart_customfield_id';
                            $attr['option.text'] = 'text';
                            $attr['option.attr'] = 'attr';
                            $attr['list.select'] = $default->virtuemart_customfield_id;

                            $customfields[$selectList[$customfield->virtuemart_custom_id]]->display = HTMLHelper::_(
                                $selectType,
                                $customfields[$selectList[$customfield->virtuemart_custom_id]]->options,
                                $customfields[$selectList[$customfield->virtuemart_custom_id]]->customProductDataName,
                                $attr
                            );
                        } else {
                            if ($type == 'M') {
                                $customfield->display = VirtueMartModelCustomfields::displayCustomMedia($customfield->customfield_value, 'product', $customfield->width, $customfield->height);
                            } else {
                                $customfield->display = vmText::_($customfield->customfield_value);
                            }
                        }
                    }

                    break;

                case 'P':
                    $attr    = $customfield->customfield_value;
                    $lkey    = 'COM_VIRTUEMART_' . strtoupper($customfield->customfield_value) . '_FE';
                    $trValue = vmText::_($lkey);

                    $options[] = ['value' => 'product_length', 'text' => vmText::_('COM_VIRTUEMART_PRODUCT_LENGTH')];
                    $options[] = ['value' => 'product_width', 'text' => vmText::_('COM_VIRTUEMART_PRODUCT_WIDTH')];
                    $options[] = ['value' => 'product_height', 'text' => vmText::_('COM_VIRTUEMART_PRODUCT_HEIGHT')];
                    $options[] = ['value' => 'product_weight', 'text' => vmText::_('COM_VIRTUEMART_PRODUCT_WEIGHT')];

                    $dim = '';

                    if ($attr == 'product_length' || $attr == 'product_width' || $attr == 'product_height') {
                        $dim = $product->product_lwh_uom;
                    } elseif ($attr == 'product_weight') {
                        $dim = $product->product_weight_uom;
                    }

                    if (!isset($product->{$attr})) {
                        logInfo('customfield.php: case P, property ' . $attr . ' does not exists. virtuemart_custom_id: ' . $customfield->virtuemart_custom_id);
                        break;
                    }

                    $val = $product->{$attr};

                    if ($customfield->round != 0) {
                        if (empty($customfield->digits)) {
                            $customfield->digits = 0;
                        }

                        $val = $currency->getFormattedNumber($val, $customfield->digits);
                    }

                    if ($lkey != $trValue && strpos($trValue, '%1') !== false) {
                        $customfield->display = vmText::sprintf($customfield->customfield_value, $val, $dim);
                    } elseif ($lkey != $trValue) {
                        $customfield->display = $trValue . ' ' . $val;
                    } else {
                        $customfield->display = vmText::_('COM_VIRTUEMART_' . strtoupper($customfield->customfield_value)) . ' ' . $val . $dim;
                    }

                    break;
                case 'Z':
                    if (empty($customfield->customfield_value)) {
                        break;
                    }

                    $categoryModel   = VmModel::getModel('category');
                    $relatedCategory = $categoryModel->getCategory((int) $customfield->customfield_value, false, true);

                    if ($relatedCategory && $relatedCategory->published) {
                        $categoryModel->addImages($relatedCategory, 1);

                        $customfield->display = shopFunctionsF::renderVmSubLayout('relatedcategory', ['customfield' => $customfield, 'related' => $relatedCategory]);
                    }

                    break;
                case 'RC':
                    $pModel = VmModel::getModel('product');

                    if (!empty($customfield->customfield_value)) {
                        $prodIds = explode(',', $customfield->customfield_value);

                        foreach ($prodIds as $pId) {
                            $related = $pModel->getProduct((int) $pId, true, $customfield->wPrice, false, 1);

                            if (!$related) {
                                vmError('Custom related Product with id ' . $pId . ' not found');
                                continue;
                            } elseif ($related->published) {
                                $pModel->addImages($related, 1);
                                $customfield->display .= VirtueMartCustomFieldRenderer::renderRelatedProduct($customfield, $related);
                            }
                        }
                    }

                    break;
                case 'R':
                    $customfield->customfield_value = (int) $customfield->customfield_value;

                    if (empty($customfield->customfield_value)) {
                        vmError('Related Product customfield with id ' . $customfield->virtuemart_customfield_id . ' has no value');
                        $customfield->display = 'customfield related product has no value';
                        return;
                    }

                    $pModel  = VmModel::getModel('product');
                    $related = $pModel->getProduct((int) $customfield->customfield_value, true, $customfield->wPrice, false, 1);

                    if (!$related) {
                        vmError('Related Product with id ' . $customfield->customfield_value . ' not found');
                        break;
                    } elseif ($related->published) {
                        $pModel->addImages($related, 1);
                        $customfield->display = VirtueMartCustomFieldRenderer::renderRelatedProduct($customfield, $related);
                        vmdebug('Rendered related product ' . (int) $customfield->customfield_value);
                    }

                    break;
            }
        }
    }

    public static function renderRelatedProduct($customfield, $related)
    {
        $thumb = '';

        if ($customfield->wImage) {
            if (!empty($related->virtuemart_media_id[0])) {
                $thumb = VirtueMartModelCustomfields::displayCustomMedia($related->virtuemart_media_id[0], 'product', $customfield->width, $customfield->height) . ' ';
            } else {
                $thumb = VirtueMartModelCustomfields::displayCustomMedia(0, 'product', $customfield->width, $customfield->height) . ' ';
            }
        }

        if ($customfield->waddtocart) {
            // Save original jdynupdate configuration
            $jdynupdate = VmConfig::get('jdynupdate', true);

            // Disable jdynupdate
            VmConfig::set('jdynupdate', false);

            if (!empty($related->customfields)) {
                $customfieldsModel = VmModel::getModel('customfields');

                if (empty($customfield->from)) {
                    $customfield->from = $related->virtuemart_product_id;
                    $customfieldsModel->displayProductCustomfieldFE($related, $related->customfields);
                } elseif ($customfield->from != $related->virtuemart_product_id) {
                    $customfieldsModel->displayProductCustomfieldFE($related, $related->customfields);
                }
            }

            $isCustomVariant = false;

            if (!empty($related->customfields)) {
                foreach ($related->customfields as $k => $custom) {
                    if ($custom->field_type == 'C' && $custom->virtuemart_product_id != (int) $customfield->customfield_value) {
                        $isCustomVariant = $custom;
                    }

                    if (!empty($custom->layout_pos)) {
                        $related->customfieldsSorted[$custom->layout_pos][] = $custom;
                    } else {
                        $related->customfieldsSorted['normal'][] = $custom;
                    }

                    unset($related->customfields);
                }
            }

            // Restore back original jdynupdate configuration
            VmConfig::set('jdynupdate', $jdynupdate);
        }

        return shopFunctionsF::renderVmSubLayout('related', ['customfield' => $customfield, 'related' => $related, 'thumb' => $thumb]);
    }

    public static function renderCustomfieldsCart($product, $html, $trigger)
    {
        if (isset($product->param)) {
            vmTrace('param found, seek and destroy');
            return false;
        }

        $variantmods = property_exists($product, 'customProductData') ? $product->customProductData : (property_exists($product, 'product_attribute') ? $product->product_attribute : []);

        if (!is_array($variantmods)) {
            $variantmods = vmJsApi::safe_json_decode($variantmods, true);

            if (!is_array($variantmods)) {
                vmdebug('renderCustomfieldsCart decoding $variantmods returns not array ' . $variantmods);
                $variantmods = [];
            }
        }

        // We let that here as Fallback
        if (empty($product->customfields)) {
            $productDB = VmModel::getModel('product')->getProduct($product->virtuemart_product_id);

            if ($productDB && !empty($productDB->customfields)) {
                $product->customfields = $productDB->customfields;
            } else {
                $product->customfields = [];
            }
        }

        $productCustoms = [];

        foreach ((array) $product->customfields as $prodcustom) {
            // We just add the customfields to be shown in the cart to the variantmods
            if (is_object($prodcustom)) {
                // We need this here to ensure that broken customdata of order items is shown updated info, or at least displayed,
                if ($prodcustom->is_cart_attribute or $prodcustom->is_input) {
                    // The problem here is that a normal value and an array can be valid. The function should complement, or update the product. So we are not allowed
                    // to override existing values. When the $variantmods array is not set for the key, then we add an array, when the customproto is used more than one time
                    if (!isset($variantmods[$prodcustom->virtuemart_custom_id])) {
                        $variantmods[$prodcustom->virtuemart_custom_id][$prodcustom->virtuemart_customfield_id] = $prodcustom->virtuemart_customfield_id;
                    }

                    //the missing values are added with an own key.
                    if (is_array($variantmods[$prodcustom->virtuemart_custom_id]) && !isset($variantmods[$prodcustom->virtuemart_custom_id][$prodcustom->virtuemart_customfield_id])) {
                        $variantmods[$prodcustom->virtuemart_custom_id][$prodcustom->virtuemart_customfield_id] = $prodcustom->virtuemart_customfield_id;
                    }
                }

                $productCustoms[$prodcustom->virtuemart_customfield_id] = $prodcustom;
            }
        }

        foreach ((array)$variantmods as $i => $customfield_ids) {
            if (!is_array($customfield_ids)) {
                $customfield_ids = [$customfield_ids => false];
            }

            foreach ($customfield_ids as $customfield_id => $params) {
                if (empty($productCustoms) || !isset($productCustoms[$customfield_id])) {
                    //vmdebug('renderCustomfieldsCart continue',$customfield_id,$productCustoms);
                    continue;
                }

                $productCustom = $productCustoms[$customfield_id];

                // vmdebug('displayProductCustomfieldSelected ',$customfield_id,$productCustom);
                // The stored result in vm2.0.14 looks like this {"48":{"textinput":{"comment":"test"}}}
                // and now {"32":[{"invala":"100"}]}
                if (!empty($productCustom)) {
                    $otag = ' <span class="product-field-type-' . $productCustom->field_type . '">';
                    $tmp  = '';

                    if ($productCustom->field_type == "E") {
                        vDispatcher::importVMPlugins('vmcustom');
                        vDispatcher::trigger($trigger . 'VM3', [&$product, &$productCustom, &$tmp]);
                    } else {
                        $value = '';

                        if (($productCustom->field_type == 'G')) {
                            $db = Factory::getDBO();
                            $db->setQuery('SELECT `product_name` FROM `#__virtuemart_products_' . VmConfig::$vmlang . '` WHERE virtuemart_product_id=' . (int)$productCustom->customfield_value);
                            $child = $db->loadObject();
                            $value = $child->product_name;
                        } elseif (($productCustom->field_type == 'M')) {
                            $customFieldModel = VmModel::getModel('customfields');
                            $value            = $customFieldModel->displayCustomMedia($productCustom->customfield_value, 'product', $productCustom->width, $productCustom->height, VirtueMartModelCustomfields::$useAbsUrls);
                        } elseif (($productCustom->field_type == 'S')) {
                            if ($productCustom->is_list && $productCustom->is_input) {
                                if ($productCustom->is_list == 2) {
                                    $value = vmText::_($productCustom->customfield_value);
                                } else {
                                    $value = vmText::_($params);
                                }
                            } else {
                                $value = vmText::_($productCustom->customfield_value);
                            }
                        } elseif (($productCustom->field_type == 'PB')) {
                            ///vmdebug('$productCustom->customfield_value',$productCustom);
                            $productDB = VmModel::getModel('product')->getProduct($productCustom->bundle_product_id);
                            //my suggestion, we could even add the price here
                            $value = $productDB->product_name . ' (' . $productDB->product_sku . ') - ' . $productDB->virtuemart_product_id;
                        } elseif (($productCustom->field_type == 'A')) {
                            if (!property_exists($product, $productCustom->customfield_value)) {
                                $productDB = VmModel::getModel('product')->getProduct($product->virtuemart_product_id);

                                if ($productDB) {
                                    $attr             = $productCustom->customfield_value;
                                    $product->{$attr} = $productDB->{$attr};
                                }
                            }

                            $value = vmText::_($product->{$productCustom->customfield_value});
                        } elseif (($productCustom->field_type == 'C')) {
                            foreach ($productCustom->options->{$product->virtuemart_product_id} as $k => $option) {
                                $value .= '<span> ';
                                if (!empty($productCustom->selectoptions[$k]->clabel) && in_array($productCustom->selectoptions[$k]->voption, VirtueMartModelCustomfields::$dimensions)) {
                                    $value .= vmText::_('COM_VIRTUEMART_' . $productCustom->selectoptions[$k]->voption);
                                    $rd     = $productCustom->selectoptions[$k]->clabel;

                                    if (is_numeric($rd) and is_numeric($option)) {
                                        $value .= ' ' . number_format(round((float) $option, (int) $rd), $rd);
                                    }
                                } else {
                                    if (!empty($productCustom->selectoptions[$k]->clabel)) {
                                        $value .= vmText::_($productCustom->selectoptions[$k]->clabel);
                                    }

                                    $value .= ' ' . vmText::_($option) . ' ';
                                }
                                $value .= '</span><br />';
                            }

                            $value = trim($value);

                            if (!empty($value)) {
                                $html .= $otag . $value . '</span><br />';
                            }

                            continue;
                        } elseif (($productCustom->field_type == 'D')) {
                            //vmdebug('my date product customfield',$productCustom);
                            if ($productCustom->is_input) {
                                $value = $params;
                            } else {
                                $value = $productCustom->customfield_value;
                            }
                        } else {
                            $value = vmText::_($productCustom->customfield_value);
                        }

                        $trTitle = vmText::_($productCustom->custom_title);
                        $tmp     = '';

                        if ($productCustom->custom_title != $trTitle && strpos($trTitle, '%1') !== false) {
                            $tmp .= vmText::sprintf($productCustom->custom_title, $value);
                        } else {
                            $tmp .= $trTitle . ' ' . $value;
                        }
                    }

                    if (!empty($tmp)) {
                        $html .= $otag . $tmp . '</span><br />';
                    }
                } else {
                    foreach ((array)$customfield_id as $key => $value) {
                        $html .= '<br />Couldnt find customfield' . ($key ? '<span>' . $key . ' </span>' : '') . $value;
                    }

                    vmdebug('customFieldDisplay, $productCustom is EMPTY ' . $customfield_id);
                }
            }
        }

        return $html . '</div>';
    }
}
