<?php

namespace Wga\WgaFaq\Hooks;

use TYPO3\CMS\Backend\Preview\StandardContentPreviewRenderer;
use TYPO3\CMS\Backend\View\BackendLayout\Grid\GridColumnItem;
use Wga\Core\Utility\FrontendUtility;
use Wga\WgaFaq\Utility\TemplateLayout;
use TYPO3\CMS\Backend\Routing\UriBuilder;
use TYPO3\CMS\Backend\Template\DocumentTemplate;
use TYPO3\CMS\Backend\Utility\BackendUtility as BackendUtilityCore;
use TYPO3\CMS\Core\Imaging\Icon;
use TYPO3\CMS\Core\Imaging\IconFactory;
use TYPO3\CMS\Core\Page\PageRenderer;
use TYPO3\CMS\Core\Type\Bitmask\Permission;
use TYPO3\CMS\Core\Utility\GeneralUtility;
use TYPO3\CMS\Fluid\View\StandaloneView;

/**
 * Hook to display verbose information about pi1 plugin in Web>Page module
 */
class PageLayoutView extends StandardContentPreviewRenderer
{
    /**
     * Extension key
     *
     * @var string
     */
    const KEY = 'wgafaq';

    /**
     * Path to the locallang file
     *
     * @var string
     */
    const LLPATH = 'LLL:EXT:wga_faq/Resources/Private/Language/locallang_be.xlf:';

    /**
     * Max shown settings
     */
    const SETTINGS_IN_PREVIEW = 9;

    /**
     * Table information
     *
     * @var array
     */
    public $tableData = [];

    /**
     * Flexform information
     *
     * @var array
     */
    public $flexformData = [];

    /**
     * @var IconFactory
     */
    protected $iconFactory;

    /** @var TemplateLayout $templateLayoutsUtility */
    protected $templateLayoutsUtility;

    /**
     * PageLayoutView constructor.
     * @param TemplateLayout $templateLayout
     * @param IconFactory $iconFactory
     */
    public function __construct(
        TemplateLayout $templateLayout,
        IconFactory $iconFactory
    ) {
        $this->templateLayoutsUtility = $templateLayout;
        $this->iconFactory = $iconFactory;
    }

    /**
     * Returns information about this extension's pi1 plugin
     *
     * @param array $params Parameters to the hook
     * @return string Information about pi1 plugin
     */
    public function renderPageModulePreviewContent(GridColumnItem $item): string
    {
		$row = $item->getRecord();

        $actionTranslationKey = $result = '';
        // phpcs:ignore
        $header = '<strong>' . htmlspecialchars($this->getLanguageService()->sL(self::LLPATH . 'pi1_title')) . '</strong>';

        if ($row['list_type'] == self::KEY . '_pi1') {
            $this->tableData = [];
            $this->flexformData = GeneralUtility::xml2array($row['pi_flexform']);

            if (is_array($this->flexformData)) {
                switch ($actionTranslationKey) {
                    default:
                        $this->getStartingPoint($row['pages']);
                        $this->getTemplateLayoutSettings($row['pid']);
                        $this->getOffsetLimitSettings();
                        break;
                }

                // phpcs:ignore
                if ($hooks = $GLOBALS['TYPO3_CONF_VARS']['EXT']['wga_events']['Wga\\WgaFaq\\Hooks\\PageLayoutView']['extensionSummary'] ?? []) {
                    $params = [
                        'action' => $actionTranslationKey
                    ];
                    foreach ($hooks as $reference) {
                        GeneralUtility::callUserFunction($reference, $params, $this);
                    }
                }

                $result = $this->renderSettingsAsTable($header, $row['uid'] ?? 0);
            }
        }

        return $result;
    }

    /**
     * @param int $id
     * @param string $table
     * @return string
     */
    public function getRecordData($id, $table = 'pages'): string
    {
        $record = BackendUtilityCore::getRecord($table, $id);

        if (is_array($record)) {
            $data = '<span data-toggle="tooltip" data-placement="top" data-title="id=' . $record['uid'] . '">'
                . $this->iconFactory->getIconForRecord($table, $record, Icon::SIZE_SMALL)->render()
                . '</span> ';
            $content = BackendUtilityCore::wrapClickMenuOnIcon(
                $data,
                $table,
                $record['uid'],
                true,
                '',
                '+info,edit,history'
            );

            $linkTitle = htmlspecialchars(BackendUtilityCore::getRecordTitle($table, $record));

            if ($table === 'pages') {
                $id = $record['uid'];
                $currentPageId = FrontendUtility::getArguments()['id'];
                $link = htmlspecialchars($this->getEditLink($record, $currentPageId));
                $switchLabel = $this->getLanguageService()->sL(self::LLPATH . 'pagemodule.switchToPage');
                // phpcs:ignore
                $content .= ' <a href="#" data-toggle="tooltip" data-placement="top" data-title="' . $switchLabel . '" onclick=\'top.jump("' . $link . '", "web_layout", "web", ' . $id . ');return false\'>' . $linkTitle . '</a>';
            } else {
                $content .= $linkTitle;
            }
        } else {
            $text = sprintf(
                $this->getLanguageService()->sL(self::LLPATH . 'pagemodule.recordNotAvailable'),
                $id
            );
            $content = $this->generateCallout($text);
        }

        return $content;
    }

    /**
     * Render offset & limit configuration
     *
     * @return void
     */
    public function getOffsetLimitSettings(): void
    {
        $limit = $this->getFieldFromFlexform('settings.limit', 'additional');
        if ($limit) {
            $this->tableData[] = [
                $this->getLanguageService()->sL(self::LLPATH . 'flexforms_additional.limit'),
                $limit
            ];
        }
    }

    /**
     * Render template layout configuration
     *
     * @param int $pageUid
     *
     * @return void
     */
    public function getTemplateLayoutSettings($pageUid): void
    {
        $title = '';
        $field = $this->getFieldFromFlexform('settings.templateLayout', 'template');

        // Find correct title by looping over all options
        if (!empty($field)) {
            $layouts = $this->templateLayoutsUtility->getAvailableTemplateLayouts($pageUid);
            foreach ($layouts as $layout) {
                if ((string)$layout[1] === (string)$field) {
                    $title = $layout[0];
                }
            }
        }

        if (!empty($title)) {
            $this->tableData[] = [
                $this->getLanguageService()->sL(self::LLPATH . 'flexforms_template.templateLayout'),
                $this->getLanguageService()->sL($title)
            ];
        }
    }

    /**
     * Get the startingpoint
     *
     * @return void
     */
    public function getStartingPoint($value): void
    {
        if (!empty($value)) {
            $pageIds = GeneralUtility::intExplode(',', $value, true);
            $pagesOut = [];

            foreach ($pageIds as $id) {
                $pagesOut[] = $this->getRecordData($id, 'pages');
            }

            $this->tableData[] = [
                $this->getLanguageService()->sL(
                    'LLL:EXT:core/Resources/Private/Language/locallang_general.xlf:LGL.startingpoint'
                ),
                implode(', ', $pagesOut)
            ];
        }
    }

    /**
     * Render an alert box
     *
     * @param string $text
     * @return string
     */
    protected function generateCallout($text): string
    {
        return '<div class="alert alert-warning">
            ' . htmlspecialchars($text) . '
        </div>';
    }

    /**
     * Render the settings as table for Web>Page module
     * System settings are displayed in mono font
     *
     * @param string $header
     * @param int $recordUid
     * @return string
     */
    protected function renderSettingsAsTable($header = '', $recordUid = 0): string
    {
        $pageRenderer = GeneralUtility::makeInstance(PageRenderer::class);
        $pageRenderer->loadRequireJsModule('TYPO3/CMS/News/PageLayout');
        $pageRenderer->addCssFile('EXT:wga_faq/Resources/Public/Css/Backend/PageLayoutView.css');

        $view = GeneralUtility::makeInstance(StandaloneView::class);
        $view->setTemplatePathAndFilename(
            GeneralUtility::getFileAbsFileName(
                'EXT:wga_faq/Resources/Private/Backend/PageLayoutView.html'
            )
        );
        $view->assignMultiple([
            'header' => $header,
            'rows' => [
                'above' => array_slice($this->tableData, 0, self::SETTINGS_IN_PREVIEW),
                'below' => array_slice($this->tableData, self::SETTINGS_IN_PREVIEW)
            ],
            'id' => $recordUid
        ]);

        return $view->render();
    }

    /**
     * Get field value from flexform configuration,
     * including checks if flexform configuration is available
     *
     * @param string $key name of the key
     * @param string $sheet name of the sheet
     * @return string|null if nothing found, value if found
     */
    public function getFieldFromFlexform($key, $sheet = 'sDEF'): ?string
    {
        $flexform = $this->flexformData;
        if (isset($flexform['data'])) {
            $flexform = $flexform['data'];
            if (isset($flexform[$sheet]['lDEF'][$key]['vDEF'])
            ) {
                return $flexform[$sheet]['lDEF'][$key]['vDEF'];
            }
        }

        return null;
    }

    /**
     * Build a backend edit link based on given record.
     *
     * @param array $row Current record row from database.
     * @param int $currentPageUid current page uid
     * @return string Link to open an edit window for record.
     * @see \TYPO3\CMS\Backend\Utility\BackendUtilityCore::readPageAccess()
     */
    protected function getEditLink($row, $currentPageUid): string
    {
        $editLink = '';
        $localCalcPerms = $GLOBALS['BE_USER']->calcPerms(BackendUtilityCore::getRecord('pages', $row['uid']));
        $permsEdit = $localCalcPerms & Permission::PAGE_EDIT;
        if ($permsEdit) {
            $uriBuilder = GeneralUtility::makeInstance(UriBuilder::class);
            $returnUrl = $uriBuilder->buildUriFromRoute('web_layout', ['id' => $currentPageUid]);
            $editLink = $uriBuilder->buildUriFromRoute('web_layout', [
                'id' => $row['uid'],
                'returnUrl' => $returnUrl
            ]);
        }
        return $editLink;
    }

    /**
     * Return language service instance
     *
     * @return \TYPO3\CMS\Core\Localization\LanguageService
     */
    public function getLanguageService(): \TYPO3\CMS\Core\Localization\LanguageService
    {
        return $GLOBALS['LANG'];
    }
}
