<?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 Feseur\Library\FsrHelper;
  use Joomla\CMS\WebAsset\WebAssetManager;
  use Joomla\Component\Formea\Site\Libraries\FormeaEltype;
  use Joomla\CMS\Factory;

  class FormeaStarRating extends FormeaEltype
  {
    /**
     * @var string
     * @since 1.0.0
     */
    private $layout = 'stacked';

    /**
     * @var string
     * @since 1.0.0
     */
    private $elementClass = '';

    /**
     * @var bool
     * @since 1.0.0
     */
    private $preview = false;

    private $ratingSetID = '';

    private $writeStyle = false;

    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/StarRating/joomla.asset.json');
    }

    public function getLabel($label = 'label', $class = [], $preview = false)
    {
      return '<label for="' . $this->formatElementId() . '" class="' . implode(' ', $class) . '">' . $label . '</label>';
    }

    public function getInput($class = [], $inputAttributes = [], $langTagUnderscore = '', $preview = false, $labelSetting = null)
    {
      $themeClass = $this->getThemeClass();
      $class[]    = 'formea-star-rating';

      $name = '';
      if (!$preview)
      {
        $name = ' name="' . $this->formatElementName() . '" ';
      }
      $defaultValue = '';
      if (isset($inputAttributes['value']))
      {
        $defaultValue = $inputAttributes['value'];
      }
      $star_size = $this->params->get('star_size', '');
      $layout    = $this->params->get('layout', '');
      if (!empty($star_size))
      {
        if ($star_size !== 'custom')
        {
          $class[] = 'star-' . $star_size;
        }
        else
        {
          $this->writeStyle = true;
        }
      }

      if ($layout === 'stacked' || $layout === 'stacked_reverse')
      {
        $class[] = 'vertical';
      }

      if ($layout === 'inline_reverse' || $layout === 'stacked_reverse')
      {
        $class[] = 'reverse';
      }


      $custom_icon = (int) $this->params->get('custom_icon', 0);
      if ($custom_icon > 0)
      {
        $this->writeStyle = true;
      }
      else
      {
        $star_weight = $this->params->get('star_weight');
        if (!empty($star_weight))
        {
          $class[] = $star_weight;
        }
      }

      $star_spacing = $this->params->get('star_spacing');
      if (!empty($star_spacing))
      {
        $class[] = 'spacing-' . $star_spacing;
      }

      $setId             = $this->formatElementId();
      $this->ratingSetID = 'fsr_' . $this->element_alias;
      $class[]           = $this->ratingSetID;
      $html              = '<div class="' . $themeClass->getBlockClass() . '">';
      $showTooltip       = (int) $this->params->get('show_active_label', 0);

      $html .= '<div class="' . implode(' ', $class) . '"';
      if ($showTooltip > 0)
      {
        $this->writeStyle = true;
        $placement        = ($showTooltip === 2) ? 'top' : 'bottom';
        $html             .= ' data-fmstarrating-tooltip="' . $placement . '" ';
      }
      $html .= '>';

      $show_min_level = (int) $this->params->get('show_min_level', 0);
      $show_max_level = (int) $this->params->get('show_max_level', 0);

      if (!empty($this->element_values))
      {
        if (isset($this->element_values[$langTagUnderscore]))
        {
          if (isset($this->element_values[$langTagUnderscore]['option_lists']))
          {
            $totalOptionLists = count($this->element_values[$langTagUnderscore]['option_lists']);
            $foundChecked     = false;

            for ($i = 0; $i < $totalOptionLists; $i++)
            {
              $fsrRatingClass = [
                'fsr-rating',
                'fsr_opt_' . $i
              ];
              if ($show_min_level > 0 && $i === 0)
              {
                $html           .= '<div class="fsr-label">' . $this->element_values[$langTagUnderscore]['option_lists'][$i]->text . '</div>';
                $show_min_level = 0;
              }
              $selected = '';
              if (!$foundChecked)
              {
                if ($defaultValue === $this->element_values[$langTagUnderscore]['option_lists'][$i]->val)
                {
                  $selected     = ' checked ';
                  $foundChecked = true;
                }
                elseif ($this->element_values[$langTagUnderscore]['option_lists'][$i]->selected)
                {
                  $selected     = ' checked ';
                  $foundChecked = true;
                }
              }
              if (!$foundChecked && empty($selected))
              {
                $fsrRatingClass[] = 'active';
              }
              $html .= '<div class="' . implode(' ', $fsrRatingClass) . '"><input type="radio"';
              $html .= ' id="' . $setId . '_' . $i . '" ';
              $html .= $name;
              $html .= $selected;
              $html .= ' value="' . $this->element_values[$langTagUnderscore]['option_lists'][$i]->val . '"/>';
              $html .= '<label class="fm-tooltip"  for="' . $setId . '_' . $i . '">' . $this->element_values[$langTagUnderscore]['option_lists'][$i]->text;
              $html .= ' <span class="fm-arrow" data-fmstarrating-arrow></span>';
              $html .= '</label>';
              $html .= '</div>';
              if ($show_max_level > 0 && $i === ($totalOptionLists - 1))
              {
                $html           .= '<div class="fsr-label">' . $this->element_values[$langTagUnderscore]['option_lists'][$i]->text . '</div>';
                $show_max_level = 0;
              }
            }

          }
        }
      }

      $html .= '</div>';
      $html .= '</div>';

      return $html;
    }


    public function getAdminLoadableStyle()
    {
      return [
        'com_formea.element.StarRating'
      ];
    }

    public function getGeneratedStyle()
    {
      $css = '';
      if (!empty($this->ratingSetID) && $this->writeStyle)
      {
        $selector          = '.formea-star-rating.' . $this->ratingSetID;
        $elementLevelProps = [];
        $show_active_label = (int) $this->params->get('show_active_label', 0);
        if ($show_active_label > 0)
        {
          $tooltip_bg_color   = $this->params->get('tooltip_bg_color', '#212529');
          $tooltip_text_color = $this->params->get('tooltip_text_color', '#f8f9fa');
          if ($tooltip_bg_color !== '#212529')
          {
            $elementLevelProps[] = '--fm-tooltip-bg:' . $tooltip_bg_color . ';';
          }
          if ($tooltip_text_color !== '#f8f9fa')
          {
            $elementLevelProps[] = '--fm-tooltip-color:' . $tooltip_text_color . ';';
          }
        }
        if (!empty($elementLevelProps))
        {
          $css .= $selector . ' {';
          $css .= implode(' ', $elementLevelProps);
          $css .= '}';
        }

        $star_size = $this->params->get('star_size', '');


        if ($star_size === 'custom')
        {
          $star_custom_size = $this->params->get('star_custom_size', '18px');
          $css              .= $selector . ' input[type=radio] {';
          $css              .= 'width:' . $star_custom_size . ';';
          $css              .= 'height:' . $star_custom_size . ';';
          $css              .= '}';
        }


        $custom_icon     = (int) $this->params->get('custom_icon', 0);
        $custom_colors   = (int) $this->params->get('custom_colors', 0);
        $fsrRatingOpts   = [];
        $_inactiveColors = [];
        $_activeColors   = [];
        if ($custom_colors > 0)
        {
          $inactive_color      = (array) $this->params->get('inactive_color', []);
          $active_colors       = (array) $this->params->get('active_colors', []);
          $inactive_color      = array_values($inactive_color);
          $active_colors       = array_values($active_colors);
          $totalInactiveColors = count($inactive_color);
          $totalAactiveColors  = count($active_colors);
          for ($i = 0; $i < $totalInactiveColors; $i++)
          {
            $fsrRatingOpts[$i][] = '--fm-inactive: ' . $inactive_color[$i]->colors . ';';
            $_inactiveColors[$i] = $inactive_color[$i]->colors;
          }
          for ($i = 0; $i < $totalAactiveColors; $i++)
          {
            $fsrRatingOpts[$i][] = '--fm-active: ' . $active_colors[$i]->colors . ';';
            $_activeColors[$i]   = $active_colors[$i]->colors;
          }

        }

        if ($custom_icon > 0)
        {
          $custom_icon_inactives = (array) $this->params->get('custom_icon_inactives', []);
          $custom_icon_inactives = array_values($custom_icon_inactives);
          $totalInactiveIcons    = count($custom_icon_inactives);

          $custom_icon_actives = (array) $this->params->get('custom_icon_actives', []);
          $custom_icon_actives = array_values($custom_icon_actives);
          $totalActiveIcons    = count($custom_icon_actives);

          for ($i = 0; $i < $totalInactiveIcons; $i++)
          {
            $icon      = FsrHelper::getImageSrc($custom_icon_inactives[$i]->icons);
            $extension = pathinfo($icon, PATHINFO_EXTENSION);
            $bgProp    = $icon;
            if ($extension === 'svg')
            {
              $fillColor = '';
              if (isset($_inactiveColors[$i]))
              {
                $fillColor = 'var(--fm-inactive,' . $_inactiveColors[$i] . ')';;
              }
              $bgProp = $this->_formatSvgCss($icon, $fillColor);
            }
            $fsrRatingOpts[$i][] = '--fm-star-regular: url("' . $bgProp . '");';
          }
          for ($i = 0; $i < $totalActiveIcons; $i++)
          {
            $icon      = FsrHelper::getImageSrc($custom_icon_actives[$i]->icons);
            $extension = pathinfo($icon, PATHINFO_EXTENSION);
            $bgProp    = $icon;
            if ($extension === 'svg')
            {
              $fillColor = '';
              if (isset($_activeColors[$i]))
              {
                $fillColor = 'var(--fm-active,' . $_activeColors[$i] . ')';;
              }
              $bgProp = $this->_formatSvgCss($icon, $fillColor);
            }
            $fsrRatingOpts[$i][] = '--fm-star-active: url("' . $bgProp . '");';
          }
        }


        if (!empty($fsrRatingOpts))
        {
          $totalOpts = count($fsrRatingOpts);
          for ($j = 0; $j < $totalOpts; $j++)
          {
            $css .= $selector . ' .fsr-rating.fsr_opt_' . $j . ' {';
            $css .= implode(' ', $fsrRatingOpts[$j]);
            $css .= '}';
          }
        }

      }

      return $css;
    }

    private function _formatSvgCss($icon, $fillColor = null)
    {
      $rawSvg = file_get_contents($icon);

      $dom = new DOMDocument;
      $dom->loadXML($rawSvg);

      if (!empty($fillColor))
      {
        // Find all <path> elements
        $pathElements = $dom->getElementsByTagName('path');
        foreach ($pathElements as $path)
        {
          // Check if the 'fill' attribute exists
          if ($path->hasAttribute('fill'))
          {
            // If 'fill' attribute exists, replace its value
            $path->setAttribute('fill', $fillColor);
          }
          else
          {
            // If 'fill' attribute does not exist, insert it with the specified value
            $path->setAttribute('fill', $fillColor);
          }
        }
      }

      // Find all <svg> elements
      $svgElements = $dom->getElementsByTagNameNS('http://www.w3.org/2000/svg', 'svg');

      $_rawSvg = $dom->saveXML($svgElements->item(0));


      $_rawSvg = str_replace('"', '\'', $_rawSvg);

      $_rawSvg = str_replace("\n", '', $_rawSvg);
      $_rawSvg = str_replace("(", '%28', $_rawSvg);
      $_rawSvg = str_replace(")", '%29', $_rawSvg);
      $_rawSvg = str_replace("#", '%23', $_rawSvg);

      return 'data:image/svg+xml,' . $_rawSvg;
    }

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

    public function getLoadableScript()
    {
      return [
        'popper',
        'com_formea.element.StarRating'
      ];
    }
  }
