<?php
  /**
   * @package     Formea.Plugin
   * @subpackage  element
   *
   * @copyright   Copyright (C) 2010-2023 Feseur Sdn Bhd. All rights reserved.
   * @license     GNU General Public License version 2 or later; see LICENSE.txt
   */
// no direct access
  defined('_JEXEC') or die();

  use Joomla\CMS\Dispatcher\DispatcherInterface;
  use Joomla\CMS\Editor\Editor;
  use Joomla\CMS\Extension\PluginInterface;
  use Joomla\CMS\Factory;
  use Joomla\CMS\HTML\HTMLHelper;
  use Joomla\CMS\Layout\LayoutHelper;
  use Joomla\CMS\Plugin\PluginHelper;
  use Joomla\CMS\WebAsset\WebAssetManager;
  use Joomla\Component\Formea\Site\Helper\FormeaGeneralHelper;
  use Joomla\Component\Formea\Site\Libraries\FormeaElementAttribute;
  use Joomla\Component\Formea\Site\Libraries\FormeaEltype;
  use Joomla\Registry\Registry;

  class FormeaRange extends FormeaEltype
  {
    protected $_internalValue = '';

    public function __construct($config = [])
    {
      parent::__construct($config);
      $app = Factory::getApplication();
      /** @var WebAssetManager $wa */
      $wa       = $app->getDocument()->getWebAssetManager();
      $registry = $wa->getRegistry();
      $registry->addRegistryFile('components/com_formea/plugins/element/Range/joomla.asset.json');
    }


    public function getInput($class = [], $inputAttributes = [], $langTagUnderscore = '', $preview = false, $labelSetting = null)
    {
      $html = '';
      if ($preview)
      {
        return '<input type="range" class="form-range" min="0" max="5" step="0.5" >';
      }
      else
      {
        $rangeClass = '';
        $knobStyle  = $this->params->get('knob_style', 'ios');
        if ($knobStyle == 'ios')
        {
          $rangeClass = 'ios-range';
        }
        elseif ($knobStyle === 'android')
        {
          $rangeClass = 'android-range';
        }
        elseif ($knobStyle === 'flat')
        {
          $rangeClass = 'flat-range';
        }
        $value = '';

        if (isset($inputAttributes['value']))
        {
          $value = $inputAttributes['value'];
        }

        //$dataVal              = 'data-formea-range="' . $value . '"';
        $this->_internalValue = $value;

        $html .= '<div  class="formea-range-wrapper ' . $rangeClass . '" id="' . $this->formatElementId() . '_wrapper"></div>';
        $html .= '<input type="hidden" name="' . $this->formatElementName() . '" id="' . $this->formatElementId() . '" >';
      }

      return $html;
    }

    /**
     * @param             $preview
     * @param             $langTag
     * @param             $columnAttributes
     * @param   Registry  $labelSetting
     *
     * @return string
     *
     * @since version
     */
    public function renderField($preview = false, $langTag = '', $columnAttributes = [], $inputAttributes = [], $labelSetting = null)
    {

      $themeClass = $this->getThemeClass();
      if (empty($langTag))
      {
        $langTag = $this->langTag;
      }
      $langTagUnderscore  = str_replace('-', '_', $langTag);
      $columnClass        = ['fm_element_' . $this->form_id . '_' . $this->element_id];
      $columnClass        = array_merge($this->element_css_class, $columnClass);
      $labelText          = '';
      $labelClass         = $themeClass->getLabelElClass();
      $inputWrapper       = '';
      $inputWrapperCloser = '';

      $labelPosition   = 'TOP';
      $helperTextAlign = 'LEFT';
      $showLabel       = true;

      $submittedData = $this->getSubmittedElementData();
      $hasError      = $submittedData->hasError;
      $error_msg     = $submittedData->error_msg;

      if (!empty($labelSetting))
      {
        $labelPosition     = strtoupper($labelSetting->get($langTagUnderscore . '.setting.position', 'TOP'));
        $labelSettingAlign = strtoupper($labelSetting->get($langTagUnderscore . '.setting.align', 'LEFT'));
        $showLabel         = filter_var($labelSetting->get($langTagUnderscore . '.setting.show_label', 'true'), FILTER_VALIDATE_BOOLEAN);
        if ($showLabel)
        {
          if ($labelPosition !== 'TOP' && $labelPosition !== 'BOTTOM')
          {
            $labelColumn           = (int) $labelSetting->get($langTagUnderscore . '.setting.label_column', 12);
            $columnClass[]         = $themeClass->getRowClass();
            $labelClass            = array_merge($themeClass->getLabelInlineElClass(), $labelClass);
            $labelClass[]          = $themeClass->getColumnClass($labelColumn);
            $wrapperSize           = $themeClass->getColumnAutoClass();
            $wrapperCalculatedSize = 12 - $labelColumn;
            if ($wrapperCalculatedSize > 0)
            {
              $wrapperSize = $themeClass->getColumnClass($wrapperCalculatedSize);
            }
            $inputWrapper       = '<div class="' . $wrapperSize . '">';
            $inputWrapperCloser = '</div>';
          }
          $labelClass[] = $themeClass->getTextAlignClass($labelSettingAlign);
        }
      }

      if ($hasError)
      {
        $columnClass[] = 'has-error';
      }


      if ($labelPosition === 'TOP')
      {
        $columnClass[] = $themeClass->getFormGroupClass();
      }

      if (isset($columnAttributes['class']))
      {
        $columnClass[] = $columnAttributes['class'];
      }

      if (!empty($this->form_element_settings))
      {
        if (!empty($this->form_element_settings->get('containerClass')))
        {
          $columnClass[] = $this->form_element_settings->get('containerClass');
        }
      }

      $html       = '<div class="' . implode(' ', $columnClass) . '">';
      $inputClass = [];

      if (!empty($this->element_details))
      {
        if (isset($this->element_details[$langTagUnderscore]))
        {
          $labelText = $this->element_details[$langTagUnderscore]['caption'];
          if (isset($this->element_details[$langTagUnderscore]['placeholder']))
          {
            $inputAttributes['placeholder'] = $this->element_details[$langTagUnderscore]['placeholder'];
          }
          if (isset($this->element_details[$langTagUnderscore]['description']))
          {
            $inputAttributes['description'] = $this->element_details[$langTagUnderscore]['description'];
          }
        }
      }
      if (!empty($this->element_values))
      {
        if (isset($this->element_values[$langTagUnderscore]))
        {
          if (isset($this->element_values[$langTagUnderscore]['defval']))
          {
            $inputAttributes['value'] = $this->element_values[$langTagUnderscore]['defval'];
          }
        }
      }

      if ($submittedData->hasSubmittedData)
      {
        $inputAttributes['value'] = $submittedData->submitted_value;
        if (!empty($submittedData->error_css_class))
        {
          $inputClass[] = $submittedData->error_css_class;
        }
        else
        {
          $inputClass[] = $themeClass->getNoErrorClass();
        }
      }


      if ($labelPosition == 'TOP')
      {
        if (!$preview && $showLabel)
        {
          $html .= $this->getLabel($labelText, $labelClass, $preview);
        }
      }


      $elementAttributeClass = new FormeaElementAttribute(['element_id' => $this->element_id]);

      if (!empty($elementAttributeClass))
      {
        $elementAttributes = $elementAttributeClass->getAttributes();
        if (!empty($elementAttributes->class))
        {
          $inputClass[] = $elementAttributes->class;
        }
        foreach ($elementAttributes as $attr => $val)
        {
          if ($attr !== 'class' && $attr !== 'additional_attr')
          {
            $inputAttributes[str_replace('_', '-', $attr)] = $val;
          }
        }
      }
      if ($labelPosition == 'LEFT')
      {
        if (!$preview && $showLabel)
        {
          $html .= $this->getLabel($labelText, $labelClass, $preview);
        }
      }
      $html .= $inputWrapper;

      $html .= $this->getInput($inputClass, $inputAttributes, $langTagUnderscore, $preview, $labelSetting);
      if ($labelPosition == 'BOTTOM')
      {
        if (!$preview && $showLabel)
        {
          $html .= $this->getLabel($labelText, $labelClass, $preview);
        }
      }
      $html .= $this->getErrorMsgFeedback($error_msg, $hasError);
      if (isset($inputAttributes['description']) && !$preview)
      {
        $html .= $this->getHelperText($inputAttributes['description'], $langTagUnderscore, $inputAttributes, $labelSetting);
      }
      $html .= $inputWrapperCloser;
      if ($labelPosition === 'RIGHT')
      {
        if (!$preview && $showLabel)
        {
          $html .= $this->getLabel($labelText, $labelClass, $preview);
        }
      }
      $html .= '</div>';

      return $html;
    }


    public function getGeneratedScript()
    {
      $id = $this->formatElementId();

      $wrapperId      = $id . '_wrapper';
      $wrapperIdEl    = str_replace('-', '_', $id) . '_wrapper_el';
      $value          = explode(',', $this->_internalValue);
      $value          = \Joomla\Utilities\ArrayHelper::toInteger($value);
      $range          = [
        'min' => (float) $this->params->get('min', min($value)),
        'max' => (float) $this->params->get('max', max($value))
      ];
      $enable_tooltip = (int) $this->params->get('enable_tooltip', 0);
      $step           = (float) $this->params->get('step', 0);
      $margin         = (float) $this->params->get('margin', 0);
      $limit          = (float) $this->params->get('limit', 0);
      $padding        = (float) $this->params->get('padding', 0);
      $direction      = $this->params->get('direction', 'ltr');
      $orientation    = $this->params->get('orientation', 'horizontal');

      $config = [
        'start'   => $value,
        'range'   => $range,
        'connect' => true,
      ];
      if ($orientation !== 'horizontal')
      {
        $config['orientation'] = $orientation;
      }
      if ($direction !== 'ltr')
      {
        $config['direction'] = $direction;
      }
      if ($step > 0)
      {
        $config['step'] = $step;
      }

      if ($margin > 0)
      {
        $config['margin'] = $margin;
      }

      if ($limit > 0)
      {
        $config['limit'] = $limit;
      }
      if ($padding > 0)
      {
        $config['padding'] = $padding;
      }

      $configString = json_encode($config);


      if ($enable_tooltip > 0)
      {
        $configString         = rtrim($configString, '}');
        $tooltip_decimal      = (int) $this->params->get('tooltip_decimal', 1);
        $tooltip_decimal_mark = $this->params->get('tooltip_decimal_mark', '.');
        $tooltip_thousand     = $this->params->get('tooltip_thousand', ',');
        $tooltip_suffix       = $this->params->get('tooltip_suffix');
        $tooltip_prefix       = $this->params->get('tooltip_prefix');
        $wNumb                = [
          'decimals' => $tooltip_decimal,
          'mark'     => $tooltip_decimal_mark,
          'thousand' => $tooltip_thousand
        ];
        if (!empty($tooltip_suffix))
        {
          $wNumb['suffix'] = $tooltip_suffix;
        }
        if (!empty($tooltip_prefix))
        {
          $wNumb['prefix'] = $tooltip_prefix;
        }
        $tooltips       = [];
        $configToolTips = ',"tooltips" : [';
        $totalValues    = count($value);
        for ($i = 0; $i < $totalValues; $i++)
        {
          $configToolTips .= 'wNumb(' . json_encode($wNumb) . '),';
        }
        $configToolTips = rtrim($configToolTips, ',');
        $configToolTips .= ']';
        $configString   .= $configToolTips;
        $configString   .= '}';
      }


      $js = "document.addEventListener('DOMContentLoaded',function(){";
      $js .= "var " . $wrapperIdEl . " = document.getElementById('" . $wrapperId . "');";
      $js .= "
noUiSlider.create(" . $wrapperIdEl . ", " . $configString . ");";
//triggerElementChange: (formId, formUniqueString, group_id, setIndex, elementId, elementValue)
      $js .= $wrapperIdEl . ".noUiSlider.on('update', function (values, handle) {
      var combinedValue = values.join(',');
      var targetInp = document.getElementById('" . $id . "');
      targetInp.value = combinedValue;
      FormeaFormGeneral.triggerElementChange(" . $this->form_id . ",'" . $this->form_id_unique . "'," . $this->group_id . "," . $this->setIndex . ",'" . $id . "',combinedValue);
});";

      $js .= "});";

      return $js;
    }

    public function getGeneratedStyle()
    {
      $style            = '';
      $enable_tooltip   = (int) $this->params->get('enable_tooltip', 0);
      $use_custom_color = (int) $this->params->get('custom_color', 0);
      if ($use_custom_color > 0 || $enable_tooltip > 0)
      {
        $knobStyle = $this->params->get('knob_style', 'ios');
        $wrapperEl = '.formea-range-wrapper';
        if ($knobStyle == 'ios')
        {
          $wrapperEl .= '.ios-range';
        }
        elseif ($knobStyle === 'android')
        {
          $wrapperEl .= '.android-range';
        }
        elseif ($knobStyle === 'flat')
        {
          $wrapperEl .= '.flat-range';
        }
        $elementClass = '.fm_element_' . $this->form_id . '_' . $this->element_id . ' ' . $wrapperEl;
        if ($use_custom_color > 0)
        {
          $style .= $elementClass . '.noUi-target{';
          $style .= 'background-color:' . $this->params->get('track_color', '#adb5bd') . ';';
          $style .= 'border-color:' . $this->params->get('track_color', '#adb5bd') . ';';
          $style .= '}';
          $style .= $elementClass . ' .noUi-connect{';
          $style .= 'background-color:' . $this->params->get('range_color', '#0d6efd') . ';';
          $style .= 'border-color:' . $this->params->get('range_color', '#0d6efd') . ';';
          $style .= '}';
          if ($knobStyle == 'android' || $knobStyle == 'flat')
          {
            //noUi-handle
            $style .= $elementClass . ' .noUi-handle{';
            $style .= 'background:' . $this->params->get('range_color', '#0d6efd') . ';';
            $style .= '}';
            if ($knobStyle == 'android')
            {
              $style .= $elementClass . ' .noUi-handle:before{';
              $style .= 'background:' . $this->params->get('range_color', '#0d6efd') . ';';
              $style .= '}';
            }
          }
        }

        if ($enable_tooltip && (int) $this->params->get('tooltip_ondrag', 0) > 0)
        {
          $style .= $elementClass . ' .noUi-tooltip{display:none;}';
          $style .= $elementClass . ' .noUi-active .noUi-tooltip{display:block;}';
        }

      }


      return $style;
    }

    public function getLoadableScript()
    {
      return [
        "com_formea.element.Range.noUiSlider"
      ];
    }

    public function getLoadableStyle()
    {
      return [
        'com_formea.element.Range'
      ];
    }

  }
