<?php

/**
 * @package         Tassos Code Snippets
 * @version         1.0.1-RC2 Free
 *
 * @author          Tassos Marinos <info@tassos.gr>
 * @link            https://www.tassos.gr
 * @copyright       Copyright © 2026 Tassos Marinos All Rights Reserved
 * @license         GNU GPLv3 <http://www.gnu.org/licenses/gpl.html> or later
 */

namespace Tassos\CodeSnippets\Administrator\Field;

defined('_JEXEC') or die;

use Joomla\CMS\Form\Field\GroupedlistField;
use Joomla\CMS\Language\Text;

/**
 * Grouped list field that appends " (Pro Only)" to options marked with pro="true"
 * and forces those options to be disabled.
 */
class ProGroupedListField extends GroupedlistField
{
    /**
     * The form field type.
     *
     * @var    string
     */
    protected $type = 'ProGroupedList';

    /**
     * Method to get the field option groups.
     *
     * Calls the parent implementation to build the groups array, then iterates
     * the result to find options whose value matches a pro="true" XML option.
     * Those options get " (Pro Only)" appended to their label and are forced disabled.
     *
     * @return  array[]  The field option objects as a nested array in groups.
     */
    protected function getGroups()
    {
        $proValues = $this->getProValues();
        $groups    = parent::getGroups();

        if (empty($proValues))
        {
            return $groups;
        }

        foreach ($groups as &$group)
        {
            foreach ($group as &$option)
            {
                if (array_key_exists($option->value, $proValues))
                {
                    $option->text .= ' (' . Text::_('NR_UPGRADE_TO_PRO') . ')';
                }
            }
        }

        return $groups;
    }

    /**
     * Returns the field input HTML with data-pro-only="true" injected into
     * pro-only <option> elements. The grouped list layout does not pass
     * option.attr to HTMLHelper::_('select.groupedlist'), so we post-process
     * the rendered HTML instead.
     *
     * @return  string
     */
    protected function getInput()
    {
        \Tassos\Framework\HTML::renderProOnlyModal();

        $proValues = $this->getProValues();
        $html      = parent::getInput();

        if (empty($proValues))
        {
            return $html;
        }

        foreach ($proValues as $value => $label)
        {
            $escapedValue = htmlspecialchars($value, ENT_QUOTES, 'UTF-8');
            $escapedLabel = htmlspecialchars($label, ENT_QUOTES, 'UTF-8');
            $html         = preg_replace(
                '#(<option\b[^>]*\bvalue="' . preg_quote($escapedValue, '#') . '"[^>]*)(>)#',
                '$1 data-pro-only="' . $escapedLabel . '"$2',
                $html
            );
        }

        return $html;
    }

    /**
     * Collects pro="true" options as a value => translated label map.
     *
     * @return  array<string, string>
     */
    private function getProValues()
    {
        $proValues = [];

        foreach ($this->element->children() as $element)
        {
            if ($element->getName() === 'group')
            {
                foreach ($element->children() as $option)
                {
                    if ($option->getName() === 'option' && (string) $option['pro'] === 'true')
                    {
                        $label              = Text::_(trim((string) $option));
                        $value              = ($option['value']) ? (string) $option['value'] : $label;
                        $proValues[$value]  = $label;
                    }
                }

                continue;
            }

            if ($element->getName() === 'option' && (string) $element['pro'] === 'true')
            {
                $label             = Text::_(trim((string) $element));
                $value             = ($element['value']) ? (string) $element['value'] : $label;
                $proValues[$value] = $label;
            }
        }

        return $proValues;
    }
}
