<?php

namespace Internetgalerie\IgDatapoolFe\ViewHelpers\Form\Tom;

use Internetgalerie\IgDatapoolFe\ViewHelpers\Form\Tom\SelectViewHelper;
use TYPO3\CMS\Core\Utility\GeneralUtility;
use TYPO3\CMS\Extbase\Mvc\Web\Routing\UriBuilder;
use TYPO3\CMS\Extbase\Persistence\ObjectStorage;
use TYPO3\CMS\Extbase\Utility\DebuggerUtility;
use TYPO3\CMS\Fluid\Core\Rendering\RenderingContext;

class SelectAjaxViewHelper extends SelectViewHelper
{
    protected static $class = 'dp-tom-select dp-select-ajax';
    protected static $style = 'width: 100%;';

    public function initializeArguments(): void
    {
        parent::initializeArguments();
        $this->registerArgument('delay', 'integer', 'delay in ms', false, 250);
        $this->registerArgument('action', 'string', 'Ajax Action', false, 'ajax');
        $this->registerArgument('arguments', 'array', 'Ajax Arguments', false, []);
        $this->registerArgument('controller', 'string', 'Ajax Controller', false, null);
        $this->registerArgument('pluginName', 'string', 'Ajax PluginName', false, null);
        $this->registerArgument('extensionName', 'string', 'Ajax ExtensionName', false, null);
        $this->registerArgument('pageUid', 'string', 'Ajax Page UID', false, 0);
        $this->registerArgument('typeNum', 'integer', 'Page type number for AJAX requests', false, 0);
        $this->registerArgument('argumentNameUid', 'string', 'argument name for initial ajax call for uid', false, 'uid');
        $this->overrideArgument('allowClear', 'boolean', 'display c clear button ("x" icon) to appear on the select box when a value is selected.', false, true);
    }


    public function render(): string
    {
        // Ensure submitted form data is respected (important for search forms)
        $this->setRespectSubmittedDataValue(true);

        /** @var RenderingContext */
        $renderingContext = $this->renderingContext;

        $pageUid = (int)$this->arguments['pageUid'];
        if ($pageUid == 0) {
            $request = $this->getRequest();
            $pageUid = $request->getAttribute('frontend.page.information')->getId();
        }

        $uriBuilder = GeneralUtility::makeInstance(UriBuilder::class);
        $uriBuilder
            ->reset()
            ->setRequest($this->getRequest())
            ->setTargetPageUid($pageUid);
        $uriBuilder->setCreateAbsoluteUri(true);

        // Add typeNum for AJAX page type if specified
        if ($this->arguments['typeNum'] > 0) {
            $uriBuilder->setTargetPageType($this->arguments['typeNum']);
        }

        $uri = $uriBuilder->uriFor(
            $this->arguments['action'],
            $this->arguments['arguments'],
            $this->arguments['controller'],
            $this->arguments['extensionName'],
            $this->arguments['pluginName']
        );

        $chashPos = strrpos($uri, '&cHash=');
        if ($chashPos > 0) {
            $uri = substr($uri, 0, $chashPos);
        }

        // Add AJAX URL as data attribute
        $this->tag->addAttribute('data-ajax-url', $uri);
        $this->tag->addAttribute('data-ajax-delay', intval($this->arguments['delay']));

        // Store initial value for restoration after AJAX load
        $value = $this->getValueAttribute();
        if ($value) {
            $this->tag->addAttribute('data-ajax-initial-value', $value);
            $initalUri = '';
            if ($this->arguments['argumentNameUid'] ?? false) {
                $value = $this->getValueAttribute();
                if ($value) {
                    $uriBuilder->setArguments(
                    [$this->arguments['argumentNameUid'] => $value]
                    );
                    $initalUri = $uriBuilder->uriFor($this->arguments['action'], null, $this->arguments['controller'], $this->arguments['extensionName'], $this->arguments['pluginName']);
                }
            }

            // Build URL for fetching initial item by UID
            //$argumentNameUid = $this->arguments['argumentNameUid'] ?: 'uid';
            //$uidArguments = $this->arguments['arguments'];
            //$uidArguments[$argumentNameUid] = $value;

            // $uriBuilder->setArguments(
            //     [$this->arguments['argumentNameUid'] => $value]
            // );
            // $uidUri = $uriBuilder->uriFor(
            //     $this->arguments['action'],
            //     null,
            //     $this->arguments['controller'],
            //     $this->arguments['extensionName'],
            //     $this->arguments['pluginName']
            // );

            // $chashPosUid = strrpos($uidUri, '&cHash=');
            // if ($chashPosUid > 0) {
            //     $uidUri = substr($uidUri, 0, $chashPosUid);
            // }
            $this->tag->addAttribute('data-ajax-initial-url', $initalUri);
        }

        return parent::render();
    }

    protected function getOptions(): array
    {
        $this->setRespectSubmittedDataValue(true);

        if ($this->getPropertyValue()) {
            $propertyValue = $this->getPropertyValue();
            if ($propertyValue instanceof ObjectStorage) {
                $options = [];
                foreach ($propertyValue as $subValue) {
                    $options[$subValue->getUid()] = $subValue->__toString();
                }
                return $options;
            }
            if (is_object($propertyValue) && method_exists($propertyValue, '__toString')) {
                return [$this->getValueAttribute() => (string)$propertyValue];
            }
        }

        $value = $this->arguments['value'];
        if ($value) {
            if (is_object($value) && method_exists($value, '__toString')) {
                return [$this->getValueAttribute() => (string)$value];
            }
            return [$this->getValueAttribute() => $value];
        }

        // For AJAX selects, don't render options with empty labels
        // JavaScript will load and display the correct option
        return [];
    }

    protected function getValueAttribute($convertObjects = true)
    {
        $valueAttribute = parent::getValueAttribute($convertObjects);
        return is_object($valueAttribute) && method_exists($valueAttribute, 'getUid') ? $valueAttribute->getUid() : $valueAttribute;
    }

    protected function convertToPlainValue($value)
    {
        if ($value instanceof ObjectStorage) {
            $ret = [];
            foreach ($value as $subValue) {
                $identifier = $this->persistenceManager->getIdentifierByObject($subValue);
                if ($identifier !== null) {
                    $ret[] = $identifier;
                }
            }
            return $ret;
        } else {
            return parent::convertToPlainValue($value);
        }
    }
}
