<?php

namespace Wga\Core\Error;

use FluidTYPO3\Flux\Integration\Overrides\ChimeraConfigurationManager;
use Psr\EventDispatcher\EventDispatcherInterface;
use TYPO3\CMS\Core\Error\PageErrorHandler\FluidPageErrorHandler as BaseFluidPageErrorHandler;
use Clickstorm\CsSeo\Controller\TypoScriptFrontendController;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
use TYPO3\CMS\Core\Context\Context;
use TYPO3\CMS\Core\Context\TypoScriptAspect;
use TYPO3\CMS\Core\Http\HtmlResponse;
use TYPO3\CMS\Core\Messaging\FlashMessage;
use TYPO3\CMS\Core\Messaging\FlashMessageService;
use TYPO3\CMS\Core\Page\PageRenderer;
use TYPO3\CMS\Core\Routing\PageArguments;
use TYPO3\CMS\Core\Site\SiteFinder;
use TYPO3\CMS\Core\TimeTracker\TimeTracker;
use TYPO3\CMS\Core\TypoScript\AST\Node\RootNode;
use TYPO3\CMS\Core\TypoScript\FrontendTypoScript;
use TYPO3\CMS\Core\TypoScript\IncludeTree\Visitor\IncludeTreeAstBuilderVisitor;
use TYPO3\CMS\Core\TypoScript\TypoScriptService;
use TYPO3\CMS\Core\Utility\GeneralUtility;
use TYPO3\CMS\Extbase\Configuration\ConfigurationManager;
use TYPO3\CMS\Extbase\Configuration\FrontendConfigurationManager;
use TYPO3\CMS\Extbase\Mvc\Controller\ControllerContext;
use TYPO3\CMS\Extbase\Mvc\Request;
use TYPO3\CMS\Extbase\Utility\LocalizationUtility;
use TYPO3\CMS\Frontend\Authentication\FrontendUserAuthentication;
use TYPO3\CMS\Frontend\Event\ModifyTypoScriptConstantsEvent;
use Wga\Core\Utility\FrontendUtility;

/**
 * Class FluidPageErrorHandler.
 */
class FluidPageErrorHandler extends BaseFluidPageErrorHandler
{
    protected $pageUid;
    protected $lang;

    /**
     * @param ServerRequestInterface $request
     * @param string $message
     * @param array $reasons
     * @return ResponseInterface
     */
    public function handlePageError(
        ServerRequestInterface $request,
        string $message,
        array $reasons = []
    ): ResponseInterface {

        $this->setLanguageByRequest($request);

        if (!isset($GLOBALS['TSFE'])) {
            $this->initTSFE($request);
        }
        if (!isset($GLOBALS['LANG'])) {
            $GLOBALS['LANG'] = $GLOBALS['TSFE']->languageService;
        }

		$languages = $GLOBALS['TSFE']->site->getLanguages();

		foreach ($languages as $language){
			$languageCode = $language->getLocale()->getLanguageCode();
			if(stripos($_SERVER['REQUEST_URI'],$languageCode) !== false){
				$currentRequestUri = str_replace('/'.$languageCode.'/','',$_SERVER['REQUEST_URI']);
			}else{
				$currentRequestUri = substr($_SERVER['REQUEST_URI'],1);
			}
		}
        if($currentRequestUri[0] == '/'){
            $currentRequestUri = mb_substr( $currentRequestUri, 1);
        }

        $this->view->assignMultiple([
            'request' => $request,
            'message' => $message,
            'reasons' => $reasons,
            'settings' => [
				'is_404' => true,
				'currentRequestUri' => $currentRequestUri,
			],
			'isError' => true,
            'page' => $GLOBALS['TSFE']->page,

        ]);

        $container = GeneralUtility::getContainer();
        $frontendUtility = GeneralUtility::makeInstance(FrontendUtility::class);
        $setup = $frontendUtility->getTyposcriptConfiguration();

		/** @var FrontendConfigurationManager $frontendConfigurationManager */
		$frontendConfigurationManager = $container->get(FrontendConfigurationManager::class);
		$frontendConfigurationManager->setConfiguration($setup);

		$rootNode = $container->get(RootNode::class);
		/** @var FrontendTypoScript $FrontendTypoScript */
		$frontendTypoScript = GeneralUtility::makeInstance(FrontendTypoScript::class,$rootNode,[]);
		$frontendTypoScript->setSetupArray($setup);

		$request = $request->withAttribute('frontend.typoscript', $frontendTypoScript);
		$GLOBALS['TYPO3_REQUEST'] = $request;

//		/** @var ChimeraConfigurationManager $chimeraConfigurationManager */
//		$chimeraConfigurationManager = $container->get(ChimeraConfigurationManager::class);
//		$chimeraConfigurationManager->setConfiguration($setup);
//		$chimeraConfigurationManager->setRequest($request);

//		foreach ($setup['plugin']['tx_wgatheme']['view'] as $id => $themeView) {
//			ksort($themeView);
//			foreach ($themeView as $key => $value){
//				$themeView[$key] = GeneralUtility::getFileAbsFileName($value);
//			}
//			$themeViews[$id] = $themeView;
//		}
		
		$request = $GLOBALS['TYPO3_REQUEST'];
		$request = $request->withAttribute('frontend.controller',$GLOBALS['TSFE']);

//		$controllerContext = GeneralUtility::makeInstance(ControllerContext::class);
//		$controllerContext->setRequest($request);
//		$this->view->setControllerContext($controllerContext);
//		$this->view->getRenderingContext()->getTemplatePaths()->fillFromConfigurationArray($themeViews);

		// Render template vai page renderer to add HeaderAssets and FooterAssets sections.
		$pageRenderer =  GeneralUtility::makeInstance(PageRenderer::class);

		$headerAssets = $this->view->renderSection('HeaderAssets', ['contentObject' => $this], true);
		$footerAssets = $this->view->renderSection('FooterAssets', ['contentObject' => $this], true);

		if (!empty(trim($headerAssets))) {
			$pageRenderer->addHeaderData($headerAssets);
		}
		if (!empty(trim($footerAssets))) {
			$pageRenderer->addFooterData($footerAssets);
		}

		$pageRenderer->addBodyContent( $this->view->render() );

        return new HtmlResponse($pageRenderer->render(), $this->statusCode);
    }

    /**
     * initialize the TSFE for the backend
     *
     * @throws \TYPO3\CMS\Core\Exception
     */
    protected function initTSFE($request)
    {
        $this->pageUid = $request->getAttributes()['site']->getRootPageId();
        try {
            if (!isset($GLOBALS['TT']) || !is_object($GLOBALS['TT'])) {
                $GLOBALS['TT'] = GeneralUtility::makeInstance(TimeTracker::class, false);
                GeneralUtility::makeInstance(TimeTracker::class)->start();
            }

            $context = GeneralUtility::makeInstance(Context::class);
            $typoScriptAspect = GeneralUtility::makeInstance(TypoScriptAspect::class, true);
            $context->setAspect('typoscript', $typoScriptAspect);
            $site = GeneralUtility::makeInstance(SiteFinder::class)->getSiteByPageId($this->pageUid);
            $pageArguments = new PageArguments($this->pageUid, '0', []);
            $frontedUser = GeneralUtility::makeInstance(FrontendUserAuthentication::class);
            $frontedUser->start($request);

            $GLOBALS['TSFE'] = GeneralUtility::makeInstance(
                \Wga\Core\XClass\TypoScriptFrontendController::class,
                $context,
                $site,
                $site->getLanguageById($this->lang),
                $pageArguments,
                $frontedUser
            );
			// @extensionScannerIgnoreLine
            $GLOBALS['TSFE']->id = $this->pageUid;

            $GLOBALS['TSFE']->newCObj();
            $GLOBALS['TSFE']->determineId($request);

            $GLOBALS['TYPO3_REQUEST'] = $request;
//            $GLOBALS['TSFE']->getConfigArray();
            $GLOBALS['TSFE']->config['config']['sys_language_uid'] = $this->lang;

        } catch (\Exception $e) {
            /** @var FlashMessage $message */
            $message = GeneralUtility::makeInstance(
                FlashMessage::class,
                $e->getMessage(),
                LocalizationUtility::translate('error.no_ts', 'cs_seo'),
				\TYPO3\CMS\Core\Type\ContextualFeedbackSeverity::ERROR
            );
            /** @var FlashMessageService $flashMessageService */
            $flashMessageService = GeneralUtility::makeInstance(FlashMessageService::class);
            $messageQueue = $flashMessageService->getMessageQueueByIdentifier('cs_seo');
            $messageQueue->enqueue($message);
        }
    }

    /**
     * @return mixed
     */
    public function getLang()
    {
        return $this->lang;
    }

    /**
     * @param mixed $lang
     */
    public function setLang($lang): void
    {
        $this->lang = $lang;
    }

    public function setLanguageByRequest($request)
    {
        $path = $request->getUri()->getPath();
        if (stripos($path, '/ua/') !== false) {
            $this->setLang(1);
        } else {
            $this->setLang(0);
        }
    }
}
