<?php

namespace Internetgalerie\IgDatapoolFe\ViewHelpers\Form\Select;

use TYPO3\CMS\Core\Page\PageRenderer;
use Internetgalerie\IgDatapoolFe\ViewHelpers\Form\SelectViewHelper;
use TYPO3\CMS\Core\Utility\GeneralUtility;

class MultipleSideBySide2ViewHelper extends SelectViewHelper
{
    protected $selectedOptions = null;
    protected $unselectedOptions = null;

    protected $availableStringDuallistboxSettings = ['nonSelectedListLabel', 'selectedListLabel', 'filterPlaceHolder', 'filterTextClear', 'moveSelectedLabel' ,'moveAllLabel', 'removeAllLabel', 'infoText', 'infoTextFiltered', 'infoTextEmpty'];
    protected $availableBooleanDuallistboxSettings = ['showFilterInputs'];
    protected $availableIntegerDuallistboxSettings = ['selectorMinimalHeight'];

    // remove if v12 is dropped
    protected PageRenderer $pageRenderer;

    public function injectPageRenderer(PageRenderer $pageRenderer): void
    {
        $this->pageRenderer = $pageRenderer;
    }

    /**
     * Initialize arguments.
     *
     * @return void
     * @api
     */
    public function initializeArguments(): void
    {
        parent::initializeArguments();
        $this->registerArgument('main', 'boolean', 'main entry', false, true);
        $this -> registerArgument('columns', 'integer', 'columns', false, 1);
        $this -> registerArgument('search', 'integer', 'search', false, false);
        $this -> registerArgument('selectAll', 'integer', 'selectAll', false, false);

        $this -> registerArgument('sorting', 'bool', 'enable sorting', false, false);
        $this -> registerArgument('positionSelected', 'string', 'position of selected items(unselected on the other side) values: left, right', false, 'left');

        foreach ($this->availableStringDuallistboxSettings as $name) {
            $this -> registerArgument($name, 'string', $name, false);
        }
        foreach ($this->availableBooleanDuallistboxSettings as $name) {
            $this -> registerArgument($name, 'bool', $name, false);
        }
        foreach ($this->availableIntegerDuallistboxSettings as $name) {
            $this -> registerArgument($name, 'int', $name, false);
        }
    }

    public function render(): string
    {
        $this->pageRenderer->addJsFooterLibrary('multiselect', 'EXT:ig_datapool_fe/Resources/Public/JavaScript/multiselect/multiselect.js');
        $this->pageRenderer->addJsFooterLibrary('multiselect-init', 'EXT:ig_datapool_fe/Resources/Public/JavaScript/multiselect/multiselect-init.js');
        $this->pageRenderer->addCssFile('EXT:ig_datapool_fe/Resources/Public/Css/multiselect.css');

        $classFrom= 'dp-select-multiselect dp-select-multiselect-from';
        $classTo= 'dp-select-multiselect dp-select-multiselect-to';

        if ($this->tag->hasAttribute('class')) {
            $classFrom .= ' ' . $this->tag->getAttribute('class');
            $classTo .= ' ' . $this->tag->getAttribute('class');
        }
        $this->tag->addAttribute('class', $classFrom);
        $this->arguments['class']= $classFrom;

        $right = 'non-selected-' . str_replace(['[',']'], '_', $this->getName());

        $positionSelected = $this->arguments['positionSelected'];

        $htmlMoveUpDown = $this->arguments['sorting'] ? $this->renderMoveUpDown() : '';
        $htmlButtons = '<div class="ym-g10 dp-col-buttons">' . $this->renderButtons($positionSelected) . '</div>';
        $htmlSelected = '<div class="ym-g45">'  .  $this->renderdSelected($right) . $htmlMoveUpDown . '</div>';
        $htmlUnSelected = '<div class="ym-g45">' .  $this->renderUnSelected($right) . '</div>';

        if ($positionSelected == 'left') {
            $htmlCols = $htmlSelected .  $htmlButtons . $htmlUnSelected;
        } else {
            $htmlCols = $htmlUnSelected .  $htmlButtons . $htmlSelected;
        }

        return '<div class="ym-grid dp-select-multiselect-container">' . $htmlCols . '</div>';
    }

    /**
     * Render select
     *
     * @return string rendered tag.
     * @api
     */
    public function renderdSelected($id)
    {
        $this->tag->addAttribute('id', $id);
        $this->arguments['multiple'] = 1;
        return parent::render();
    }

    /**
     * Render buttons
     *
     * @return string rendered tag.
     * @api
     */
    public function renderButtons($positionSelected)
    {
        if ($positionSelected == 'left') {
            $buttons = [
                'multiselect_rightAll' => 'glyphicon-backward',
                'multiselect_rightSelected' => 'glyphicon-chevron-left',
                'multiselect_leftSelected' => 'glyphicon-chevron-right',
                'multiselect_leftAll' => 'glyphicon-forward',
            ];
        } else {
            $buttons = [
                'multiselect_rightAll' => 'glyphicon-forward',
                'multiselect_rightSelected' => 'glyphicon-chevron-right',
                'multiselect_leftSelected' => 'glyphicon-chevron-left',
                'multiselect_leftAll' => 'glyphicon-backward',
            ];
        }
        $ret ='';
        foreach ($buttons as $id => $glyphicon) {
            $ret .= '<button type="button" id="' . $id . '" class="btn btn-block"><span class="glyphicon ' . $glyphicon . '"></span></button>';
        }
        return $ret;
    }

    /**
     * Render selected site
     *
     * @return string rendered tag.
     * @api
     */
    public function renderUnselected($unSelectedId)
    {
        return '<select name="nonSelected[]" data-right="#' . $unSelectedId . '"  class="dp-select-multiselect dp-select-multiselect-non-selected" size="8" multiple="multiple">' . $this->renderOptionTags($this->unselectedOptions) . '</select>';
    }

    /**
     * Render move up/down
     *
     * @return string rendered tag.
     * @api
     */
    public function renderMoveUpDown()
    {
        return '<div class="ym-grid dp-select-multiselect-move-container">
            <div class="ym-g50 dp-col-move-up">
                <button type="button" id="multiselect_move_up" class="btn btn-block"><span class="glyphicon glyphicon-arrow-up"></span></button>
            </div>
            <div class="ym-g50 dp-col-move-up">
                <button type="button" id="multiselect_move_down" class="btn btn-block col-sm-6"><span class="glyphicon glyphicon-arrow-down"></span></button>
            </div>
        </div>';
    }

    protected function getAllOptions()
    {
        if ($this->selectedOptions !== null && $this->unselectedOptions !== null) {
            return;
        }
        $this->selectedOptions = [];
        $this->unselectedOptions = [];
        $options = parent::getOptions();
        $selectedValues = parent::getSelectedValue();
        if (!is_array($selectedValues)) {
            $selectedValues = [$selectedValues];
        }
        // set the unselected
        foreach ($options as $value => $label) {
            if (!in_array($value, $selectedValues)) {
                $this->unselectedOptions[$value] = $label;
            }
        }
        // set label for selected and keep sorting
        foreach ($selectedValues as $index => $selectedValue) {
            $this->selectedOptions[$selectedValue] = $options[$selectedValue];
            /*$this->selectedOptions[$index] = [
                'uid' => $selectedValue,
                $this->arguments['optionLabelField'] => $options[$selectedValue],
             ];
            */
        }
        //var_dump($this->selectedOptions, $this->arguments['optionLabelField']);exit(0);
    }

    /**
     * Render the option tags.
     *
     * @return array an associative array of options, key will be the value of the option tag
     */
    protected function getOptions(): array
    {
        $this->getAllOptions();
        return $this->selectedOptions;
    }
}
