<?php
namespace Medienreaktor\Products\Controller;

use GeorgRinger\News\Domain\Model\Category;
use GeorgRinger\News\Domain\Repository\CategoryRepository;
use GeorgRinger\News\Service\CategoryService;
use Psr\Http\Message\ResponseInterface;
use TYPO3\CMS\Core\Error\Http\PageNotFoundException;
use TYPO3\CMS\Core\Utility\GeneralUtility;
use TYPO3\CMS\Extbase\Http\ForwardResponse;
use TYPO3\CMS\Extbase\Utility\DebuggerUtility;

/***
 *
 * This file is part of the "Products" Extension for TYPO3 CMS.
 *
 * For the full copyright and license information, please read the
 * LICENSE.txt file that was distributed with this source code.
 *
 *  (c) 2017 Daniel Kestler &lt;daniel.kestler@medienreaktor&gt;, medienreaktor GmbH
 *
 ***/

/**
 * ProductController
 */
class ProductController extends \TYPO3\CMS\Extbase\Mvc\Controller\ActionController
{
    /**
     * productRepository
     *
     * @var \Medienreaktor\Products\Domain\Repository\ProductRepository
     */
    protected $productRepository = null;

    /**
     * productGroupRepository
     *
     * @var \Medienreaktor\Products\Domain\Repository\ProductGroupRepository
     */
    protected $productGroupRepository = null;

    /**
     * pageRepository
     *
     * @var \Medienreaktor\Products\Domain\Repository\PageRepository
     */
    protected $pageRepository = null;


    /**
     * $productDataService
     *
     * @var \Medienreaktor\Products\Service\ProductDataService
     */
    protected $productDataService = null;

    /**
     * @var \TYPO3\CMS\Extbase\Configuration\ConfigurationManagerInterface
     */
    protected $configurationManager;

    /**
     * @var \TYPO3\CMS\Form\Mvc\Persistence\FormPersistenceManagerInterface
     */
    protected $formPersistenceManager;
    public function __construct(\Medienreaktor\Products\Domain\Repository\ProductRepository $productRepository, \Medienreaktor\Products\Domain\Repository\ProductGroupRepository $productGroupRepository, \Medienreaktor\Products\Domain\Repository\PageRepository $pageRepository, \Medienreaktor\Products\Service\ProductDataService $productDataService, \TYPO3\CMS\Extbase\Configuration\ConfigurationManagerInterface $configurationManager, \TYPO3\CMS\Form\Mvc\Persistence\FormPersistenceManagerInterface $formPersistenceManager)
    {
        $this->productRepository = $productRepository;
        $this->productGroupRepository = $productGroupRepository;
        $this->pageRepository = $pageRepository;
        $this->productDataService = $productDataService;
        $this->configurationManager = $configurationManager;
        $this->formPersistenceManager = $formPersistenceManager;
    }

    /**
     * action list
     *
     *
     */
    public function listAction(): \Psr\Http\Message\ResponseInterface
    {
        if (isset($this->settings['productgroup'])) {
            $productGroupUid = $this->settings['productgroup'];
            $productGroup = $this->productGroupRepository->findByUid($productGroupUid);

            if (count($productGroup->getProducts()) == 1) {
                foreach ($productGroup->getProducts() as $product) {
                    return (new \TYPO3\CMS\Extbase\Http\ForwardResponse('show'))->withControllerName('Product')->withExtensionName('products')->withArguments(['product' => $product]);
                }
            }

            $this->view->assign('productGroup', $productGroup);
        }
        return  $this->htmlResponse();

    }

    public function filterAction(): \Psr\Http\Message\ResponseInterface
    {
        // Get current language
        $languageUid = $GLOBALS["TYPO3_REQUEST"]->getAttribute("language")->getLanguageId() ?? -1;
        // Get Products for list view
        $productPages = $this->pageRepository->findByDokType("80", $this->settings["rootPage"]);

        usort($productPages, function($a, $b) {
            return strcmp($a["title"], $b["title"]);
        });

        $productGroups = [];
        foreach ($productPages as $productPage) {

            $productGroupData = $this->productDataService->getProductDataByProductGroupId($productPage["productgroup"]);
            if ($productGroupData && $productPage["sys_language_uid"] === $languageUid) {
                $productGroups[] = [
                    "pageData" => $productPage,
                    "productData" => $productGroupData
                ];
            }
        }

        $this->view->assign("productGroups", $productGroups);


        // Get data for filter
        $categoryRepository = Generalutility::makeInstance(CategoryRepository::class);

        $applicationCategoryIDs = explode(",", CategoryService::getChildrenCategories($this->settings["applicationAreaCID"], 0, '', true));
        $productCategoryCategoryIDs = explode(",", CategoryService::getChildrenCategories($this->settings["productCategoryCID"], 0, '', true));

        $applicationCategories = $categoryRepository->findByIdList($applicationCategoryIDs)->toArray();
        $productCategoryCategories = $categoryRepository->findByIdList($productCategoryCategoryIDs)->toArray();


        $applicationCategoriesFiltered = [];
        $productCategoryCategoriesFiltered = [];
        foreach ($productGroups as $productGroup) {

            if (isset($productGroup["productData"]["categories"]["application"])) {
                /** @var Category $category */
                foreach ($productGroup["productData"]["categories"]["application"] as $category) {
                    if (array_search($category, $applicationCategories) >= 0 && !array_key_exists($category->getUid(), $applicationCategoriesFiltered))
                        $applicationCategoriesFiltered[$category->getUid()] = $category;
                }
            }

            if (isset($productGroup["productData"]["categories"]["product"])) {
                /** @var Category $category */
                foreach ($productGroup["productData"]["categories"]["product"] as $category) {
                    if (array_search($category, $productCategoryCategories) >= 0 && !array_key_exists($category->getUid(), $productCategoryCategoriesFiltered))
                        $productCategoryCategoriesFiltered[$category->getUid()] = $category;
                }
            }

        }

        $this->view->assign("filter", [
            "application" => $applicationCategoriesFiltered,
            "productCategory" => $productCategoryCategoriesFiltered
        ]);
        return $this->htmlResponse();

    }

    private function showActionPrepareData(): void
    {
        $productGroupUid = $this->settings['productgroup'] ?? $GLOBALS["TSFE"]->page["productgroup"];
        if ($productGroupUid) {
            $productData = $this->productDataService->getProductDataByProductGroupId($productGroupUid);
            $this->view->assignMultiple($productData);
        }
    }

    /**
     * action show
     *
     * @return void
     */
    public function showAction(): \Psr\Http\Message\ResponseInterface
    {
        $this->showActionPrepareData();
        return $this->htmlResponse();
    }

    /**
     * action showPageHeader
     *
     * @return void
     */
    public function showPageHeaderAction(): \Psr\Http\Message\ResponseInterface
    {
        $this->showActionPrepareData();
        return $this->htmlResponse();
    }

    /**
     * action showPageFooter
     *
     * @return void
     */
    public function showPageFooterAction(): \Psr\Http\Message\ResponseInterface
    {
        $this->showActionPrepareData();
        return $this->htmlResponse();
    }

    /**
  * action forward
  *
  * @return \Psr\Http\Message\ResponseInterface
  */
 public function forwardAction() {
        $query = $this->request->getArgument('query');
        $product = $this->productRepository->findOneBySku($query);

        if ( ! $product) {
            throw new PageNotFoundException();
        }

		return $this->redirect('show', 'Product', 'products', ['product' => $product], $product->getPid());
	}

    /**
	 * action forwardList
	 *
	 * @return void
	 */
	public function forwardListAction(): \Psr\Http\Message\ResponseInterface {
        $products = $this->productRepository->findAll();
        $this->view->assign('products', $products);
        /*
		$node = $this->settings['node'];

		$group = $this->productGroupRepository->find($node);

		$this->forward('index', 'Product', 'procat', ['node' => $node, 'name' => $this->urlEncode($group['name'])], $this->settings['seriesPid']);
        */
        return $this->htmlResponse();
	}

    /**
     * Get the form definition with cart items
     *
     * @return array
     */
    private function getFormDefinition(\Medienreaktor\Products\Domain\Model\Product $product = NULL) {
        $formIdentifier = $this->settings['productSupportFormIdentifier'];
        if (!$formIdentifier)
            return null;
        $formDefinition = $this->formPersistenceManager->load($formIdentifier);

        $renderables = $formDefinition['renderables'][0]['renderables'];

        if ($product) {
            $renderables[] = [
                'type' => 'Hidden',
                'defaultValue' => $product->getSku().' – '.$product->getName(),
                'identifier' => 'product',
                'label' => 'Produkt'
            ];
        } else {
            $renderables[] = [
                'type' => 'Hidden',
                'identifier' => 'product',
                'label' => 'Produkt'
            ];
        }

        $formDefinition['renderables'][0]['renderables'] = $renderables;

        return $formDefinition;
    }

    /**
     * This method is used to display all pages / finishers except the
     * first page because its non cached.
     *
     * @return void
     */
    public function performAction(): \Psr\Http\Message\ResponseInterface
    {
        $formDefinition = $this->getFormDefinition();
        $this->view->assign('formDefinition', $formDefinition);
        return $this->htmlResponse();
    }


    /**
     * switchable Controller Migration
     *
     * @return ForwardResponse|ResponseInterface
     */
    public function switchableAction()
    {

        // Wert für 'switchableControllerActions' aus flexForm holen
        $cObjData = \nn\t3::Tsfe()->cObjData( $this->request );
        if(isset($cObjData['pi_flexform'])){
            $ffData = \nn\t3::FlexForm()->parse($cObjData['pi_flexform']);
            // ... und an passende Action weiterleiten
            $action = preg_replace('/[^>]*>(.*)/', '\1', $ffData['switchableControllerActions']);
            $action = str_replace(";","", $action);
        } else if ($this->settings["switchableControllerAction"]) {
            $action = $this->settings["switchableControllerAction"];
        } else if($cObjData["doktype"] == 80){
            $action = "show";
        } else {
            $action = "list";
        }


        $methodName = "{$action}Action";

        if (!method_exists($this, $methodName)) {
            return $this->htmlResponse("PayloadController->{$methodName}() exisitert nicht.");
        }

        return new ForwardResponse( $action );
    }


}
