<?php

namespace Internetgalerie\IgDatapoolFe\Utility;

use TYPO3\CMS\Extbase\Reflection\ReflectionService;
use TYPO3\CMS\Fluid\ViewHelpers\FormViewHelper;
use TYPO3\CMS\Core\Utility\GeneralUtility;
use TYPO3\CMS\Extbase\Utility\LocalizationUtility;
use TYPO3Fluid\Fluid\Core\Rendering\RenderingContextInterface;
use TYPO3\CMS\Core\SingletonInterface;

class ReflectionUtility implements SingletonInterface
{
    /**
     * @var ReflectionService
     */
    protected $reflectionService;

    /**
     * @var RenderingContextInterface
     */
    protected $renderingContext=null;

    /**
     * @param ReflectionService $reflectionService
     */
    public function injectReflectionService(ReflectionService $reflectionService): void
    {
        $this->reflectionService = $reflectionService;
    }

    public function init(RenderingContextInterface $renderingContext): void
    {
        if ($this->renderingContext===null) {
            $this->renderingContext = $renderingContext;
            $this->viewHelperVariableContainer = $this->renderingContext->getViewHelperVariableContainer();
            $this->request = $this->renderingContext->getRequest();

            // is a object the in the form ViewHelper
            if ($this->viewHelperVariableContainer->exists(FormViewHelper::class, 'formObject')) {
                $formObject = $this->viewHelperVariableContainer->get(FormViewHelper::class, 'formObject');
                $this->modelClassName = $formObject::class;
            } else {
                // no get it from createAction from Controller
                /*
                if (!$extensionName) {
                    $extensionName = $this->request->getControllerExtensionName();
                }
                */
                // name of the object
                if ($this->viewHelperVariableContainer->exists(FormViewHelper::class, 'formObjectName')) {
                    $formObjectName = $this->viewHelperVariableContainer->get(FormViewHelper::class, 'formObjectName');
                }
                // Fix fuer Typo3 8.7
                $controllerObjectName=$this->request->getControllerObjectName();
                $this->modelClassName=str_replace('Controller', '', str_replace("\\Controller\\", "\Domain\\Model\\", $controllerObjectName));
                return ;

                // Reflection of createAction in controller
                /*
                $methodParameters =$this->reflectionService->getClassSchema($this->request->getControllerObjectName())->getMethod('createAction')['params'];
                foreach ($methodParameters as $parameterName => $parameterInfo) {
                    if($parameterName==$formObjectName) {
                        $this->modelClassName = $parameterInfo['type'];
                        break;
                    }
                }
                */
            }
        }
    }

    /**
     * get the object class - is wrong and cann't be done - only reposotory knows the tablename?
     */
    public static function classToTable($class)
    {
        $arr = GeneralUtility::trimExplode('\\', $class, true);
        unset($arr[0]);
        return 'tx_' . strtolower(implode('_', $arr));
    }
    /**
     * get the object class - is wrong and cann't be done - only reposotory knows the tablename?
     */
    public static function extensionModelToTable($extensionName, $modelClassName)
    {
        $arr = GeneralUtility::trimExplode('\\', $modelClassName, true);
        $modelName = $arr[count($arr)-1];
        return 'tx_' . strtolower((string) $extensionName) . '_domain_model_' . strtolower($modelName);
    }
    /**
     * get the object class
     */
    public static function propertyToField($camel)
    {
        return GeneralUtility::camelCaseToLowerCaseUnderscored($camel);
    }



    public function getFormObjectType(RenderingContextInterface $renderingContext)
    {
        $this->init($renderingContext);
        return $this->modelClassName;
    }

    public function getTableName(RenderingContextInterface $renderingContext)
    {
        $this->init($renderingContext);
        return self::classToTable($this->modelClassName);
    }
    /**
     * Compatibility Function - really ugly and not always correct
     */

    public function getFieldLabelByProperty(RenderingContextInterface $renderingContext, string $propertyName, string $extensionName = '', string $tablename = '')
    {
        $this->init($renderingContext);
        if (!$tablename) {
            if ($extensionName) {
                $tablename = self::extensionModelToTable($extensionName, $this->modelClassName);
            } else {
                $tablename = self::classToTable($this->modelClassName);
            }
        }
        $field = self::propertyToField($propertyName);
        $tableAndField = $tablename . '.' . $field;
        $extensionName = $extensionName ?: $this->request->getControllerExtensionName();
        //die($extensionName  .'=='. $tablename .'=' . $this->modelClassName .','. LocalizationUtility::translate($tableAndField, 'ig_fibu'));exit(0);
        //0blename= 'tx_' . strtolower($this->request->getControllerExtensionName()) .'_domain_model_' . strtolower($controller);
        return LocalizationUtility::translate($tableAndField, $extensionName);
        ;
    }

    public function getMappingResultsForProperty(RenderingContextInterface $renderingContext, string $propertyName)
    {
        $this->init($renderingContext);
        $originalRequestMappingResults = $this->request->getAttribute('extbase')->getOriginalRequestMappingResults();
        $formObjectName = $this->viewHelperVariableContainer->get(FormViewHelper::class, 'formObjectName');
        return $originalRequestMappingResults->forProperty($formObjectName)->forProperty($propertyName);
    }
}
